Setup staging domain for main branch merges #359
Workflow file for this run
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: Flutter App CI/CD | |
| on: | |
| push: | |
| branches: [main, copilot/**] | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| pages: write | |
| id-token: write | |
| pull-requests: write | |
| deployments: write | |
| concurrency: | |
| group: ci-${{ github.ref }} | |
| cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} | |
| jobs: | |
| # Detect which files have changed | |
| changes: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| app: ${{ steps.filter.outputs.app }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Check for file changes | |
| uses: dorny/paths-filter@v3 | |
| id: filter | |
| with: | |
| filters: | | |
| app: | |
| - 'lib/**' | |
| - 'web/**' | |
| - 'pubspec.yaml' | |
| - 'test/**' | |
| - 'android/**' | |
| - '.github/workflows/build-deploy.yml' | |
| - 'mise.toml' | |
| # Run tests once before building | |
| test: | |
| needs: changes | |
| runs-on: ubuntu-latest | |
| if: | | |
| github.event_name == 'workflow_dispatch' || | |
| needs.changes.outputs.app == 'true' | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Flutter | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: '3.38.3' | |
| channel: 'stable' | |
| cache: true | |
| - name: Create Firebase google-services.json | |
| run: echo '${{ secrets.GOOGLE_SERVICES_JSON }}' > android/app/google-services.json | |
| - name: Get dependencies | |
| run: flutter pub get | |
| - name: Generate mocks | |
| run: dart run build_runner build --delete-conflicting-outputs | |
| - name: Analyze code | |
| run: flutter analyze --no-fatal-infos | |
| - name: Run tests with coverage | |
| run: flutter test --coverage | |
| - name: Install lcov | |
| run: sudo apt-get update && sudo apt-get install -y lcov | |
| - name: Report code coverage | |
| uses: zgosalvez/github-actions-report-lcov@v4 | |
| with: | |
| coverage-files: coverage/lcov.info | |
| # TODO: Increase coverage target back to 70% as test coverage improves | |
| minimum-coverage: 25 | |
| artifact-name: code-coverage-report | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| update-comment: true | |
| - name: Upload coverage to Codecov | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| files: coverage/lcov.info | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| fail_ci_if_error: false | |
| # Build web after tests pass | |
| build-web: | |
| needs: test | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Flutter | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: '3.38.3' | |
| channel: 'stable' | |
| cache: true | |
| - name: Create Firebase google-services.json | |
| run: echo '${{ secrets.GOOGLE_SERVICES_JSON }}' > android/app/google-services.json | |
| - name: Get dependencies | |
| run: flutter pub get | |
| - name: Get git version info | |
| id: git_version | |
| run: | | |
| chmod +x scripts/get_version_info.sh | |
| scripts/get_version_info.sh github >> $GITHUB_OUTPUT | |
| - name: Build web | |
| run: | | |
| flutter build web --release --base-href "/" \ | |
| --dart-define=GIT_TAG=${{ steps.git_version.outputs.git_tag }} \ | |
| --dart-define=GIT_COMMIT=${{ steps.git_version.outputs.git_commit }} \ | |
| --dart-define=GIT_BRANCH=${{ steps.git_version.outputs.git_branch }} \ | |
| --dart-define=BUILD_VERSION=${{ steps.git_version.outputs.version }} \ | |
| --dart-define=BUILD_TIME=${{ steps.git_version.outputs.build_time }} | |
| - name: Upload build artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: web-build | |
| path: build/web | |
| # Build Android after tests pass | |
| build-android: | |
| needs: test | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up JDK 17 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: '17' | |
| distribution: 'temurin' | |
| - name: Setup Flutter | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: '3.38.3' | |
| channel: 'stable' | |
| cache: true | |
| - name: Create Firebase google-services.json | |
| run: echo '${{ secrets.GOOGLE_SERVICES_JSON }}' > android/app/google-services.json | |
| - name: Get dependencies | |
| run: flutter pub get | |
| - name: Get git version info | |
| id: git_version | |
| run: | | |
| chmod +x scripts/get_version_info.sh | |
| scripts/get_version_info.sh github >> $GITHUB_OUTPUT | |
| - name: Build debug APK | |
| run: | | |
| flutter build apk --debug \ | |
| --dart-define=GIT_TAG=${{ steps.git_version.outputs.git_tag }} \ | |
| --dart-define=GIT_COMMIT=${{ steps.git_version.outputs.git_commit }} \ | |
| --dart-define=GIT_BRANCH=${{ steps.git_version.outputs.git_branch }} \ | |
| --dart-define=BUILD_VERSION=${{ steps.git_version.outputs.version }} \ | |
| --dart-define=BUILD_TIME=${{ steps.git_version.outputs.build_time }} | |
| - name: Build release APK (unsigned) | |
| run: | | |
| flutter build apk --release \ | |
| --dart-define=GIT_TAG=${{ steps.git_version.outputs.git_tag }} \ | |
| --dart-define=GIT_COMMIT=${{ steps.git_version.outputs.git_commit }} \ | |
| --dart-define=GIT_BRANCH=${{ steps.git_version.outputs.git_branch }} \ | |
| --dart-define=BUILD_VERSION=${{ steps.git_version.outputs.version }} \ | |
| --dart-define=BUILD_TIME=${{ steps.git_version.outputs.build_time }} | |
| - name: Build release App Bundle (unsigned) | |
| run: | | |
| flutter build appbundle --release \ | |
| --dart-define=GIT_TAG=${{ steps.git_version.outputs.git_tag }} \ | |
| --dart-define=GIT_COMMIT=${{ steps.git_version.outputs.git_commit }} \ | |
| --dart-define=GIT_BRANCH=${{ steps.git_version.outputs.git_branch }} \ | |
| --dart-define=BUILD_VERSION=${{ steps.git_version.outputs.version }} \ | |
| --dart-define=BUILD_TIME=${{ steps.git_version.outputs.build_time }} | |
| - name: Upload debug APK | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: app-debug-apk | |
| path: build/app/outputs/flutter-apk/app-debug.apk | |
| if-no-files-found: error | |
| - name: Upload release APK | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: app-release-apk | |
| path: build/app/outputs/flutter-apk/app-release.apk | |
| if-no-files-found: error | |
| - name: Upload release App Bundle | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: app-release-aab | |
| path: build/app/outputs/bundle/release/app-release.aab | |
| if-no-files-found: error | |
| deploy-web: | |
| needs: build-web | |
| runs-on: ubuntu-latest | |
| if: github.ref == 'refs/heads/main' | |
| environment: | |
| name: github-pages | |
| url: ${{ steps.deployment.outputs.page_url }} | |
| steps: | |
| - name: Download build artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: web-build | |
| path: build/web | |
| - name: Setup Pages | |
| uses: actions/configure-pages@v4 | |
| - name: Upload to GitHub Pages | |
| uses: actions/upload-pages-artifact@v3 | |
| with: | |
| path: build/web | |
| - name: Deploy to GitHub Pages | |
| id: deployment | |
| uses: actions/deploy-pages@v4 | |
| deploy-web-preview: | |
| needs: [changes, build-web] | |
| runs-on: ubuntu-latest | |
| if: | | |
| github.event_name == 'workflow_dispatch' || | |
| needs.changes.outputs.app == 'true' | |
| steps: | |
| - name: Download build artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: web-build | |
| path: build/web | |
| - name: Deploy to Cloudflare Pages (Staging/PR Previews) | |
| id: deploy | |
| uses: cloudflare/wrangler-action@v3 | |
| with: | |
| apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| command: pages deploy build/web --project-name=staging-cambeerfestival --branch=${{ github.head_ref || github.ref_name }} | |
| - name: Comment PR with Preview URL | |
| if: github.event_name == 'pull_request' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const aliasUrl = '${{ steps.deploy.outputs.pages-deployment-alias-url }}'; | |
| const deployUrl = '${{ steps.deploy.outputs.deployment-url }}'; | |
| const previewUrl = aliasUrl || deployUrl; | |
| const comment = `## 🚀 Cloudflare Pages Preview | |
| Your preview deployment is ready! | |
| **Preview URL**: ${previewUrl} | |
| This preview will be automatically updated when you push new commits to this PR.`; | |
| github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: comment | |
| }); |