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"