Skip to content

ci: add goreleaser-driven release pipeline - #4

Open
kpeluso wants to merge 1 commit into
brynbellomy:mainfrom
kpeluso:feat/1-release-pipeline
Open

ci: add goreleaser-driven release pipeline#4
kpeluso wants to merge 1 commit into
brynbellomy:mainfrom
kpeluso:feat/1-release-pipeline

Conversation

@kpeluso

@kpeluso kpeluso commented May 28, 2026

Copy link
Copy Markdown
Contributor

Symptom

Downstream integrators installing veto on EC2 / CI hosts have to clone
the source repo and run make install (which gates on go test -race).
That adds 30–90s of cold-boot latency to every install and requires Go,
gcc, make, and build-essential to be pre-installed on the host. The
releases page on GitHub is empty — there is no curl-installable binary
for an integrator to fetch.

Implementation

Adds a goreleaser-driven release pipeline:

  • .goreleaser.yaml (v2 schema). Pure-Go builds (CGO_ENABLED=0)
    for {linux,darwin} x {amd64,arm64}. -trimpath, -s -w, plus
    -X main.{version,commit,buildDate}=… ldflags that become meaningful
    the moment a separate PR (--version flag) lands those vars in
    cmd/veto/main.go (Go's linker silently ignores -X against
    undefined symbols until then). Tarball archives named
    veto_<ver>_<os>_<arch>.tar.gz ship the binary plus README.md.
    checksums.txt (SHA256) sits alongside.
    go generate ./internal/interposer/gen/... runs in the before-hook
    so pm_names.h is in sync with the canonical Go PM list at release
    time (matters for a separate pending PR that go:embeds
    veto_interpose.c).
  • .github/workflows/release.yml. Single ubuntu-latest runner, fires
    on v*.*.* tag pushes. actions/checkout@v4 with
    fetch-depth: 0 (goreleaser needs full history), actions/setup-go@v5
    pinned to Go 1.26.2 with module cache, then
    goreleaser/goreleaser-action@v6 running release --clean.
    permissions: contents: write lets the default GITHUB_TOKEN
    upload release assets.
  • README updates the Quickstart to lead with a curl-tar install of the
    latest release (with jq + uname-based OS/arch detection) and
    documents make install as a "From source" fallback under
    "Installation Details".

CGO stays disabled because the C interposer is not cgo-linked into
veto; pending embed work go:embeds veto_interpose.c and builds it
at install time on the user's host. The release workflow does not need
to ship per-arch .so / .dylib files.

Verification

Smoke-tested locally with goreleaser 2.16.0 on darwin/arm64:

  • goreleaser check validates the config cleanly.
  • goreleaser release --snapshot --clean --skip=publish builds all
    four targets and emits four tarballs plus checksums.txt in 9s.
  • tar -tzf dist/veto_0.0.1-snapshot_linux_amd64.tar.gz lists
    README.md and veto — the expected payload.

Activation notes

This workflow does nothing until the maintainer pushes a v*.*.*
tag. The first release is a manual step on the maintainer's side:

git tag v0.1.0
git push origin v0.1.0

The push triggers release.yml, which cross-compiles all four targets,
uploads the tarballs + checksums.txt, and creates the GitHub release.
Subsequent releases need only another tag push.

Out of scope

  • No generic CI workflow for non-release pushes.
  • No CHANGELOG file.
  • No LICENSE file (LICENSE* glob intentionally dropped from the
    archive files: list — currently only README.md is included).
  • No artifact signing (cosign / GPG). Hardening for a later pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant