Files
go-config/docs/asr/ASR-0009-ci-cd-and-automated-semver.md
T
eSlider 0ae52ef72d docs: enhance release flow documentation and add version command to CLI
- Updated AGENTS.md and README.md to clarify the automated release process using release-please and GoReleaser.
- Added a version command to the envc CLI to display build metadata.
- Included CI/CD details in README for better understanding of testing and release automation.
2026-05-02 20:00:14 +01:00

3.3 KiB
Raw Blame History

ASR-0009: CI/CD pipeline and automated semantic versioning

Context

ASR-0008 only covered GitHub presentation and the initial manual tag of v0.1.0. The project needs continuous verification on every PR and a release flow that does not require humans to bump version strings. The source tree must stay free of version literals (the CHANGELOG aside) so that go install …@latest and GoReleaser artefacts agree on a single source of truth: git tags.

Decision

  1. Test pipeline (.github/workflows/test.yml): matrix of Go 1.22, 1.23, and stable on ubuntu-latest plus one stable run on macOS and Windows, with go test -race -shuffle=on -count=1 -coverprofile=coverage.out. Coverage is uploaded to Codecov from the Linux stable leg only. go mod tidy is enforced via git diff --exit-code.
  2. Lint pipeline (.github/workflows/lint.yml): go vet plus golangci-lint@v6 using the repo's existing .golangci.yml.
  3. Automated SemVer (.github/workflows/release-please.yml + release-please-config.json + .release-please-manifest.json): Google's release-please-action in release-type: go mode parses Conventional Commits since the previous tag and opens a "chore: release vX.Y.Z" PR that edits CHANGELOG.md and the manifest only. Merging the PR creates the git tag. The manifest is seeded with the current 0.2.0 so history is continuous.
  4. Release pipeline (.github/workflows/release.yml + .goreleaser.yml): on push: tags: ["v*"], GoReleaser v2 cross-compiles cmd/envc for linux/darwin/windows × amd64/arm64 (no windows/arm64), stamps -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} into the binary, produces tar.gz / zip archives plus checksums.txt, and attaches them to a GitHub Release whose body is generated from commit groups (feat, fix, perf, …).
  5. No version literals in Go code. cmd/envc/main.go defines var version = "dev" (and commit, date), overridable only at link time. envc version prints whatever the release build injected; local go install builds report dev.
  6. Dependency hygiene (.github/dependabot.yml): weekly gomod and github-actions updates, grouped for minor/patch, with conventional chore(deps) / ci(actions) commit prefixes so release-please classifies them correctly.

Consequences

  • Contributors must use Conventional Commits; otherwise release-please will not bump the version. chore: / docs: / ci: commits produce no release.
  • Breaking changes require feat!: or a BREAKING CHANGE: footer, which release-please maps to a major bump (subject to bump-minor-pre-major: true while the module is pre-1.0).
  • Re-tagging a release manually is discouraged — the tag is the contract that triggers GoReleaser.
  • Codecov token (CODECOV_TOKEN) and branch protection enforcing the Tests and Lint checks must be configured in the GitHub repository settings (operational, not code).

Status

Accepted — 2026-05-02.

References