Releasing¶
A release publishes the codesynapse CLI (bare binaries on GitHub and a formula in the Homebrew tap astrona-io/homebrew-tap) and the server stack (container images and the Helm chart, see Server release).
Cut a release¶
Tag main and push the tag:
git switch main && git pull
git tag -a v0.3.0 -m "v0.3.0"
git push origin v0.3.0
.github/workflows/release.yml then:
- Builds
codesynapse-{darwin,linux}-{amd64,arm64}withCGO_ENABLED=0and stamps the tag intocodesynapse --version. Each binary gets a signed build provenance attestation. - Creates the GitHub release with the four binaries, a
SHA256SUMSfile and generated release notes. - Renders
Formula/codesynapse.rbwith.github/scripts/homebrew-formula.shand pushes it to the tap ascodesynapse X.Y.Z. - Installs the formula from the tap on macOS and Ubuntu runners and checks the version matches the tag.
- Builds the tagged documentation with MkDocs and publishes it to the documentation site on GitHub Pages.
A tag with a -, such as v0.3.0-rc1, is a pre-release. It gets a GitHub release, never becomes "latest", and doesn't touch the tap.
The Release workflow doesn't mark a final release "latest" itself. The Images workflow does that once the published stack passed its install test (below).
Documentation site¶
The shareable documentation URL is https://codesynapse.astrona.io/. Each stable release replaces the site with documentation built from that release's tag. Pre-releases do not replace the published documentation. This is a single current-release site, not a version archive.
The Release workflow calls .github/workflows/docs.yml directly after creating the release: releases created using GITHUB_TOKEN do not trigger a separate release-event workflow. The documentation workflow also handles stable releases published manually, and supports Actions → Documentation → Run workflow for the initial publication or a retry. Select the intended release tag when retrying; manually choosing another ref publishes that ref's documentation. Documentation pull requests build with --strict but cannot deploy.
For initial repository setup, enable Settings → Pages → Source → GitHub Actions. The github-pages environment must allow stable release tags and any ref deliberately used for a manual publication. Deployment uses pages: write and id-token: write; it does not require a long-lived deployment token. Private repositories do not deploy. The deployment job records the published URL in its environment.
Set the Pages custom domain to codesynapse.astrona.io and its DNS CNAME to astrona-io.github.io (without the repository path). docs/CNAME is copied into the generated site, and MkDocs uses the custom domain for canonical links. Once GitHub has verified DNS and issued the certificate, enable Enforce HTTPS in Pages settings. DNS is managed separately from the release workflow.
Validate documentation locally with just docs-build. A failed documentation build leaves the existing site in place; retry the failed workflow after fixing the issue. Documentation publishing is independent of the container/chart installation check that controls the release's latest status.
Server release¶
The same tag runs .github/workflows/images.yml. It refuses a tag that isn't vX.Y.Z or vX.Y.Z-rcN on a commit on main (.github/scripts/release-tag.sh), then:
- Images: builds
codesynapse-{api,worker,mcp,web}for amd64 and arm64, pushes them as:X.Y.Zand:X.Y(an RC only as:X.Y.Z-rcN), with SBOM and provenance, and signs them with cosign (keyless, GitHub OIDC). - Chart: packages
deploy/helm/codesynapsewith chart and app versionX.Y.Z, pushes it tooci://ghcr.io/astrona-io/charts/codesynapseand signs it. The images it deploys are written into itsartifacthub.io/imagesannotation (an RC is also markedartifacthub.io/prerelease), anddeploy/helm/artifacthub-repo.ymlis pushed as theartifacthub.iotag. Artifact Hub checks the repository about every 30 minutes and lists new versions on its own; therepositoryIDin that file makes astrona.io its verified publisher. The GHCR package must be public for Artifact Hub to read it. - Verify: checks the signatures of the chart and the four images, creates a throwaway kind cluster, installs the published chart with the published images (
just chart-install-published) and runshelm test. - Latest: for a final release only, moves the images'
:latesttag to the verified manifests and marks the GitHub release latest.
A failure in steps 1 to 3 leaves the previous release as latest. Fix forward with a new tag; don't move a published tag.
Try a published version on your own kind cluster (just kind-up first). For a private package, create a docker-registry Secret in the codesynapse namespace and pass its name:
just chart-install-published 0.3.0 # public packages
just chart-install-published 0.3.0 ghcr # with the pull secret ghcr
just chart-test
Upgrading an installation: Upgrading.
Requirements¶
- Public repository. Homebrew can't download private release assets, so steps 3 and 4 are skipped while the repository is private. Tags still produce GitHub releases.
HOMEBREW_TAP_TOKENsecret on this repository: a fine-grained PAT with Contents read/write onastrona-io/homebrew-taponly. astrona-cli uses the same kind of token for its formula.
Checking a formula change¶
.github/workflows/homebrew.yml runs on pull requests that touch the formula scripts, the release workflow, cmd/codesynapse or go.mod. It runs .github/scripts/test-homebrew-formula.sh on macOS and Linux. The script renders the formula for a fake v0.0.1, runs brew style and brew audit --strict, then installs a keg-only copy built from the checkout and runs brew test. Run it locally the same way; it cleans up after itself.
Don't edit Formula/codesynapse.rb in the tap by hand. The next release overwrites it.
Verifying a download¶
gh release download v0.3.0 -R astrona-io/codesynapse -p 'codesynapse-darwin-arm64' -p SHA256SUMS
shasum -a 256 -c SHA256SUMS --ignore-missing
gh attestation verify codesynapse-darwin-arm64 -R astrona-io/codesynapse