Publish to pub.dev #4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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, '-') }} |