CI/CD & SBOM
Every check CI runs is a Makefile target, so it reproduces locally. Releases are driven by GoReleaser — see ADR 0008 for the rationale.
Supply-chain hardening
All GitHub Actions (first- and third-party) are pinned to full commit SHAs
with a # vX comment, so a moved or compromised tag cannot silently change what
runs. Bump them like dependencies (e.g. Dependabot/Renovate keyed on the comment).
The semgrep/semgrep scanner container is intentionally left on a rolling tag so
it runs the latest engine and rules.
CI (.github/workflows/ci.yml)
Runs on push to main and on pull requests:
- quality —
make ci:gofmtcheck,go vet,golangci-lint,go test -racewith coverage, andgovulncheck. Coverage is uploaded as an artifact. - sbom —
goreleaser release --snapshot(no publish/sign/image): produces the same CycloneDX SBOMs as a real release and uploadsdist/*.cdx.json. - semgrep — a static security scan (
semgrep scan --config auto --error).
make tools # install pinned golangci-lint, govulncheck
make ci # the same gate CI runs
make sbom # CycloneDX SBOMs in dist/ (needs goreleaser + syft)
Release (.github/workflows/release.yml)
Runs on v* tags as a single GoReleaser job that produces:
- Binaries —
linux/{amd64,arm64}anddarwin/{amd64,arm64}.tar.gzarchives pluschecksums.txt, attached to a GitHub Release. - CycloneDX SBOM — one
*.cdx.jsonper archive (syft). - Container image — multi-arch
ghcr.io/fjacquet/pstore_exporterbuilt with buildx, carrying SBOM and provenance attestations. - Signatures — keyless cosign signature of
checksums.txt(checksums.txt.sigstore.json), via GitHub OIDC. - Homebrew cask — published to
fjacquet/homebrew-tap.
git tag v0.1.0 && git push origin v0.1.0 # triggers the release
make release-snapshot # local dry-run, no publish/sign/push
Required secrets
GITHUB_TOKEN— automatic; creates the Release and pushes the GHCR image.HOMEBREW_TAP_GITHUB_TOKEN— a PAT withcontents:writeonfjacquet/homebrew-tap(the default token cannot push to another repo).
SBOM
GoReleaser is the single SBOM source (syft):
- Release SBOM — a CycloneDX
*.cdx.jsonper archive, attached to the release. - Image SBOM —
dockers_v2(sbom: true) attaches an SBOM and provenance attestation to the pushed container image.
Verify a downloaded release:
cosign verify-blob --bundle checksums.txt.sigstore.json checksums.txt # signature
sha256sum -c checksums.txt # integrity
Versioning
The build version is injected via -ldflags "-X main.version={{ .Version }}",
derived by GoReleaser from the git tag. Check it with:
Documentation
This site is built with MkDocs Material and deployed to GitHub Pages by
.github/workflows/docs.yml on every push to main.