Skip to content

Publish to pub.dev

Publish to pub.dev #4

Workflow file for this run

name: Publish to pub.dev
on:
push:
tags:
- 'v*.*.*' # Trigger on version tags like v0.0.1, v1.0.0, etc.
workflow_dispatch:
inputs:
package:
description: 'Package to publish (all, gameframework, gameframework_unity, gameframework_unreal)'
required: true
default: 'all'
type: choice
options:
- all
- gameframework
- gameframework_unity
- gameframework_unreal
dry_run:
description: 'Run in dry-run mode (validate but do not publish)'
required: false
default: true
type: boolean
permissions:
contents: write
jobs:
# Validate all packages before publishing
validate:
name: Validate ${{ matrix.package.name }}
runs-on: ubuntu-latest
strategy:
matrix:
package:
- name: gameframework
path: packages/gameframework
- name: gameframework_unity
path: engines/unity/dart
- name: gameframework_unreal
path: engines/unreal/dart
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.27.x'
channel: 'stable'
cache: true
- name: Get dependencies
working-directory: ${{ matrix.package.path }}
run: flutter pub get
- name: Analyze code
working-directory: ${{ matrix.package.path }}
run: flutter analyze
- name: Run tests
working-directory: ${{ matrix.package.path }}
run: flutter test
- name: Validate package
working-directory: ${{ matrix.package.path }}
run: flutter pub publish --dry-run
# Publish gameframework (core package) first
publish-gameframework:
name: Publish gameframework
needs: validate
runs-on: ubuntu-latest
if: |
(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')) ||
(github.event_name == 'workflow_dispatch' &&
(github.event.inputs.package == 'all' || github.event.inputs.package == 'gameframework'))
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.27.x'
channel: 'stable'
cache: true
- name: Get dependencies
working-directory: packages/gameframework
run: flutter pub get
- name: Setup pub credentials
if: github.event.inputs.dry_run != 'true'
run: |
mkdir -p $HOME/.pub-cache
echo '${{ secrets.PUB_CREDENTIALS }}' > $HOME/.pub-cache/credentials.json
- name: Publish to pub.dev (dry-run)
if: github.event.inputs.dry_run == 'true'
working-directory: packages/gameframework
run: flutter pub publish --dry-run
- name: Publish to pub.dev
if: github.event.inputs.dry_run != 'true'
working-directory: packages/gameframework
run: flutter pub publish --force
- name: Extract version
if: github.event.inputs.dry_run != 'true'
id: version
working-directory: packages/gameframework
run: |
VERSION=$(grep '^version:' pubspec.yaml | awk '{print $2}')
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Published gameframework v$VERSION"
# Publish engine plugins after core package
# matrix is NOT available in job-level `if`, so per-package filtering
# is handled at the step level via the should_publish check.
publish-engine-plugins:
name: Publish ${{ matrix.package.name }}
needs: [validate, publish-gameframework]
runs-on: ubuntu-latest
# always() is required so this job isn't auto-skipped when publish-gameframework is skipped
# (e.g. when dispatching for a single engine plugin only).
# We gate on validate succeeding and publish-gameframework not having failed.
if: |
always() &&
needs.validate.result == 'success' &&
(needs.publish-gameframework.result == 'success' || needs.publish-gameframework.result == 'skipped') &&
(
(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')) ||
(github.event_name == 'workflow_dispatch' && github.event.inputs.package != 'gameframework')
)
strategy:
matrix:
package:
- name: gameframework_unity
path: engines/unity/dart
- name: gameframework_unreal
path: engines/unreal/dart
steps:
# Determine at step level whether this specific matrix entry should publish.
# matrix context IS available in step-level expressions.
- name: Check if this package should be published
id: should_publish
run: |
if [[ "${{ github.event_name }}" == "push" ]] || \
[[ "${{ github.event.inputs.package }}" == "all" ]] || \
[[ "${{ github.event.inputs.package }}" == "${{ matrix.package.name }}" ]]; then
echo "publish=true" >> $GITHUB_OUTPUT
else
echo "publish=false" >> $GITHUB_OUTPUT
echo "Skipping ${{ matrix.package.name }} (not selected)"
fi
- name: Checkout repository
if: steps.should_publish.outputs.publish == 'true'
uses: actions/checkout@v4
- name: Setup Flutter
if: steps.should_publish.outputs.publish == 'true'
uses: subosito/flutter-action@v2
with:
flutter-version: '3.27.x'
channel: 'stable'
cache: true
# Only wait if the core package was actually published (not skipped/dry-run)
- name: Wait for gameframework availability on pub.dev
if: |
steps.should_publish.outputs.publish == 'true' &&
github.event.inputs.dry_run != 'true' &&
needs.publish-gameframework.result == 'success'
run: |
echo "Waiting 60 seconds for gameframework to be available on pub.dev..."
sleep 60
- name: Get dependencies
if: steps.should_publish.outputs.publish == 'true'
working-directory: ${{ matrix.package.path }}
run: flutter pub get
- name: Setup pub credentials
if: |
steps.should_publish.outputs.publish == 'true' &&
github.event.inputs.dry_run != 'true'
run: |
mkdir -p $HOME/.pub-cache
echo '${{ secrets.PUB_CREDENTIALS }}' > $HOME/.pub-cache/credentials.json
- name: Publish to pub.dev (dry-run)
if: |
steps.should_publish.outputs.publish == 'true' &&
github.event.inputs.dry_run == 'true'
working-directory: ${{ matrix.package.path }}
run: flutter pub publish --dry-run
- name: Publish to pub.dev
if: |
steps.should_publish.outputs.publish == 'true' &&
github.event.inputs.dry_run != 'true'
working-directory: ${{ matrix.package.path }}
run: flutter pub publish --force
- name: Extract version
if: |
steps.should_publish.outputs.publish == 'true' &&
github.event.inputs.dry_run != 'true'
id: version
working-directory: ${{ matrix.package.path }}
run: |
VERSION=$(grep '^version:' pubspec.yaml | awk '{print $2}')
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Published ${{ matrix.package.name }} v$VERSION"
# Create GitHub release on tag push after all packages are published
create-release:
name: Create GitHub Release
needs: [publish-gameframework, publish-engine-plugins]
runs-on: ubuntu-latest
if: |
always() &&
github.event_name == 'push' &&
startsWith(github.ref, 'refs/tags/v') &&
needs.publish-gameframework.result == 'success' &&
needs.publish-engine-plugins.result == 'success'
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Extract version from tag
id: tag_version
run: echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
- name: Read CHANGELOG
id: changelog
run: |
CHANGELOG_FILE="packages/gameframework/CHANGELOG.md"
if [ -f "$CHANGELOG_FILE" ]; then
CHANGELOG=$(awk '/^## \[?[0-9]/{if(++count==2) exit} count==1' "$CHANGELOG_FILE")
echo "changelog<<EOF" >> $GITHUB_OUTPUT
echo "$CHANGELOG" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
else
echo "changelog=No changelog available" >> $GITHUB_OUTPUT
fi
- name: Create Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref_name }}
name: Release ${{ steps.tag_version.outputs.version }}
body: |
## Flutter Game Framework ${{ steps.tag_version.outputs.version }}
Published packages:
- [gameframework](https://pub.dev/packages/gameframework)
- [gameframework_unity](https://pub.dev/packages/gameframework_unity)
- [gameframework_unreal](https://pub.dev/packages/gameframework_unreal)
### Changelog
${{ steps.changelog.outputs.changelog }}
draft: false
prerelease: ${{ contains(steps.tag_version.outputs.version, '-') }}