Derive versionCode from the commit count, not github.run_number
Some checks are pending
pre-commit / pre-commit (push) Waiting to run
Tests / test (3.10) (push) Waiting to run
Tests / test (3.11) (push) Waiting to run
Tests / test (3.12) (push) Waiting to run
release-apk / release (APK) (push) Waiting to run

run_number counts workflow RUNS, not code. Two failure modes, one of which
already bit: it resets to 1 if this file is renamed (the existing NOTE warned
about that), and it can fall BEHIND a build produced outside this workflow.
On 2026-08-09 diet-guard's phone held a manually sideloaded vc 8 while CI's
next build was vc 6, so `adb install -r` refused every CI build with
INSTALL_FAILED_VERSION_DOWNGRADE. The only non-destructive escape was
re-running the workflow until the counter passed 8 -- forcing a downgrade
needs an uninstall, which wipes app data.

`git rev-list --count HEAD` only ever increases, tracks the code rather than
the CI file, and is already far ahead of every installed build (diet-guard
62 vs 9, screen-locker 118 vs 5, wake-alarm 41 vs 5, todo 51).

Needs fetch-depth: 0 -- checkout@v4 is shallow by default and would count 1.
Verified the count is identical from the repo root and from app/, so the
job's `working-directory: app` default does not affect it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GZH89WEqAjuJT8WZdqc7AP
This commit is contained in:
Krzysztof Rudnicki 2026-08-09 18:15:34 +02:00
parent e23f7ac3b4
commit 3ff08f93f6

View File

@ -15,9 +15,13 @@ concurrency:
group: release-apk-${{ github.ref }}
cancel-in-progress: false
# NOTE: versionCode is github.run_number, which is per-workflow-FILE. Never
# rename or replace this file — the counter resets to 1, versionCode goes
# backwards, and Android silently refuses every future update.
# NOTE: versionCode is the commit count (`git rev-list --count HEAD`), which
# only ever increases and tracks the code rather than the CI file. It replaced
# github.run_number on 2026-08-09: run_number counts workflow RUNS, so it
# resets to 1 if this file is renamed AND it can fall behind a build made
# outside this workflow — which happened, leaving CI unable to install over a
# manually sideloaded APK (INSTALL_FAILED_VERSION_DOWNGRADE). The checkout
# below therefore needs fetch-depth: 0; a shallow clone counts 1 commit.
#
# This job is NOT gated on a test suite: this repo has no Flutter analyze/test
# job to depend on, so a broken commit still publishes. The build failing is
@ -31,6 +35,13 @@ jobs:
working-directory: app
steps:
- uses: actions/checkout@v4
with:
# versionCode is the commit count; a shallow clone would report 1.
fetch-depth: 0
- name: Derive versionCode from the commit count
id: vc
run: echo "code=$(git rev-list --count HEAD)" >> "$GITHUB_OUTPUT"
- uses: actions/setup-java@v4
with:
@ -87,7 +98,7 @@ jobs:
run: |
flutter build apk --release \
--build-name="${{ steps.ver.outputs.semver }}" \
--build-number="${{ github.run_number }}"
--build-number="${{ steps.vc.outputs.code }}"
# Fail closed. `findByName("release") ?: debug` silently falls back to
# the debug key if key.properties is misplaced, producing a green build
@ -115,7 +126,7 @@ jobs:
id: art
run: |
set -euo pipefail
out="diet-guard-${{ steps.ver.outputs.semver }}-build.${{ github.run_number }}.apk"
out="diet-guard-${{ steps.ver.outputs.semver }}-build.${{ steps.vc.outputs.code }}.apk"
cp build/app/outputs/flutter-apk/app-release.apk "$out"
echo "path=$out" >> "$GITHUB_OUTPUT"
@ -124,12 +135,12 @@ jobs:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
tag="v${{ steps.ver.outputs.semver }}-build.${{ github.run_number }}"
tag="v${{ steps.ver.outputs.semver }}-build.${{ steps.vc.outputs.code }}"
gh release create "$tag" "${{ steps.art.outputs.path }}" \
--prerelease \
--target "${{ github.sha }}" \
--title "$tag" \
--notes "Automated build of ${{ github.sha }} (versionCode ${{ github.run_number }})."
--notes "Automated build of ${{ github.sha }} (versionCode ${{ steps.vc.outputs.code }})."
# Cut a clean vX.Y.Z the first time a pubspec version is seen. A failing
# `gh release view` is the "not published yet" signal, which also covers
@ -149,4 +160,4 @@ jobs:
gh release create "$tag" "${{ steps.art.outputs.path }}" \
--target "${{ github.sha }}" \
--title "$tag" \
--notes "Release $tag (versionCode ${{ github.run_number }})."
--notes "Release $tag (versionCode ${{ steps.vc.outputs.code }})."