Skip to content

Setup staging domain for main branch merges #359

Setup staging domain for main branch merges

Setup staging domain for main branch merges #359

Workflow file for this run

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
});