Releases
teemtape ships releases through a two-phase, PR-based flow so that main can
stay a protected, pull-request-only branch. No bot ever pushes a commit directly
to main.
Why two phases?
Section titled “Why two phases?”Branch protection applies to branches (refs/heads/*) but not to tags
(refs/tags/*) or GitHub Releases. So the release is split:
- Prepare — bump the version and update
CHANGELOG.mdon a branch, then open a pull request. The version bump lands onmainonly by merging that PR. - Tag & release — once the PR is merged, tag the merge commit, cut the GitHub
release, and publish to npm. Tagging is allowed even with
mainlocked down.
Actions ▸ Prepare release ──▶ opens "chore(release): vX.Y.Z" PR │ (review version bump + CHANGELOG) ▼ merge PR to main │ ▼ tag-release.yml ──▶ tag vX.Y.Z ─▶ GitHub release ─▶ npm publishPhase 1 — Prepare release (manual)
Section titled “Phase 1 — Prepare release (manual)”Workflow: .github/workflows/release.yml. Trigger it from Actions → Prepare
release → Run workflow.
Inputs:
release_type:patch(default),minor, ormajor.version: an explicit version (e.g.1.2.3) that overridesrelease_type.dry_run: bump, build, andnpm publish --dry-runwithout opening a PR.
It computes the next version, writes it to all package.json files and
rewrites internal @teemtape/* dependency ranges, builds and tests the
publishable packages, generates a Keep a Changelog-style entry from merged PRs,
and opens (or updates) a chore(release): v<version> PR against main.
Phase 2 — Tag and release (on merge)
Section titled “Phase 2 — Tag and release (on merge)”Workflow: .github/workflows/tag-release.yml. Triggered by a push to main that
changes packages/cli/package.json (i.e. the release PR merging). Keyed off the
@teemtape/cli version: it cuts the release only if there’s no v<version> tag
yet — so ordinary merges don’t trigger one.
It detects the new version, builds and tests the publishable packages, creates and
pushes the annotated tag v<version>, cuts the GitHub release (notes from the
matching CHANGELOG.md section), and publishes @teemtape/api-client and
@teemtape/cli to npm with provenance. packages/mock-server and workers/* are
intentionally not published. The publish step is idempotent.
Human approval gates
Section titled “Human approval gates”Nothing ships without a human in the loop, and you can layer two gates:
- Release PR review. Nothing is tagged, released, or published until someone
merges the
chore(release): v<version>PR — the merge is the approval. To require an explicit reviewer, add Require a pull request before merging → Require approvals to themainruleset. - Pre-publish approval.
tag-release.ymlruns in thereleaseenvironment. Configure Settings → Environments → release → Required reviewers and the job pauses after merge until an approver clicks Approve. With no reviewers, the environment is inert and the job runs straight through.
Requirements
Section titled “Requirements”NPM_PACKAGE_TOKEN— an npm automation token with publish access to the@teemtapescope.contents: write+id-token: writepermissions (already configured) for pushing the tag, creating the release, and npm provenance.- For Phase 1 to open the PR with the built-in
GITHUB_TOKEN, enable Settings → Actions → General → Allow GitHub Actions to create and approve pull requests. Alternatively set aRELEASE_TOKENsecret (a PAT withcontents+pull-requestswrite); both workflows prefer it when present.
Manual version helper
Section titled “Manual version helper”scripts/version.mjs can be run locally:
node scripts/version.mjs current # print the current versionnode scripts/version.mjs next minor # print the next version for a bump typenode scripts/version.mjs set 1.2.3 # write 1.2.3 across all package.json filesCutting a release by hand
Section titled “Cutting a release by hand”If you ever need to bypass the workflows, the same protected-branch-friendly shape works locally — open a version-bump PR, merge it, then tag and release:
git checkout main && git pullgit tag -a v0.1.1 -m "Release 0.1.1"git push origin v0.1.1 # allowed: tags aren't branch-protectedgh release create v0.1.1 --target main --generate-notesRecommendation
Section titled “Recommendation”Use the built-in two-phase flow: run Prepare release to open the release PR,
review the version bump and CHANGELOG.md entry, then merge to automatically tag,
publish the GitHub release, and push the npm packages — all while keeping main
protected.