From 7ae35920f8062dc60a951e98fa4bac9cf4f5e88f Mon Sep 17 00:00:00 2001 From: vjrj Date: Wed, 22 Jul 2026 18:38:06 +0200 Subject: [PATCH] ci(release): gate Play + F-Droid deploy on the test suite MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Forgejo workflows are independent — ci.yml never triggers on tag pushes (its branches filter skips refs/tags/*), so releases shipped with zero test gating. Duplicate analyze + test-commons-core + test-app-seeds into release.yml and make play needs them; gate the fdroid chain on the same tests via explicit result checks while keeping !cancelled() so it stays decoupled from play's result. Red suite now blocks every deploy. --- .forgejo/workflows/release.yml | 83 ++++++++++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 5 deletions(-) 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