Skip to content

Merge pull request #241 from richardthe3rd/fix/festival-switch-freeze #109

Merge pull request #241 from richardthe3rd/fix/festival-switch-freeze

Merge pull request #241 from richardthe3rd/fix/festival-switch-freeze #109

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
permissions:
contents: read
id-token: write
pull-requests: write
deployments: write
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
lint-pr:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# 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/**'
- 'test-e2e/**'
- 'package.json'
- 'playwright.config.ts'
- '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 App
uses: ./.github/actions/setup-flutter-app
with:
google-services-json: ${{ secrets.GOOGLE_SERVICES_JSON }}
generate-mocks: 'true'
- 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
# Updated: Coverage threshold increased from 25% to 70%
# Current coverage: 72%+ with comprehensive test improvements
minimum-coverage: 70
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 App
uses: ./.github/actions/setup-flutter-app
with:
google-services-json: ${{ secrets.GOOGLE_SERVICES_JSON }}
- name: Get git version info
id: git_version
run: 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
# Run E2E tests on web build
test-e2e-web:
needs: build-web
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Download web build artifact
uses: actions/download-artifact@v4
with:
name: web-build
path: build/web
- name: Install npm dependencies
run: npm ci
- name: Install Playwright browsers
run: npx playwright install --with-deps chromium
- name: Start http-server in background
run: |
npx http-server build/web -p 8080 -c-1 -a 127.0.0.1 --proxy http://127.0.0.1:8080? > /dev/null 2>&1 &
echo $! > .http-server.pid
- name: Wait for server to be ready
run: |
timeout 30 bash -c 'until curl -s http://127.0.0.1:8080 > /dev/null; do sleep 1; done' || exit 1
# Additional wait to ensure Flutter app fully initializes
sleep 3
# Verify server responds to festival route (tests SPA routing)
curl -f -s http://127.0.0.1:8080/cbf2025 > /dev/null || (echo "SPA routing not working" && exit 1)
- name: Run Playwright tests
run: npx playwright test
- name: Upload Playwright report
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: playwright-report/
retention-days: 7
- name: Stop http-server
if: always()
run: |
if [ -f .http-server.pid ]; then
kill $(cat .http-server.pid) || true
rm .http-server.pid
fi
# 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: Cache Gradle dependencies
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Setup Flutter App
uses: ./.github/actions/setup-flutter-app
with:
google-services-json: ${{ secrets.GOOGLE_SERVICES_JSON }}
- name: Get git version info
id: git_version
run: 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: 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
deploy-web-preview:
needs: [changes, build-web, test-e2e-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
});