Branching And Release¶
Branch Model¶
stagingis the active integration branch- feature and bug-fix branches start from
staging - pull requests should go back into
staging mainis the stable branch for releases- the scheduled promotion is
staging -> main
CI Expectations¶
- pull requests into
stagingandmainrun formatting, vet, test, and build checks - pushes to
stagingandmainrun the same CI checks
Release Automation¶
When code is pushed to main:
- the next release tag is calculated in
vYYYY.MM.DDformat - release archives are built for macOS, Linux, and Windows
- release notes are generated from the commits since the previous tag
- release notes are grouped by area instead of one flat commit list
- breaking commits are surfaced as upgrade notes
- a compare link is added when the repository remote can be resolved to GitHub
- GitHub Release assets are published
- the npm package
@hunpeolabs/gigis published from this same repository - the release tag is mapped to npm package version
YYYY.M.Dfor registry compatibility
The release workflow is split into:
- metadata resolution
- release verification across Go, docs, and npm package staging
- npm publication
- npm registry verification with retry for first-visibility lag
- GitHub Release publication after npm succeeds
npm publication is now a release requirement. If neither trusted publishing nor a token fallback is configured, the release workflow fails during verification before it creates a GitHub Release.
npm publication supports two modes:
trustedsteady-state publish through GitHub Actions OIDC after the package already exists on npmtokenbootstrap or fallback publish through repository secretNPM_PUBLISH_TOKEN
The safer steady-state setup is:
- open npm package settings for
@hunpeolabs/gig - add a trusted publisher for GitHub Actions
- set owner
phamhungptithcm - set repository
gig - set workflow filename
release.yml - set environment name
npm-release - optionally require approvals on the GitHub environment
npm-release - set repository variable
NPM_TRUSTED_PUBLISHING=trueafter npm trusted publishing is configured and ready
The npm package scope and the GitHub repository owner are different here:
- npm package scope:
@hunpeolabs/gig - GitHub repository for the trusted publisher:
phamhungptithcm/gig
Bootstrap note:
- npm trusted publisher settings live on the package, so
@hunpeolabs/gigusually needs to exist first - for the first publish, set repository secret
NPM_PUBLISH_TOKENso the release workflow can bootstrap the package automatically from GitHub Actions NPM_PUBLISH_TOKENmust come from an npm identity that can publish to@hunpeolabs/gig- if the token path is used, prefer an npm automation token or a granular token with bypass 2FA enabled
- after the package exists, configure trusted publishing on npm, verify one GitHub Actions publish, then remove the token fallback if you no longer want it
- if you leave
NPM_PUBLISH_TOKENconfigured, the workflow can still use it as an emergency fallback when trusted publishing is not enabled
Recovery note:
- if a GitHub Release already exists but npm publication failed, do not push a no-op commit just to retry
- open the
Releaseworkflow in GitHub Actions and run it manually withrelease_tag=vYYYY.MM.DD - the workflow will re-run verification from the current
mainworkflow, skip GitHub Release creation if it already exists, and only retry the missing npm publish work for that release tag
Easiest Bootstrap Commands¶
If you want the shortest path with the least memory burden, use these commands from the repo root:
./scripts/npm-release.sh prepare
./scripts/npm-release.sh bootstrap
gh variable set NPM_TRUSTED_PUBLISHING --repo phamhungptithcm/gig --body true
If you prefer make:
make npm-release-prepare
make npm-release-bootstrap
What each command does:
prepare: open a searchable release-tag selector, stage the npm package, and runnpm pack --dry-runbootstrap: open the same selector, publish the first package version locally, configure npm trusted publishing, verify npm state, and print the exact next commandsverify: show the published version and trusted publisher configuration
If fzf is installed, the selector behaves like a searchable dropdown with type-to-filter.
If fzf is not installed, the script falls back to a search prompt and numbered list.
Important setup details:
- the workflow filename is case-sensitive and must match
release.ymlexactly - trusted publishing works on GitHub-hosted runners, which this workflow uses
- automatic provenance on npm requires a public package published from a public repository
- the first publish can now be done through GitHub Actions by setting repository secret
NPM_PUBLISH_TOKEN package.jsonrepository metadata must continue to matchhttps://github.com/phamhungptithcm/gig.git- after the first successful trusted publish, switch the npm package to
Require two-factor authentication and disallow tokens
After trusted publishing works, revoke old npm automation tokens and disallow token-based publishing for the package.
Release Note Standard¶
The release workflow uses ./scripts/release-notes.sh [previous-tag] <current-tag>.
The generated release notes should always follow the same shape:
Summarywith the release focus and change countsHighlightsgrouped into CLI and workflows, source-control-native access, packaging and release automation, docs, and maintenanceUpgrade Noteswhen a breaking commit is detectedFull Changelogwith a compare link when possible
To keep the output readable, commit subjects should follow Conventional Commits whenever possible:
- use scopes such as
cli,sourcecontrol,release, ordocs - keep the subject line short and user-visible
- reserve
docs,chore,build,ci, andtestfor non-product work so the generator can place them correctly - use
!only for real breaking changes because it is promoted intoUpgrade Notes
Branch Protection Follow-Up¶
After the workflow changes are merged and CI has produced at least one successful run on main and staging, sync the required checks:
./scripts/sync-required-checks.sh phamhungptithcm/gig
That script only updates branch protection when these checks already exist and are passing on the target branch:
gopackagingdocs
This avoids locking merges by requiring a check name before GitHub has seen it on the branch.
Docs Deployment¶
When docs inputs change on main:
- MkDocs builds the site
- GitHub Pages publishes the updated docs
Easiest First-Time User Flow¶
- install
gig - run
gig --help - run
gig version - run
gig inspect ABC-123 --path . - run
gig verify --ticket ABC-123 --from test --to main --path .
Suggested Weekly Team Flow¶
- developers branch from
staging - developers open pull requests back into
staging - QA and review happen on
staging - at release time, open a promotion pull request from
stagingtomain - merging to
mainpublishes the next release and updates docs if needed
Where gig Fits In That Flow¶
Use gig before the promotion step when you need to answer:
- what changed for this ticket?
- is
testbehinddev? - is
mainstill missing a follow-up fix? - does this ticket need manual review because of DB or config changes?