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: # flutter-ci runner image (CI-Runner/CI-flutter/Dockerfile) bakes in # Flutter SDK + Android cmdline-tools + platform-34 + build-tools 34.0.0 # + JDK 17 + a non-root `runner` user. No setup-action ceremony needed. runs-on: flutter-ci defaults: run: working-directory: flutter_client steps: - name: Checkout uses: actions/checkout@v4 - 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"