Repository navigation
fork: publish fork releases and sync them with upstream - #1
Merged
Merged
Conversation
The CLI's updates, server self-updates, SSH installs, the one-line installers and the desktop release links all read 3mdistal/t3code, so no fork build installs stock T3 over itself. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
t3 triage files public issues on pingdotgg/t3code, and Alice reports this fork's bugs privately. --option id=value sets model options on a new thread, so the sync's conflict thread can start at xhigh effort. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Passkey entitlements need a provisioning profile for upstream's App ID, so a signed build without one signs with the unrestricted entitlements instead, and an unsigned build is signed ad hoc. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3mdistal
force-pushed
the
fork/infra
branch
2 times, most recently
from
October 24, 2026 06:37
5fb22f2 to
4565520
Compare
Fork release publishes vX.Y.Z-alice.N with update manifests from every push to fork/main, after Fork CI passes on that commit. Fork CI and Fork Windows Tests are generated from upstream's workflows for GitHub-hosted runners. Every other upstream workflow keeps its jobs but has its triggers commented out, so only the fork's workflows can run here. scripts/fork/sync.ts rebases the stack onto each new upstream stable tag, resolves conflicts in upstream's workflows itself, refuses to push a stack where one could run, and starts one conflict thread when it can't finish. FORK.md is the brief. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Upstream's v0.1.2 fails its own Release Smoke check: a lockfile-only install of the workspace manifests stops on ERR_PNPM_UNUSED_PATCH. Upstream fixed it 35 minutes after the tag in 22840ab. This is that commit unchanged, so the next sync's rebase drops it as already applied. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The fork has nowhere to come from. Without this, a fork build would update itself from upstream's releases (and install stock T3 over the fork), the CLI and the one-line installers would download upstream's builds, and upstream's release workflow can't run on a fork at all: it needs Blacksmith runners, deploy secrets, and upstream's Apple App ID. Nothing keeps the fork on upstream's stable releases either.
Approach
Every push to
fork/mainpublishesvX.Y.Z-alice.N, whereX.Y.Zis the upstream stable tag the patch stack sits on. Upstream's build already treats any version without-nightlyor-previewas a production app on thelatestupdate channel, and electron-updater compares semver, so installed fork builds follow the fork's latest release with no updater patch. A test pins those assumptions so a sync fails loudly if upstream changes them.Releases reuse upstream's per-platform packaging (
release-desktop.yml) on GitHub-hosted runners, gated on Fork CI passing on the exact commit being published. Only the fork's own workflows can run: every other upstream workflow keeps its jobs, but its triggers are commented out. A sync script rebases the stack onto each new upstream stable tag, waits for CI, and promotes it; when it can't, it starts one conflict thread for Alice instead of guessing.What changed
CLI_RELEASE_REPOSITORY,DEFAULT_DESKTOP_RELEASE_REPOSITORY, and the two install scripts point at3mdistal/t3code. Upstream tests that pinned upstream URLs now expect the fork's.t3 triageis off. It files public issues onpingdotgg/t3code; Alice reports bugs privately.t3 thread start --option id=value, so the conflict thread can start at xhigh effort.apps/desktop/resources/entitlements.mac.plist; an unsigned build is signed ad hoc.release-desktop.ymlno longer requiresAPPLE_TEAM_IDorMACOS_PROVISIONING_PROFILE..github/workflows/fork-release.yml: version, Fork CI, JS bundle, macOS arm64 / Linux x64 / Windows x64 builds (Windows builds on Linux like upstream's and runs its checks onwindows-2025; Linux is needed because Windows embeds its CLI archive), then publish withlatest.yml,latest-mac.yml,latest-linux.yml, blockmaps, CLI archives andSHA256SUMS.scripts/fork/ci-workflows.tscomments out theon:block of every workflow exceptfork-ci,fork-release,fork-windows-testsandrelease-desktop, leavingworkflow_call, which nothing calls. The files stay because upstream's tests and knip read them: deleting them would have meant deleting three upstream tests and two scripts and patchingrelease-smoke.ts. A test fails CI if any upstream workflow could run.fork-ci.ymlandfork-windows-tests.ymlare generated from upstream'sci.ymlandwindows-tests.ymlby the same script (GitHub-hosted runners, longer timeouts, fork triggers). A test fails if the copies drift.scripts/fork/versions.tspicks the next version;scripts/fork/sync.tsruns the sync (run,push,promote,--dry-run). Both use only Node built-ins, so they run before any install.ERR_PNPM_UNUSED_PATCH, upstream run); upstream fixed it 35 minutes after the tag. The commit is upstream's unchanged (same patch-id), and the sync drops it once a release contains it.FORK.mdis the brief for the patch stack, releases, rollback, the sync, and the conflict rules.Safety and operations
sync.ts pushandpromoterefuse a commit where an upstream workflow could run. The sync now rebases onto the target tag itself, so stack commits upstream has since released, like the backport, drop out instead of conflicting.main, the other 1,800 branches and the 729v*tags that came with the fork keep upstream's live triggers, so they are never pushed. Upstream's newer stable tags never go to the fork; the release workflow fetches them from upstream.fork/main, so schedules and bot events read the inert copies. Switching before the merge would point them atfork/main's current tree, which is upstream's v0.1.2 withrelease.yml's half-hourly schedule live.v0.1.2-alice.1. Nothing installs it: the PC runs Nightly, which follows upstream's nightly feed.Verification
scripts/fork(23 tests, including scratch-repo rebases: upstream editing a trigger block and adding a workflow, a backport upstream released and then changed again, a non-workflow conflict, a workflow the rewrite can't handle),cliRelease(5),updateChannels.fork(1),desktopUpdate.logic(9), mobileenvironment-maintenance(7), and serverthread.fork,threadandtriagepass on Windows.notify-discord-release.test.ts,vercel-deployment-output.test.cjs,relay-state-output.test.cjs.vp run check:changed: format, lint, knip, graphql and typecheck pass.update.test.ts's PATH-launcher case, andbuild-desktop-artifact.test.ts's archive tests (taron Windows). Fork CI runs them on Linux.git ls-treeon the head commit: the only live triggers are Fork CI's (pull requests intofork/main,sync/**pushes, call, dispatch), Fork Release's (fork/mainpushes, dispatch), Fork Windows Tests' (dispatch) andrelease-desktop.yml's (call). Every other workflow's only trigger isworkflow_call.actionlintreports nothing on the four workflows that run. On the inert ones it reportsinputs.*references with no declared inputs, which can't matter since they never run; GitHub raised no workflow-file errors on the push.0.1.3-alice.1to-alice.2to0.1.4-alice.1), and the conflict rehearsal.Review focus
fork-release.yml's gate: publish needs version, Fork CI, and every desktop build; a re-run on a released commit does nothing.sync.ts promote: it movesfork/mainwith--force-with-leaseagainst the commit the sync started from, and refuses unless Fork CI passed on the sync branch.isInertWorkflowinci-workflows.ts: it is the check that stands between upstream's triggers and the fork.Done by Claude Opus 5.5 in Claude Code, running in T3 Code.
🤖 Generated with Claude Code