ci: main publishes, so a tag stops being required — and :latest stops shipping a dev client
CI & Build / Build now, or wait for Android? (push) Successful in 3s
CI & Build / Python lint (push) Successful in 3s
CI & Build / TypeScript typecheck (push) Successful in 7s
CI & Build / Python tests (push) Successful in 11s
CI & Build / integration (push) Successful in 17s
CI & Build / Build & push image (push) Skipped
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 3m21s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 6m36s
Desktop (Tauri) / Update manifest (push) Successful in 4s
Android / Kotlin + Rust (APK) (push) Successful in 9m24s
CI & Build / Build now, or wait for Android? (push) Successful in 3s
CI & Build / Python lint (push) Successful in 3s
CI & Build / TypeScript typecheck (push) Successful in 7s
CI & Build / Python tests (push) Successful in 11s
CI & Build / integration (push) Successful in 17s
CI & Build / Build & push image (push) Skipped
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 3m21s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 6m36s
Desktop (Tauri) / Update manifest (push) Successful in 4s
Android / Kotlin + Rust (APK) (push) Successful in 9m24s
Step 3 of M314. Note 3127 §0's diagnostic is "is `main` publishing sufficient for a user to receive the build" — and here it was not. The desktop and Android lanes BUILT on main and published nothing: `Publish release` was gated on `refs/tags/v*`, the channel publishes on `refs/heads/dev`, the manifest job on dev-or-tag. So the stable channel moved only when somebody cut a tag, which made a `v*` tag load-bearing rather than the optional bookmark the model wants. Both channels are rolling fixed-tag releases now. `dev` from dev, `stable` from main, same machinery — `publish-release.sh` already took RELEASE_TAG, `write-manifest.sh` already pruned, and both already PATCHed a stale description on 409 (#2182). This is wiring, not new mechanism. ## The defect this carried `ci.yml`'s "Fetch the Android client to bake in" read `releases/download/dev` UNCONDITIONALLY, on every branch. Every image baked in the dev APK — `:latest` included — so a stable server served a dev-channel client to anyone who downloaded it from there. That has nothing to do with versioning; it is fixed here because this is the step that finally gives `stable` an APK to point at. It also means Android needs no channel machinery of its own. The APK is served FROM the image, so the channel is already a property of which image you run — note 3127 §7's "nothing to hand off" shape, arrived at here by accident. One branch-conditional line, not a second channel in `client_dist.py` as this milestone first assumed. ## The break this nearly shipped `install.sh --channel stable` read the version out of `stable/latest.json` and then fetched `releases/tags/v<version>` for the bundles — correct while stable was a manifest-only pointer, and broken the moment stable holds its own. Stable is the DEFAULT channel, so `curl … | sh` would have failed for everyone between this commit and the first merge to main. Both channels are one lookup now: fetch the fixed-tag release, install what is on it. A transitional fallback covers the window where `stable` still has no bundles, marked for deletion in step 7 — without it the default channel is broken for however long it takes to merge, and that window is gated on an operator request rather than on this lane. ## The two writers problem `stable`'s manifest was written by tag builds. It is written by main now, and the tag path stops writing it — two writers for one channel is a race with no winner worth having. A `v*` tag still writes its own versioned manifest; its build consequence goes entirely in step 7. Also corrected: `update.rs`'s header still described stable as following `v*` tags. Nothing in that file moved — it only ever read `<channel>/latest.json` — but the comment was a lie, and it is the file somebody reads to understand the feed. #3143 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -199,19 +199,29 @@ jobs:
|
||||
JSON
|
||||
cat dist/thoughtsync-android.json
|
||||
|
||||
# The rolling dev channel, same fixed-tag release the desktop bundles use.
|
||||
# CI artifacts are per-run and auth-gated, so they are no use as a fetch
|
||||
# target; a release asset has a permanent URL. Only ever a SIGNED build —
|
||||
# publishing an unsigned APK would offer people something they cannot
|
||||
# install over what they already have.
|
||||
- name: Publish to the dev channel
|
||||
if: github.ref == 'refs/heads/dev' && steps.build.outputs.keystore != ''
|
||||
# The rolling channel for this branch, the same fixed-tag releases the desktop
|
||||
# bundles use. CI artifacts are per-run and auth-gated, so they are no use as a
|
||||
# fetch target; a release asset has a permanent URL. Only ever a SIGNED build —
|
||||
# publishing an unsigned APK would offer people something they cannot install
|
||||
# over what they already have.
|
||||
#
|
||||
# `stable` from main is new in M314 step 3, and it is what lets the server image
|
||||
# bake in a client that matches its own channel: a :latest image fetches the APK
|
||||
# from `stable`, a :dev image from `dev`. Before this, main published no APK at
|
||||
# all and every image — stable included — baked in the dev one.
|
||||
- name: Publish to the channel for this branch
|
||||
if: (github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main') && steps.build.outputs.keystore != ''
|
||||
working-directory: .
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
RELEASE_TAG: dev
|
||||
RELEASE_PRERELEASE: "true"
|
||||
run: bash desktop/packaging/publish-release.sh
|
||||
run: |
|
||||
case "$GITHUB_REF_NAME" in
|
||||
main) RELEASE_TAG=stable; RELEASE_PRERELEASE=false ;;
|
||||
*) RELEASE_TAG=dev; RELEASE_PRERELEASE=true ;;
|
||||
esac
|
||||
export RELEASE_TAG RELEASE_PRERELEASE
|
||||
echo "Publishing the APK to the $RELEASE_TAG channel."
|
||||
bash desktop/packaging/publish-release.sh
|
||||
|
||||
- name: Upload the APK
|
||||
# Mirrored action, never actions/upload-artifact. @v4+ throws
|
||||
|
||||
Reference in New Issue
Block a user