feat(release): semantic-release on main + compiled binaries + install docs - #55
Merged
Merged
Conversation
…trix (#9) Replace the tag-triggered release flow (#44) with per-merge releases: every push to main runs the CI gate, cross-compiles ct as standalone bun binaries (darwin-arm64, darwin-x64, linux-x64), smoke-tests each one on its native OS/arch (--help plus a real ct plan against a fixture .config.ts, so jiti's runtime TS transpilation inside the compiled binary is actually exercised — not just --help), and only then runs semantic-release (pinned via npx, no new devDependencies) to compute the version, generate the changelog as GitHub Release notes, create the tag, and publish the release with the tarball + binaries attached. No manual tag push. Release stays private/GitHub-only: no npm publish plugin. Comment/label side effects on @semantic-release/github are disabled to keep the GITHUB_TOKEN permission footprint at contents:write only.
…#9) Point Install at the release binaries (no Node required) with the npm tarball as a fallback, and describe the new push-to-main release flow that replaces the old v* tag trigger.
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.
Summary
Closes #9.
Builds on the tag-triggered release flow from #44 (
.github/workflows/release.yml) — this PR replaces the tag-push trigger with the remaining scope from #9:mainvia semantic-release (.releaserc.json:@semantic-release/commit-analyzer+@semantic-release/release-notes-generator+@semantic-release/github, all pinned vianpxin CI rather than added as devDependencies). No manual tag push, no npm publish (private repo — GitHub Releases only). The GitHub Release's auto-generated notes double as the changelog;@semantic-release/github's comment/label side effects are disabled so the workflow only needscontents: write.bun build --compile, cross-compiled from a single Linux runner forbun-darwin-arm64,bun-darwin-x64, andbun-linux-x64(all pure-JS deps: commander, jiti, openapi-fetch, picocolors; Keychain access goes through thesecurityCLI, not a native module).macos-14for arm64,macos-13for x64,ubuntu-latestfor linux-x64) before the release job runs at all — see.github/scripts/smoke-test-binary.sh. Each binary runsct --helpandct plan --config tests/fixtures/sample.config.tswith a bogusCT_HOSTand no stored token. That's the deepest command that exercises jiti's runtime TS transpilation of a.config.ts(the actual risk ofbun build --compile) without touching the network: the fixture must load and evaluate successfully, and the command must fail specifically at theauthedSession()step ("Not logged in"on a clean runner, or the host-mismatch"Refusing to send the stored login token"if a credential happens to be present) — not at config load. A config-load failure is treated as a real bug and fails the job.curlthe platform binary from.../releases/latest/download/ct-<target>,chmod +x, move ontoPATH; npm tarball (ct-cli.tgz) kept as a Node-based fallback.Release pipeline shape
build(CI gate + compile 3 binaries + npm-pack tarball + INSTALL.md, uploaded as a workflow artifact) →smoke-darwin-arm64/smoke-darwin-x64/smoke-linux-x64(each downloads the artifact, runs the smoke script against its own binary) →release(needs all three smoke jobs; downloads the artifact, runsnpx semantic-release, which — only if there's a releasablefeat:/fix:/breaking-change commit since the last release — creates the tag, the GitHub Release, and attaches the tarball + binaries as assets).semantic-release publishes via the GitHub API using the default
GITHUB_TOKEN, so the tag/release it creates does not re-trigger thispush: branches: [main]workflow (GitHub doesn't firepushevents for activity performed with the default token) — no loop.Verified locally
npm run lint,npm run typecheck,npm test(369 passed / 4 skipped),npm run buildall clean, on top of latestmain(rebased in after two other PRs landed mid-task).python3 -m yaml) and every embeddedrun:block (including theINSTALL.mdheredoc) passesbash -n..releaserc.jsonis valid JSON.tsx(not a compiled bun binary — bun isn't installed on this machine, and I did not install global tooling per the task constraints):ct --helpsucceeds, thenct planagainst the fixture config withCT_HOSTset to a bogus host correctly fails at the auth layer (on this dev machine that's the host-mismatch branch, since a real credential for a different host is in the Keychain) — script exits 0."Config file not found"error, and the script correctly does not treat that as a pass (confirms the pass/fail logic actually discriminates config-load failures from auth failures, rather than just checking for "any error").actionlintandshellcheckare not installed on this machine and were not installed for this task (per the task's tooling constraint); YAML/bash were validated manually as above instead.Not verified (CI-only)
bun build --compileactually succeeds and produces a working binary — bun is not installed locally. This is exactly what thebuild+ threesmoke-*jobs exist to prove; if bundling misbehaves (e.g. jiti's dynamicimport()doesn't survive compilation), the smoke jobs will fail loudly and no release will be cut.semantic-releaseactually cuts a real tag/release end-to-end with these exact plugin versions/config against this repo's GitHub API permissions.bun-darwin-*targets from a Linux host (should work per Bun's documented cross-compile support, but unverified here).Test plan
main, confirm theReleaseworkflow runsbuild→ all threesmoke-*jobs →release, and that afeat:/fix:commit produces a new GitHub Release with a version bump, generated notes, and 4 attached assets (ct-cli.tgz,ct-darwin-arm64,ct-darwin-x64,ct-linux-x64, plusINSTALL.md).ct-darwin-arm64(or-x64) from the release on a clean Mac with no Node installed and confirmct --helpruns.chore:) onmainruns the pipeline but does not publish a release.