Skip to content

Commit 447356d

Browse files
authored
Merge pull request #10 from Helldez/ci/tag-driven-version
ci: derive release version from the git tag (no manual bump, no release PR)
2 parents 5882642 + 301409d commit 447356d

3 files changed

Lines changed: 49 additions & 8 deletions

File tree

.github/workflows/android-apk.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ jobs:
3030
steps:
3131
- name: Checkout
3232
uses: actions/checkout@v4
33+
with:
34+
fetch-depth: 0 # full history so `git rev-list --count` yields a real versionCode
3335

3436
- name: Setup JDK 17
3537
uses: actions/setup-java@v4
@@ -55,6 +57,18 @@ jobs:
5557
- name: Bundle QVAC SDK worker
5658
run: npx qvac bundle sdk
5759

60+
- name: Resolve app version (tag → versionName, commit count → versionCode)
61+
# The git tag is the single source of truth for releases — no version
62+
# bump is committed. app.config.js reads these env vars at prebuild time.
63+
run: |
64+
if [ "${GITHUB_REF_TYPE}" = "tag" ]; then
65+
# Tag "vX.Y.Z" → versionName "X.Y.Z" (strip the leading "v").
66+
echo "RESONANCE_VERSION_NAME=${GITHUB_REF_NAME#v}" >> "$GITHUB_ENV"
67+
fi
68+
# Commit count is strictly increasing across history → a valid,
69+
# monotonic Android versionCode without manual bookkeeping.
70+
echo "RESONANCE_VERSION_CODE=$(git rev-list --count HEAD)" >> "$GITHUB_ENV"
71+
5872
- name: Expo prebuild (generate android/)
5973
run: npx expo prebuild --platform android --clean
6074

AGENTS.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -194,17 +194,21 @@ so nothing build-related needs to be committed.
194194
- **A `v*` tag** builds the APK *and attaches the raw `app-release.apk` to a
195195
GitHub Release*. This is the only binary users should download.
196196

197+
**The git tag is the single source of truth for the version.** Do **not** bump
198+
`app.json`/`package.json` per release — `app.config.js` overrides the version at
199+
build time from env vars CI derives: `versionName` from the tag (`vX.Y.Z`
200+
`X.Y.Z`) and `versionCode` from `git rev-list --count HEAD` (strictly increasing,
201+
so Android always accepts the update). `app.json`'s static version is only the
202+
local-dev fallback.
203+
197204
**To cut a release (the user-facing APK):**
198205

199-
1. On a `release/vX.Y.Z` branch, bump `version` in **both** `app.json` and
200-
`package.json`, and `android.versionCode` in `app.json` (versionCode must
201-
strictly increase or Android refuses the update).
202-
2. Open a PR into `main`, merge it, delete the branch.
203-
3. `git checkout main && git pull --ff-only`, then tag the merge commit and
204-
push the tag: `git tag vX.Y.Z <merge-sha> && git push origin vX.Y.Z`.
205-
4. CI builds from the tagged commit and attaches `app-release.apk` to the new
206+
1. `git checkout main && git pull --ff-only`.
207+
2. Tag the head of `main` and push the tag — that is the whole release:
208+
`git tag vX.Y.Z && git push origin vX.Y.Z`. No branch, no PR, no version bump.
209+
3. CI builds from the tagged commit and attaches `app-release.apk` to the new
206210
Release. Confirm with `gh release view vX.Y.Z`.
207-
5. **Write the release notes — a Release with a bare APK and no body is not
211+
4. **Write the release notes — a Release with a bare APK and no body is not
208212
done.** Use the standing template (see `v0.1.1`): install steps, the
209213
**SHA-256 of the attached APK** (`Get-FileHash app-release.apk -Algorithm
210214
SHA256` on the CI-built artifact), the debug-signing caveat, and a one-line

app.config.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Resonance Expo config.
2+
//
3+
// Static configuration lives in app.json. This thin wrapper lets the release
4+
// pipeline make the **git tag the single source of truth for the version**:
5+
// when CI sets the env vars below (versionName from the tag, versionCode from a
6+
// monotonic commit count), they win; otherwise app.json's values are used, so
7+
// local development and non-release builds are unaffected.
8+
//
9+
// Expo passes the parsed app.json in as `config`, so this only overrides the
10+
// two version fields and leaves everything else untouched.
11+
module.exports = ({ config }) => {
12+
const versionName = process.env.RESONANCE_VERSION_NAME;
13+
const versionCode = process.env.RESONANCE_VERSION_CODE;
14+
15+
return {
16+
...config,
17+
...(versionName ? { version: versionName } : {}),
18+
android: {
19+
...config.android,
20+
...(versionCode ? { versionCode: Number.parseInt(versionCode, 10) } : {}),
21+
},
22+
};
23+
};

0 commit comments

Comments
 (0)