From 7c0f9750d8968461c001322e01c287f673629dfb Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Sat, 2 May 2026 17:42:38 -0400 Subject: [PATCH] =?UTF-8?q?ci(flutter):=20Forgejo=20workflow=20=E2=80=94?= =?UTF-8?q?=20sync,=20analyze,=20test,=20build=20APK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Triggers on push to dev/main, tag pushes, PR to main, and manual dispatch — all path-filtered to flutter_client/** and the three shared web inputs the sync_shared.sh script reads. Steps: - Sync tokens/error-copy/svg from web/ via tool/sync_shared.sh - Re-run dart run tool/gen_tokens.dart and fail if lib/theme/tokens.dart drifts from shared/fabledsword.tokens.json (catches forgotten regen on the JSON edit path) - flutter pub get / analyze --fatal-infos / test - Debug APK on every push (uploaded as a workflow artifact) - Release APK on tag, attached to the corresponding Forgejo release via RELEASE_TOKEN (release.yml creates the release entry; this workflow just attaches the APK as minstrel-.apk) Uses subosito/flutter-action@v2 on ubuntu-latest for portability — no dependence on a Flutter-pre-installed runner. --- .forgejo/workflows/flutter.yml | 105 +++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 .forgejo/workflows/flutter.yml diff --git a/.forgejo/workflows/flutter.yml b/.forgejo/workflows/flutter.yml new file mode 100644 index 00000000..c46b131f --- /dev/null +++ b/.forgejo/workflows/flutter.yml @@ -0,0 +1,105 @@ +name: flutter + +# Analyze + test + build the Flutter mobile client. Only runs when the +# diff touches flutter_client/ or one of the shared web inputs the +# sync_shared.sh script copies. Other pushes skip — this workflow is +# independent from the Go/web test.yml and release.yml. + +on: + push: + branches: [dev, main] + tags: ['v*'] + paths: + - 'flutter_client/**' + - 'web/src/lib/styles/tokens.json' + - 'web/src/lib/styles/error-copy.json' + - 'web/static/placeholders/album-fallback.svg' + - '.forgejo/workflows/flutter.yml' + pull_request: + branches: [main] + paths: + - 'flutter_client/**' + - 'web/src/lib/styles/tokens.json' + - 'web/src/lib/styles/error-copy.json' + - 'web/static/placeholders/album-fallback.svg' + - '.forgejo/workflows/flutter.yml' + workflow_dispatch: + +jobs: + analyze-test-build: + runs-on: ubuntu-latest + + defaults: + run: + working-directory: flutter_client + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Flutter + uses: subosito/flutter-action@v2 + with: + flutter-version: '3.24.5' + channel: stable + cache: true + + - name: Sync shared assets from web/ + run: ./tool/sync_shared.sh + + - name: Verify generated tokens.dart matches JSON + shell: bash + run: | + dart run tool/gen_tokens.dart + if ! git diff --exit-code lib/theme/tokens.dart; then + echo "::error::lib/theme/tokens.dart is out of sync with shared/fabledsword.tokens.json" + echo "Run: cd flutter_client && dart run tool/gen_tokens.dart" + exit 1 + fi + + - name: Pub get + run: flutter pub get + + - name: Analyze + run: flutter analyze --fatal-infos + + - name: Test + run: flutter test --reporter compact + + - name: Build debug APK + if: github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/') + run: flutter build apk --debug + + - name: Build release APK + if: startsWith(github.ref, 'refs/tags/v') + run: flutter build apk --release + + - name: Upload debug APK artifact + if: github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/') + uses: forgejo/upload-artifact@v3 + with: + name: minstrel-debug-${{ github.sha }} + path: flutter_client/build/app/outputs/flutter-apk/app-debug.apk + + - name: Attach release APK to release + if: startsWith(github.ref, 'refs/tags/v') + shell: bash + env: + RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }} + run: | + TAG="${GITHUB_REF#refs/tags/}" + REPO="${GITHUB_REPOSITORY}" + # Look up the release ID for this tag (release must exist already; + # release.yml creates it as part of the server-side release flow). + RELEASE_ID=$(curl -fsSL \ + -H "Authorization: token ${RELEASE_TOKEN}" \ + "https://git.fabledsword.com/api/v1/repos/${REPO}/releases/tags/${TAG}" \ + | grep -oP '"id":\s*\K[0-9]+' | head -1) + if [ -z "${RELEASE_ID}" ]; then + echo "::error::release for tag ${TAG} not found" + exit 1 + fi + curl -fsSL \ + -H "Authorization: token ${RELEASE_TOKEN}" \ + -F "attachment=@build/app/outputs/flutter-apk/app-release.apk" \ + "https://git.fabledsword.com/api/v1/repos/${REPO}/releases/${RELEASE_ID}/assets?name=minstrel-${TAG}.apk"