Skip to content

Releasing

engram releases are driven by release-please and GoReleaser, wired in .github/workflows/release.yaml. A single vX.Y.Z tag versions the binary, the multi-arch image, the OCI Helm chart, and the Claude plugin together.

  1. Every push to main runs the release workflow. release-please maintains an always-open release PR that bumps CHANGELOG.md, charts/engram/Chart.yaml (version + appVersion), and skill/engram/.claude-plugin/plugin.json ($.version) from the Conventional Commits since the last release.
  2. Merging the release PR is the release. release-please cuts the bare vX.Y.Z tag and GitHub Release (with the changelog body).
  3. In the same workflow run (gated on release_created), GoReleaser builds the binary — injecting main.version via -ldflags — and the multi-arch image, uploads them to the GitHub Release, then task chart:push packages and pushes the OCI Helm chart to oci://ghcr.io/seanb4t/charts.

Merging the release PR is the only required human action.

ArtifactHow
BinaryGoReleaser; version injected via -ldflags into main.version
Multi-arch container imageGoReleaser; pushed to GHCR
OCI Helm charttask chart:push; pushed to oci://ghcr.io/seanb4t/charts
Claude pluginskill/engram/.claude-plugin/plugin.json $.version — synced by release-please

The docs site is not part of the release process. It is a separate Astro/Starlight application in docs-site/ that deploys continuously from main via Cloudflare Workers Static Assets. release-please’s package set covers the single Go module at the repo root (.); docs-site/ is outside it by construction and has no release tag, no CHANGELOG entry, and no version number.

The release workflow uses a GitHub App token to open the release PR, cut the tag, and create the GitHub Release — so writes are attributable and can bypass the protected-main ruleset. Configure:

  1. A GitHub App with Contents: write and Pull requests: write on this repo, installed on the repo.
  2. Two repo secrets: RELEASE_APP (the App ID) and RELEASE_APP_PRIVATE_KEY.
  3. The App named as a bypass actor on the main branch ruleset.

The default GITHUB_TOKEN keeps packages: write only — it pushes the image and OCI chart to GHCR, nothing else.

To force a particular version, land a commit on main whose body carries a Release-As: footer:

chore(release): cut 0.5.0
Release-As: 0.5.0

release-please re-cuts the open release PR at that version. Keep the footer in the squashed commit body so it survives squash-merge.

  • task release:checkgoreleaser check (config validity).
  • task release:snapshot — local goreleaser dry build (no publish).
  • task chart:linthelm lint + helm template.