Release channels¶
The three TraceApps (CookTrace, LiftTrace, NutriTrace) publish across three parallel channels. Same model for all of them.
Stable¶
Regular releases follow strict MAJOR.MINOR.PATCH semver. Every stable release:
- Lives on the app's GitHub Releases page marked "Latest" (for example
v1.2.3). - Publishes multi-arch Docker images tagged
:X.Y.Z,:X.Y,:X, and:latest. - Uploads a signed Android APK to the release assets.
- Bumps
package.json,src/lib/version.js, AndroidversionCode+versionName, and adds aCHANGELOG.mdblock.
Stable is what non-tester users install. If a tag is not stable, it will not be marked "Latest" on GitHub.
dev-latest (rolling)¶
dev-latest is a floating GitHub pre-release. Every dev-worthy build overwrites the same tag with a fresh APK; no version bump, no CHANGELOG entry, no release notes. It is the primary channel for testers who want "always the newest thing."
The :dev Docker tag is the equivalent on the container side. It auto-publishes on every push to the dev branch. dev-latest and :dev refresh in step.
Silent overwrite is the whole point. Doc fixes, small refactors, incremental improvements, and iteration on in-flight features all land here without any release-notes ceremony. If a tester's install upgrade path is "redownload the APK and reinstall," they get the newest thing every time.
Milestone v<version>-devNN¶
Numbered dev pre-releases exist for feature milestones testers should be able to pin, install intentionally, or reference by name in bug reports. Examples: a new AI capability, a new wearable integration, a big backup change.
Each numbered milestone gets:
- A permanent GitHub pre-release at
v<version>-devNNwith tester-facing notes. - A
## [X.Y.Z-devNN] - <date>block inCHANGELOG.md, capturing the delta since the previous milestone or the last stable. - A version bump in
package.jsonandsrc/lib/version.js. AndroidversionCodeandversionNameare NOT bumped on dev iterations. - A Docker tag
X.Y.Z-devNNalongside:devon bothghcr.io/traceapps/<app>andtraceapps/<app>(Docker Hub). - A refresh of
dev-latestto point at the same commit.
The <version> reflects what will land as the next stable release. After NT v1.0.3, the next milestone dev build is v1.0.4-dev01 (patch-worthy) or v1.1.0-dev01 (minor-worthy).
Iteration number format¶
- Zero-padded two digits for 1 through 9:
dev01,dev02, …,dev09. - Natural two digits from 10 onward:
dev10,dev11, …,dev99. - No dot between
devand the number. This makes the wholedevNNone alphanumeric semver pre-release identifier, which stays inside SemVer 2.0.0 §9 (which forbids leading zeros in pure-numeric identifiers like.01). It also sorts identically in lex and semver order, so the GitHub Tags page,gh release list, Docker Hub tag lists, and the in-app updater all agree on the orderdev01 < dev02 < … < dev09 < dev10 < … < dev99 < <stable>. - Not expected to hit
dev100+in any patch cycle; if that ever happens, revisit padding width. - Historical note: NT tags
v1.1.0-dev.1throughv1.1.0-dev.15used the older dotted format. They sort correctly ahead of new no-dot tags (dev.15 < dev16), so no retroactive rename was needed.
How Docker tags map¶
| Tag | Channel | Updates when |
|---|---|---|
:X.Y.Z (e.g. 1.2.3) |
Stable | Never; immutable pin |
:X.Y (e.g. 1.2) |
Stable | Any 1.2.z patch release |
:X (e.g. 1) |
Stable | Any 1.y.z minor or patch |
:latest |
Stable | Every stable release |
:X.Y.Z-devNN |
Milestone dev | Never; immutable pin to that milestone |
:dev |
Rolling dev | Every push to the dev branch |
Legacy :X.Y.Z-rc.N tags from before the semver switch remain in the registry; no new -rc tags are cut.
How Android APKs map¶
All APKs, stable and dev, are signed with the shared TraceApps keystore. That has two consequences:
- Upgrades work in place. A newer APK installs straight over an older one. Local SQLite, cached images, and preferences all survive.
- Cross-channel upgrades work too. Moving from stable to
dev-latest, from a numbered milestone to stable, or fromdev-latestto a milestone does not wipe anything, because Android checks the signing key, not the channel.
Downgrades still fail. Android refuses an APK with a lower versionCode, and a forced downgrade via uninstall wipes the app's private storage. Back up first via Settings if you plan to move backwards.
How to pick¶
- Most testers: install
dev-latestand let it float. Redownload from the same URL whenever you want the newest build. - Reporting a bug: if the maintainer asked you to try a specific milestone, or you want a stable label to reference, install a numbered
v<version>-devNN. - Everyone else: install the latest stable release. It is what non-tester users are running.