Spec: phpboyscout/cicd v0.9 — Go track¶
- Repository:
gitlab.com/phpboyscout/cicd - Released as:
v0.9.0(minor — four additive components; no change to existing components or the v0.8 preset). - Driver: every project that will be derived from
go-tool-basecarries ~120 lines of identical lint / test / security / release jobs. Extracting once means a new Go project's.gitlab-ci.ymlbecomes ~30 lines ofinclude:blocks. Sibling to the Tofu split (tofu-lint/tofu-security/tofu-validate/tofu-module-publish) — same shape, same conventions, same Renovate-tracked component pins.
Decisions¶
D1 — Four components, mirroring the Tofu split¶
Rather than one monolithic "go-ci" component, the Go track is split by concern so consumers can opt out per pipeline stage:
| Component | Stage | Job(s) | Purpose |
|---|---|---|---|
go-lint |
lint |
golangci-lint |
golangci-lint over the project's packages |
go-test |
test |
go-test (+ optional go-test-e2e) |
go test -race -coverprofile with the standard coverage-badge regex; opt-in e2e job under an env-var build flag |
go-security |
security |
govulncheck, trivy, gitleaks, osv-scanner, analyze (semgrep) |
Five MR-time vulnerability / secret / static-analysis scanners |
goreleaser |
release |
goreleaser |
Tag-gated goreleaser release --clean |
Each component is the minimal unit a consumer can include in
isolation — a docs-only Go repo can take go-lint + go-test and
skip go-security + goreleaser entirely.
D2 — MR-only by default, overridable via inputs.if¶
All four gate components (go-lint, go-test, go-security) default
to running only on merge-request pipelines:
This matches go-tool-base's current .mr-only anchor. Consumers
override the input to widen (e.g. also run on tags) or narrow (e.g.
only on changed paths). Component interpolation passes runtime $VAR
references through unchanged.
goreleaser instead takes a tag_pattern input (RE2, default
^v[0-9]+\.[0-9]+\.[0-9]+$) — same shape as tofu-apply's
tag_pattern (v0.3.1) and tofu-module-publish's (v0.7.0).
D3 — enable_e2e as opt-in boolean with when: never on the disabled path¶
Most projects that derive from go-tool-base won't have a separate
e2e suite. Rather than force every consumer to add a rules: [{when:
never}] override, go-test exposes enable_e2e (default false):
The first rule (enable_e2e != "true") interpolates at include time
to either "true" != "true" (matches → when: never) or
"false" != "true" (no match → falls through to the MR-only rule).
Compared to a single && rule, this keeps the disabled path from
generating a skipped-job entry in the pipeline UI.
D4 — goreleaser defaults GOTOOLCHAIN=local to dodge sum.golang.org¶
The goreleaser image ships a Go toolchain that already satisfies
common go.mod toolchain directives. Setting GOTOOLCHAIN=local
stops the runner from attempting an inline toolchain download from
sum.golang.org mid-release — a transient IPv6 routing issue on
shared runners broke a prior go-tool-base v0.5.0 release at exactly
this point. Override to auto only if your project's go.mod
explicitly needs a newer toolchain.
GIT_DEPTH: "0" is hard-coded: goreleaser walks the full commit
history to derive changelogs and snapshot metadata.
D5 — Tool-version pins per scanner, not a unified image¶
go-security exposes a separate *_image input per scanner
(govulncheck via golang:X-bookworm, trivy, gitleaks, osv-scanner,
semgrep). The Renovate preset's custom manager auto-bumps each pin
independently, mirroring how tofu-security already handles its tool
suite. A future "phpboyscout-go-tools" multi-tool image could collapse
this to one input — out of scope for v0.9.
Consumers (post-release)¶
| Project | Inline jobs replaced | Components consumed |
|---|---|---|
go-tool-base |
lint, tests, e2e-bdd-tests, govulncheck, trivy, gitleaks, osv-scanner, analyze, goreleaser |
all four (with enable_e2e: true) |
future projects derived from go-tool-base |
(nothing inline yet) | inherit the full stack at fork time |
Renovate (v0.8) already tracks phpboyscout/cicd component pins, so a
new v0.9.0 surfaces as MRs in every consumer that extends the preset.
Follow-up¶
- Adopt across consumers in one migration MR per repo (task #49 already covers Renovate; add Go-track adoption to its scope or a sibling task once v0.10 (Rust track) is also out — adopting all at once reduces churn).
- Future component: a
go-toolsimage (single image bundling govulncheck + trivy + gitleaks + osv-scanner + semgrep + golangci-lint - go) so
go-lintandgo-securityjobs avoid pulling 5 distinct images per pipeline. Sibling toinfra-toolsfor the Tofu side.