- 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.
66 lines
3.3 KiB
Markdown
66 lines
3.3 KiB
Markdown
# 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](https://github.com/googleapis/release-please-action)
|
||
in `release-type: go` mode parses [Conventional
|
||
Commits](https://www.conventionalcommits.org/) 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
|
||
|
||
- [release-please-action](https://github.com/googleapis/release-please-action)
|
||
- [GoReleaser v2 docs](https://goreleaser.com/customization/)
|
||
- [Conventional Commits 1.0.0](https://www.conventionalcommits.org/en/v1.0.0/)
|