Releases are cut by pushing a version tag. GitHub Actions
(.github/workflows/release.yml) then runs
GoReleaser with the config in
.goreleaser.yaml, which builds the artifacts and publishes a GitHub
Release with a changelog generated from the commit log.
-
Make sure the Test workflow is green on
main. -
Run the release script, which creates an SSH-signed annotated tag after checking that the tag doesn't already exist on origin (a tag that exists only locally is replaced). It requires git's
user.signingkeyto be set to your SSH public key../tag.sh v0.1.0
-
Push the tag as the script instructs:
git push origin v0.1.0
-
Watch the Release workflow in the Actions tab. When it finishes, the release with all artifacts appears on the Releases page.
Each release contains:
- Linux static binaries (tar.gz) for amd64, arm64, and armv7
- Debian (.deb) and RPM (.rpm) packages for the same architectures
- Windows binaries (zip) for amd64 and arm64
checksums.txtwith SHA-256 checksums of the above
Each release also pushes container images (amd64 and arm64) to
ghcr.io/tailscale/tailcat, tagged
both vX.Y.Z and latest. The image is the static binary in a
distroless base
image; see Dockerfile.goreleaser.
The binary version is embedded at build time via -ldflags -X main.version=...; tailcat version prints it. Builds made with
go install github.com/tailscale/tailcat/cmd/tailcat@vX.Y.Z instead
report the module version from the Go build info.
To build everything without tagging or publishing, install GoReleaser and run:
goreleaser release --snapshot --cleanThe artifacts land in dist/ (which is gitignored). In snapshot mode
the container images are built into the local Docker daemon as
separate per-platform tags rather than a multi-arch manifest, and
nothing is pushed. Building them requires a buildx builder with the
docker-container driver (docker buildx create --use).