Skip to content

chore(mobile): read the app version from the tag instead of committing it - #89

Merged
Cawlumm merged 2 commits into
mainfrom
chore/version-from-tag
Aug 7, 2026
Merged

chore(mobile): read the app version from the tag instead of committing it#89
Cawlumm merged 2 commits into
mainfrom
chore/version-from-tag

Conversation

@Cawlumm

@Cawlumm Cawlumm commented Aug 6, 2026

Copy link
Copy Markdown
Owner

The release version lived in two places — mobile/app.json, bumped by hand before each tag, and the tag itself. CI papered over the gap by rewriting app.json during the build, so the committed value was simultaneously required by process and ignored in practice. A ritual whose only failure mode is silent.

mobile/app.config.js now reads the version from LYFTR_VERSION, which the release job sets from the tag. The tag becomes the only place a release version exists: nothing to bump, nothing to drift, and the stamp step is deleted rather than made more careful.

module.exports = ({ config }) => ({
  ...config,
  version: process.env.LYFTR_VERSION || config.version,
})

Changes

  • mobile/app.config.js — new; the only thing it overrides is version. Everything static stays in app.json.
  • expo.version becomes an explicit dev placeholder, 0.0.0-dev, used when LYFTR_VERSION is unset: local expo start, dev builds, dry runs. Never what ships.
  • android.versionCode dropped. It was kept as a seed to initialize the remote counter on the first appVersionSource: remote build. That has happened — the counter stands at 5 on EAS — so the field was inert, and the CLI recommended removing it on every build.
  • Workflow — the "Stamp the version into app.json" step is gone; the build step passes LYFTR_VERSION instead.
  • RELEASING.md — the "bump expo.version before tagging" instruction is replaced with "there is nothing to bump."

Verification

expo config --json resolves correctly both ways:

env resolved version
unset 0.0.0-dev
LYFTR_VERSION=0.1.0-beta.5 0.1.0-beta.5
LYFTR_VERSION=9.9.9 9.9.9

android.versionCode resolves to undefined, i.e. left to EAS. npm run type-check passes.

What this can't prove before merge: a dry run leaves LYFTR_VERSION unset by design, so CI can only exercise the fallback. The tag path is verified locally via expo config above, but its first real proof is the next tagged release — where the existing gate already fails the build if the APK's versionName doesn't match the tag. So a regression here surfaces as a failed release, not a bad one.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JxKyZy6vR6xKu7Sp2MrEwn

Cawlumm and others added 2 commits August 5, 2026 22:21
…g it

The release version lived in two places: mobile/app.json, bumped by hand before each
tag, and the tag itself. CI papered over the gap by rewriting app.json during the
build — so the committed value was simultaneously required by process and ignored in
practice. That's a bump ritual whose only failure mode is silent.

mobile/app.config.js now reads the version from LYFTR_VERSION, which the release job
sets from the tag being built. The tag becomes the only place a release version
exists: nothing to bump, nothing to drift, and the stamp step is gone rather than
made more careful.

expo.version in app.json becomes an explicit dev placeholder (0.0.0-dev) for when
LYFTR_VERSION is unset — local expo start, dev builds, dry runs. It is never what
ships, and RELEASING.md says so.

android.versionCode is dropped entirely. It was kept as a seed to initialize the
remote counter on the first appVersionSource: remote build; that has happened (the
counter stands at 5 on EAS), so the field was inert and the CLI recommended removing
it on every build.

Verified `expo config --json` resolves 0.0.0-dev with no env var, and the exact value
of LYFTR_VERSION when set.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JxKyZy6vR6xKu7Sp2MrEwn
The dry run left LYFTR_VERSION unset and fell back to app.json's 0.0.0-dev — which is
also app.config.js's fallback. So the versionName gate compared the fallback against
itself and passed whether or not the variable ever reached the build. A check that
cannot fail.

EAS evaluates the app config both locally and on the builder, so that plumbing is
precisely what needs proving before a tagged release depends on it. A dry run now
builds as 0.0.0-dryrun.<run number>, a value that can only appear in the APK if
LYFTR_VERSION actually flowed through — and the existing verify step then proves it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JxKyZy6vR6xKu7Sp2MrEwn
@Cawlumm
Cawlumm merged commit 34693b8 into main Aug 7, 2026
34 of 40 checks passed
@Cawlumm
Cawlumm deleted the chore/version-from-tag branch August 7, 2026 11:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant