diff --git a/.forgejo/workflows/release.yml b/.forgejo/workflows/release.yml index f956269..d598b06 100644 --- a/.forgejo/workflows/release.yml +++ b/.forgejo/workflows/release.yml @@ -47,7 +47,75 @@ on: default: '' jobs: + # Test gate. Forgejo/Actions workflows are independent — there is no cross-workflow + # `needs:`, and ci.yml does NOT trigger on tag pushes (its `branches` filter never + # matches refs/tags/*). So the CI test jobs are duplicated here (verbatim from + # ci.yml) to gate the deploy: nothing ships unless analyze + both test suites pass. + # Keep these in sync with ci.yml by hand. + analyze: + runs-on: docker + container: + image: ghcr.io/cirruslabs/flutter:3.41.9 + steps: + - name: Checkout + env: + TOKEN: ${{ github.token }} + run: | + git config --global --add safe.directory '*' + git init -q . + git remote add origin "http://x-access-token:${TOKEN}@forgejo:3000/${GITHUB_REPOSITORY}.git" + git fetch -q --depth 1 origin "${GITHUB_SHA}" + git checkout -q FETCH_HEAD + - run: flutter pub get + - run: flutter analyze + + test-commons-core: + runs-on: docker + container: + image: ghcr.io/cirruslabs/flutter:3.41.9 + steps: + - name: Checkout + env: + TOKEN: ${{ github.token }} + run: | + git config --global --add safe.directory '*' + git init -q . + git remote add origin "http://x-access-token:${TOKEN}@forgejo:3000/${GITHUB_REPOSITORY}.git" + git fetch -q --depth 1 origin "${GITHUB_SHA}" + git checkout -q FETCH_HEAD + - run: flutter pub get + - name: dart test + working-directory: packages/commons_core + run: dart test + + test-app-seeds: + runs-on: docker + container: + image: ghcr.io/cirruslabs/flutter:3.41.9 + steps: + - name: Checkout + env: + TOKEN: ${{ github.token }} + run: | + git config --global --add safe.directory '*' + git init -q . + git remote add origin "http://x-access-token:${TOKEN}@forgejo:3000/${GITHUB_REPOSITORY}.git" + git fetch -q --depth 1 origin "${GITHUB_SHA}" + git checkout -q FETCH_HEAD + # SQLCipher so the "no plaintext at rest" security test actually runs. + - run: apt-get update -qq && apt-get install -y -qq libsqlcipher-dev + - run: flutter pub get + - name: Generate code + test + working-directory: apps/app_seeds + run: | + dart run slang + dart run build_runner build --delete-conflicting-outputs + flutter test --coverage + play: + # Gate on the tests: with no status-check function in this `if`, the implicit + # success() on `needs` still applies — play runs only on a tag AND green tests. + needs: [analyze, test-commons-core, test-app-seeds] if: ${{ startsWith(github.ref, 'refs/tags/') }} runs-on: docker container: @@ -121,11 +189,16 @@ jobs: fdroid_reference_armeabi_v7a: # Serialize after play so two heavy Android builds never run concurrently on # the shared host (capacity:2) — that contention OOM-killed play's Gradle - # daemon. `if: always()` keeps the fdroid chain independent of play's result - # (runs after play whether it succeeded, failed, or — on workflow_dispatch — - # was skipped). - needs: play - if: ${{ always() }} + # daemon. Gated on the test jobs, but kept INDEPENDENT of play's result: + # `!cancelled()` is a status function, which drops the implicit success() on + # `needs`, so play failing/skipping (e.g. on workflow_dispatch, where play is + # tag-only) does not block the fdroid chain — while the explicit result checks + # still hard-gate on green tests. Nothing gets built/uploaded on a red suite. + needs: [analyze, test-commons-core, test-app-seeds, play] + if: ${{ !cancelled() + && needs.analyze.result == 'success' + && needs.test-commons-core.result == 'success' + && needs.test-app-seeds.result == 'success' }} runs-on: docker container: image: registry.gitlab.com/fdroid/fdroidserver:buildserver-trixie