Skip to content

feat(worker): flip route to production for Phase 4a-APT#503

Merged
aaddrick merged 1 commit intomainfrom
phase-4a-apt-production-route
Apr 23, 2026
Merged

feat(worker): flip route to production for Phase 4a-APT#503
aaddrick merged 1 commit intomainfrom
phase-4a-apt-production-route

Conversation

@aaddrick
Copy link
Copy Markdown
Owner

Summary

Flips worker/wrangler.toml from pkg-staging.claude-desktop-debian.devpkg.claude-desktop-debian.dev. This is the Phase 4a-APT cutover step from docs/worker-apt-plan.md — it unblocks #493 by making the strip-binaries liveness probe in update-apt-repo / update-dnf-repo start succeeding, which lets gh-pages pushes go through without the >100MB .deb tripping GitHub's hard cap.

Draft because there are manual pre-reqs outside this PR that have to complete before merging. PR body spells them out.

Validation that got us here

Phase 2 container matrix was re-run against pkg-staging.claude-desktop-debian.dev today:

Container Result
debian:stable ✅ install via Worker
ubuntu:24.04 ✅ install via Worker
debian:testing ✅ install via Worker
fedora:latest ✅ makecache; install fails on #500 sha256 (pre-existing)
rockylinux:9 ✅ makecache; install fails on #500 sha256 (pre-existing)

Rocky 9's "Bad GPG signature" finding from #501 turned out to be a testing artifact (missing -y on dnf makecache → empty stdin on the key-import prompt → verification against an unimported key). With -y, the signature chain verifies and only the #500 sha256 mismatch remains. Posted a correction on that issue: #501 (comment)

#500's fix in #502 (gh release upload --clobber of the signed RPM to the Release) has not been exercised by CI yet — update-dnf-repo was skipped in the test tag's run because update-apt-repo failed at the push step on the 100MB cap. That step is the first thing this PR unblocks.

Pre-merge checklist (manual)

Do NOT merge until these are done:

  1. Add CNAME file to gh-pages root containing pkg.claude-desktop-debian.dev (via Settings → Pages → Custom domain, or direct git push to gh-pages).
  2. Wait for GitHub Pages cert provisioning. Typical ~1h. Edge cases up to 24h+ per the plan doc. Monitor Settings → Pages for the green cert indicator.
  3. Verify cert works: curl -I https://aaddrick.github.io/claude-desktop-debian/dists/stable/InRelease should return a 301 redirecting to pkg.claude-desktop-debian.dev.

Only then merge this PR. deploy-worker.yml will deploy the Worker to the new route.

Post-merge validation

# Production probe (this is what CI's strip gate uses):
curl -fsI https://pkg.claude-desktop-debian.dev/dists/stable/InRelease

# Re-run the failed v2.0.3 release jobs — simultaneously validates #500
# and lets v2.0.3+claude1.3883.0 reach apt/dnf users:
gh run rerun 24836419696 --failed --repo aaddrick/claude-desktop-debian

Rollback

If the production chain misbehaves:

  1. Remove the CNAME file from gh-pages (via Pages UI). aaddrick.github.io/claude-desktop-debian/ stops auto-301'ing. Existing sources.list URLs continue serving directly from Pages (pre-strip .deb history is still there for any version that was already pushed).
  2. Unbind the Worker route via Cloudflare dashboard as a fast disable (<1 min) if needed separately.

Not in scope

