ci(release): gate Play + F-Droid deploy on the test suite

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.
This commit is contained in:
vjrj 2026-07-22 18:38:06 +02:00
parent f04dd3da1a
commit 7ae35920f8

View file

@ -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