Skip to content

feat(desktop): mirror each release to a stable bucket prefix - #270

Merged
quickbeard merged 1 commit into
mainfrom
stable-download-prefix
Aug 19, 2026
Merged

quickbeard merged 1 commit into
mainfrom
stable-download-prefix

Conversation

@quickbeard

Copy link
Copy Markdown
Owner

A download link had to name /codev/<version>/<file>, so any link written down anywhere — the docs, an email, a chat message — died at the next release. stage-release.ts now also copies each installer to /codev/latest/<file>.

How

mc cp <target>/1.18.4-9/codev-code-desktop-linux-amd64.deb \
      <target>/latest/codev-code-desktop-linux-amd64.deb

Both sides are already in the bucket, so mc issues a server-side copy: the mirror costs storage, not a second upload of ~1.8 GB. Ordering is artifacts → mirror → manifests, preserving the existing "manifests last" rule.

Blockmaps are skipped. They only mean anything beside the artifact a manifest names, and manifests name <version>/.

This cannot affect auto-update. Nothing reads the prefix — the manifests still name <version>/, which is all an installed build ever resolves. It exists purely so a human-facing link keeps working.

Also: stops uploading everything four times

Not a new problem, but it compounds with adding more copy operations, so it's fixed here. The upload loop ran per manifest and uploaded the version folder whole:

for (const manifest of manifests) {
  const version = …                       // same version for every manifest
  for (const file of await readdir(join(outDir, version)))
    await upload(…)                       // ← every artifact, once per manifest
}

Every channel file of a release carries the same version, so a two-channel Linux release uploaded each artifact twice and a full four-channel release would upload each one four times. This is observable in the current output — the Linux release staged yesterday printed all eight mc cp lines twice. Deduping the versions into a Set first makes it once.

Verified

No unit test: the script's payload is mc invocations, and testing that would mean mocking $, which the repo's testing guidance rules out. Instead it was run end to end on a synthetic release — two channel files, three artifacts each, two blockmaps — with CODEV_UPDATE_TARGET unset so it prints rather than uploads:

  • 8 uploads to 1.18.4-9/ (6 artifacts + 2 blockmaps), each exactly once
  • 6 in-bucket mirrors to latest/, blockmaps correctly absent
  • 2 manifests last

bun typecheck clean.

Scope notes

  • No DIVERGENCES.md row: scripts/stage-release.ts is a fork-only file, which the divergence policy excludes, and the new layout is documented in the script's own header.
  • No CHANGELOG.md entry: nothing about the app changes. This is release tooling and bucket layout.
  • The latest/ folder sits beside the latest*.yml files, which is a little confusable on a listing. Kept anyway because it is the name a download link is expected to have; STABLE_PREFIX is a one-line change if you'd rather it were current/.
  • Stale objects are not pruned: if a future release drops a target, that installer lingers in latest/ from the previous one. Worth an mc mirror --remove if the target list ever changes.

Follow-up, not included

The docs page resolves downloads through a redirect route (landing-page #114) rather than these URLs, so it needs no change. This makes the bucket URL stable too, for links outside the docs site.

🤖 Generated with Claude Code

A download link had to name /codev/<version>/<file>, so every link
written down anywhere — docs, an email, a chat message — died at the
next release. stage-release now also copies each installer to
/codev/latest/<file>.

Both sides are already in the bucket, so mc does a server-side copy:
the mirror costs storage, not a second upload of ~1.8GB. Blockmaps are
skipped, since they only mean anything beside the artifact a manifest
names, which is the versioned copy.

Nothing reads the prefix. The manifests still name <version>/ and that
is all an installed build resolves, so this cannot affect auto-update.

Also stops uploading every artifact once per channel file. The loop
uploaded a whole version folder for each manifest, and every manifest of
a release carries the same version — so a four-channel release uploaded
each artifact four times. Deduping the versions first makes it once.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@quickbeard
quickbeard merged commit b36022e into main Aug 19, 2026
0 of 5 checks passed
@quickbeard
quickbeard deleted the stable-download-prefix branch August 19, 2026 06:29
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