From 831730e30824ab7f86903901ea6a12258cbfe048 Mon Sep 17 00:00:00 2001 From: vjrj Date: Sun, 19 Jul 2026 10:31:36 +0200 Subject: [PATCH] ci(release): redirect app clone to internal Forgejo; robust apksigner; manual dispatch (play=tags only) --- .forgejo/workflows/release.yml | 42 ++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/.forgejo/workflows/release.yml b/.forgejo/workflows/release.yml index 4d78872..3053c12 100644 --- a/.forgejo/workflows/release.yml +++ b/.forgejo/workflows/release.yml @@ -27,9 +27,13 @@ on: push: tags: - 'v*' + # Manual trigger to test the fdroid_reference job on a branch without cutting a + # tag or deploying to Play (the play job below is guarded to tags only). + workflow_dispatch: jobs: play: + if: ${{ startsWith(github.ref, 'refs/tags/') }} runs-on: docker container: image: ghcr.io/cirruslabs/flutter:3.41.9 @@ -119,6 +123,10 @@ jobs: export PATH="$fds:$PATH" export PYTHONPATH="$fds:$fds/examples" git config --global --add safe.directory '*' + # The job container reaches github.com but not the host's public git.comunes.org + # (NAT hairpin); redirect the app clone to the internal Forgejo host so + # `fdroid build` can fetch the source (and SOURCE_DATE_EPOCH from its commit). + git config --global url."http://x-access-token:${TOKEN}@forgejo:3000/".insteadOf "https://git.comunes.org/" # 3) Fetch our in-repo recipe (the single source of truth) at this commit, # plus the pubspec versionCode base for the per-ABI codes. @@ -151,15 +159,23 @@ jobs: "org.comunes.tane:$((base * 10 + 3))" # 6) Sign each unsigned APK with tane-upload and attach to the Forgejo release. - apksigner=$(ls -d "$ANDROID_HOME"/build-tools/*/apksigner | sort -V | tail -1) + apksigner=$(find "$ANDROID_HOME" -name apksigner -type f 2>/dev/null | sort -V | tail -1) + if [ -z "$apksigner" ]; then + yes | sdkmanager "build-tools;34.0.0" >/dev/null 2>&1 || true + apksigner=$(find "$ANDROID_HOME" -name apksigner -type f 2>/dev/null | sort -V | tail -1) + fi echo "$TANE_KEYSTORE_BASE64" | base64 -d > /tmp/ks.jks api="http://forgejo:3000/api/v1/repos/${GITHUB_REPOSITORY}" tag="${GITHUB_REF_NAME}" - curl -sf -X POST "$api/releases" \ - -H "Authorization: token ${TOKEN}" -H 'Content-Type: application/json' \ - -d "{\"tag_name\":\"${tag}\",\"name\":\"${tag}\"}" >/dev/null || true - rid=$(curl -sf -H "Authorization: token ${TOKEN}" "$api/releases/tags/${tag}" \ - | python3 -c 'import sys,json;print(json.load(sys.stdin)["id"])') + is_tag=false; [ "${GITHUB_REF_TYPE:-}" = tag ] && is_tag=true + rid="" + if $is_tag; then + curl -sf -X POST "$api/releases" \ + -H "Authorization: token ${TOKEN}" -H 'Content-Type: application/json' \ + -d "{\"tag_name\":\"${tag}\",\"name\":\"${tag}\"}" >/dev/null || true + rid=$(curl -sf -H "Authorization: token ${TOKEN}" "$api/releases/tags/${tag}" \ + | python3 -c 'import sys,json;print(json.load(sys.stdin)["id"])') + fi for f in unsigned/org.comunes.tane_*.apk; do vc=$(echo "$f" | sed -E 's/.*_([0-9]+)\.apk/\1/') case $((vc % 10)) in @@ -172,9 +188,15 @@ jobs: "$apksigner" sign --ks /tmp/ks.jks --ks-key-alias "$TANE_KEY_ALIAS" \ --ks-pass "pass:$TANE_KEYSTORE_PASSWORD" --key-pass "pass:$TANE_KEY_PASSWORD" \ --out "$out" "$f" - curl -sf -X POST "$api/releases/${rid}/assets?name=app-${abi}-release.apk" \ - -H "Authorization: token ${TOKEN}" \ - -F "attachment=@${out};type=application/vnd.android.package-archive" - echo "uploaded app-${abi}-release.apk (from ${f##*/})" + # Prove the signer cert matches AllowedAPKSigningKeys. + "$apksigner" verify --print-certs "$out" | grep -i 'SHA-256' || true + if $is_tag; then + curl -sf -X POST "$api/releases/${rid}/assets?name=app-${abi}-release.apk" \ + -H "Authorization: token ${TOKEN}" \ + -F "attachment=@${out};type=application/vnd.android.package-archive" + echo "uploaded app-${abi}-release.apk (from ${f##*/})" + else + echo "built+signed app-${abi}-release.apk (dispatch: upload skipped)" + fi done rm -f /tmp/ks.jks