Closes nothing directly — this is Phase 4a-APT tooling; the .deb size problem (#493) will close when the first post-cutover release successfully pushes with .debs stripped.

Refs #493, #500, #501


Generated with Claude Code
Co-Authored-By: Claude Opus 4.7 [email protected]
85% AI / 15% Human
Claude: ran Phase 2 container re-validation, diagnosed #501 as testing artifact (posted correction comment), drafted wrangler flip + PR body
Human: approved sequencing, triggered the test tag that surfaced the remaining blocker

Phase 2 container validation passed against
pkg-staging.claude-desktop-debian.dev — APT (debian:stable,
ubuntu:24.04, debian:testing) and DNF (fedora:latest, rockylinux:9)
both install the current pool version via the Worker chain. The one
remaining failure is #500's sha256 mismatch on RPM download, and
PR #502's gh release upload --clobber fix runs on the next release
that reaches update-dnf-repo.

This flip binds the Worker to pkg.claude-desktop-debian.dev. Once
this is deployed, the strip step's liveness probe in update-apt-repo
and update-dnf-repo will start succeeding, stripping .debs/.rpms from
the local pool tree before push — the original #493 blocker.

Pre-merge checklist (manual, outside this PR):

1. Add CNAME file containing pkg.claude-desktop-debian.dev to the
   gh-pages branch root (via Pages settings UI or direct push).
2. Wait for GitHub Pages cert provisioning. Typical ~1h; verify in
   repo Settings > Pages that the green cert indicator shows.
3. Merge this PR. CI deploys the Worker to the new route via
   deploy-worker.yml.
4. Confirm production probe responds:
     curl -fsI https://pkg.claude-desktop-debian.dev/dists/stable/InRelease
5. Re-run the failed update-apt-repo + update-dnf-repo jobs from the
   v2.0.3+claude1.3883.0 run (gh run rerun 24836419696 --failed) —
   this simultaneously validates #500's fix and completes the v2.0.3
   release for apt/dnf users.

Rollback: remove the CNAME file from gh-pages, unbind the Worker
route via the Cloudflare dashboard. gh-pages .deb assets from the
pre-strip history still exist and serve directly via github.io.

Refs #493, #500

Co-authored-by: Claude <[email protected]>
@aaddrick aaddrick marked this pull request as ready for review April 23, 2026 14:07
@aaddrick aaddrick merged commit b9bc02d into main Apr 23, 2026
16 checks passed
@aaddrick aaddrick deleted the phase-4a-apt-production-route branch April 23, 2026 14:09
aaddrick added a commit that referenced this pull request Apr 23, 2026
…01 loop (#504)

Once the CNAME file is in place on gh-pages (Phase 4a-APT), GitHub
Pages auto-301s all aaddrick.github.io/claude-desktop-debian/* traffic
to pkg.claude-desktop-debian.dev/*. The Worker's origin fetch against
aaddrick.github.io gets 301'd by Pages, the 301 passes through to the
client, the client follows it back to pkg.<domain>, and the Worker
runs again — infinite loop.

Observed immediately after merging #503 and Pages finishing the CNAME
build:

  $ curl -I https://pkg.claude-desktop-debian.dev/dists/stable/InRelease
  HTTP/2 301
  location: http://pkg.claude-desktop-debian.dev/dists/stable/InRelease
  x-github-request-id: 3C94:286425:...
  x-served-by: cache-yyz4566-YYZ
  via: 1.1 varnish

(Scheme-downgrade to http is a separate Pages quirk when
 https_enforced=false, which is the case here because DNS points
 at Cloudflare, not Pages, so Pages can't provision a cert.)

raw.githubusercontent.com serves the same gh-pages branch content
without Pages' routing layer. All five metadata paths verified to
return 200:

  /dists/stable/InRelease
  /dists/stable/main/binary-amd64/Packages
  /KEY.gpg
  /rpm/x86_64/repodata/repomd.xml
  /rpm/x86_64/repodata/repomd.xml.asc

Also fixes the deploy-worker.yml post-deploy probe which still
hardcoded pkg-staging. That's what made #503's deploy show as
failed in the Actions UI even though the wrangler deploy itself
succeeded — route bound and Worker live, but the probe was
resolving a hostname wrangler had just removed.

Refs #493, #503

Co-authored-by: Claude <[email protected]>
aaddrick added a commit that referenced this pull request Apr 23, 2026
* fix(ci): smoke test allows http:// on Pages 301 hop

Phase 4a-APT's first rerun of update-apt-repo succeeded all the way
through strip + push (v2.0.3 metadata is live on gh-pages now), but
the smoke test failed at hop 0:

  Hop 0: 301 https://aaddrick.github.io/.../*.deb
         -> http://pkg.claude-desktop-debian.dev/.../*.deb
  Hop 0 mismatch: expected https://pkg..., got http://pkg...

Pages emits http:// in the Location header because https_enforced is
unsettable on the repo's Pages config: DNS for pkg.<domain> points at
Cloudflare (Worker custom_domain), so Pages can never pass domain
verification to provision its own cert. Cloudflare serves both schemes
for pkg.<domain>, so the http vs https in Pages' redirect is cosmetic
— the chain still terminates correctly.

Relax hop 0's regex in both smoke tests (update-apt-repo,
update-dnf-repo) and the heartbeat workflow to accept https?://.
Later hops stay https-only since GitHub's Release-asset redirects
are always HTTPS.

Failure was the tail-end of run 24836419696's rerun:
https://github.com/aaddrick/claude-desktop-debian/actions/runs/24836419696

Refs #493, #503

* chore: retrigger CI (previous trigger lost to GH flake)
aaddrick added a commit that referenced this pull request Apr 23, 2026
v2.0.4 rerun of update-apt-repo made it past hops 0 and 1 (the smoke
test scheme fix in #506 worked — Pages' http:// redirect no longer
trips the chain walker), but failed on hop 2:

  Hop 2: 302 .../releases/download/v2.0.4+claude1.3883.0/...deb
         -> https://release-assets.githubusercontent.com/...
  ::error::Hop 2 mismatch: expected https://objects\.githubusercontent\.com/,
           got https://release-assets.githubusercontent.com/...

GitHub migrated the Release asset CDN from objects.githubusercontent.com
to release-assets.githubusercontent.com (both have been serving in the
past; release-assets is the current canonical hostname). Accept either
hostname via alternation.

Verified against the actual v2.0.4 Release:
  $ curl -Is https://github.com/aaddrick/claude-desktop-debian/releases/download/v2.0.4+claude1.3883.0/claude-desktop_1.3883.0-2.0.4_amd64.deb \
    | grep -i location
  location: https://release-assets.githubusercontent.com/github-production-release-asset/...

Same fix in three sites:
- .github/workflows/ci.yml (update-apt-repo smoke test)
- .github/workflows/ci.yml (update-dnf-repo smoke test)
- .github/workflows/apt-repo-heartbeat.yml (daily heartbeat)

docs/worker-apt-plan.md has historical references to
objects.githubusercontent.com too; those can be updated in a follow-up
docs sweep — the architectural claim (binary bytes flow direct from
GitHub CDN, never through Cloudflare) is unchanged.

Refs #493, #503
aaddrick added a commit that referenced this pull request Apr 23, 2026
Phase 4a-APT cutover (#493, #503) moves binary distribution behind a
Cloudflare Worker at pkg.claude-desktop-debian.dev. The Worker serves
repo metadata directly and 302-redirects .deb/.rpm requests to GitHub
Release assets, which makes the >100 MB .deb push cap irrelevant.

GitHub Pages auto-301s legacy aaddrick.github.io/claude-desktop-debian
URLs to pkg.claude-desktop-debian.dev, but the redirect uses http://
(Pages has no cert for pkg.<domain> — DNS points at Cloudflare, so
Pages can never pass domain verification). apt refuses that scheme
downgrade as a security policy, so existing users' sources.list
silently breaks on the next `apt update`. DNF accepts the downgrade
and keeps working.

Changes:

- README.md: install snippets (APT + DNF) now point at
  pkg.claude-desktop-debian.dev directly. New users never touch the
  Pages redirect chain.
- README.md: add a "Migrating from the old aaddrick.github.io URL"
  section with sed one-liners for existing users + a short background
  paragraph explaining why the change was needed.
- .github/workflows/ci.yml: release-notes install snippets (APT + DNF,
  both branches) and the generated claude-desktop.repo file's baseurl
  and gpgkey all point at pkg.<domain>. Smoke-test chain walkers
  deliberately keep starting at github.io (they test the full 3-hop
  Pages→Worker→Releases chain for clients that do follow the
  downgrade, like curl-without-L and dnf).

Refs #493, #503
aaddrick added a commit that referenced this pull request Apr 23, 2026
The plan doc served its purpose through #494 (merge) → #498
(scaffolding) → #502 / #503 / #504 / #506 / #509 / #510 (cutover).
v2.0.5+claude1.3883.0 is the first release through the new pipeline,
verified end-to-end on five distros. #493 is closed.

Removes docs/worker-apt-plan.md and the two architecture-pointer
comments in worker/src/worker.js and worker/wrangler.toml that
referenced it. Both files now carry a short self-contained summary
of what the Worker does and why.

Also corrects worker.js's CDN-hostname reference from
objects.githubusercontent.com (the old name) to release-assets
(current, matches #509's regex fix).

Git history retains the full plan doc for anyone who needs the
design rationale; nothing is actually lost.
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