Summary
The release workflow ships a single linux/amd64 binary with no integrity verification, no container image, and a hand-maintained build invocation that duplicates build.sh. This limits adoption and creates drift risk.
Concretely:
1. Single platform
.github/workflows/release.yml:90-110 builds only linux/amd64:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build ...
Modern Go projects ship at minimum:
linux/amd64
linux/arm64 (ARM-based EC2/GCE, Apple Silicon Linux VMs, Raspberry Pi)
darwin/arm64 + darwin/amd64
windows/amd64
Users on anything else have to build from source.
2. No artifact integrity
The release uploads a bare connectivity binary — no SHA256SUMS, no signature, no SBOM. A user has no way to verify a downloaded binary matches what CI built. GitHub's TLS protects in transit, but doesn't prove anything about the build artifact's lineage.
3. No container image
connectivity monitor is almost always deployed as a sidecar/daemon. Every consumer currently has to write their own Dockerfile.
4. Build configuration is duplicated
build.sh and release.yml independently define the same ldflags pattern:
build.sh:
go build -ldflags " \
-X 'main.GitTag=$GIT_TAG' \
-X 'main.GitCommit=$GIT_COMMIT' \
-X 'main.GoVersion=$GO_VERSION' \
..."
release.yml:
go build -ldflags="-s -w \
-X 'main.GitTag=${TAG}' \
-X 'main.GitCommit=${HEAD_SHA}' \
-X 'main.GoVersion=${GO_VERSION}' \
..."
Differences (intentional?): -s -w, -trimpath, BuildTainted value, timestamp format. When the version metadata schema changes, both have to change in lockstep — drift is inevitable.
Suggested fixes (pick what fits, in order of value)
Multi-arch
Either a matrix:
strategy:
matrix:
include:
- { goos: linux, goarch: amd64 }
- { goos: linux, goarch: arm64 }
- { goos: darwin, goarch: amd64 }
- { goos: darwin, goarch: arm64 }
- { goos: windows, goarch: amd64, ext: .exe }
Or switch to goreleaser, which handles multi-arch, archives, checksums, SBOMs, container images, and Homebrew taps from a single .goreleaser.yaml. For this project's scope, goreleaser would replace build.sh AND release.yml and remove the duplication entirely.
Integrity
If using a matrix:
- name: Checksums
run: sha256sum connectivity-* > SHA256SUMS
- name: Upload to release
run: gh release upload "${TAG}" connectivity-* SHA256SUMS
Consider cosign sign-blob / Sigstore for keyless signing on top.
Container image
A trivial multi-arch image (alongside the release):
FROM scratch
COPY connectivity /connectivity
ENTRYPOINT ["/connectivity"]
Publish to GHCR (ghcr.io/dolph/connectivity:${TAG}) using docker/build-push-action.
Deduplicate build config
Extract version-ldflags into a single source of truth — a make ldflags target, a version.sh helper, or just commit to goreleaser which centralizes it.
Impact
A maintainer-grade release pipeline catches its own regressions (failed cross-compile, broken ldflags) before users do, and removes future "user can't install on Mac" / "no checksums" / "no image" requests.
Relates to #13 (toolchain), #22 (deps).
Summary
The release workflow ships a single
linux/amd64binary with no integrity verification, no container image, and a hand-maintained build invocation that duplicatesbuild.sh. This limits adoption and creates drift risk.Concretely:
1. Single platform
.github/workflows/release.yml:90-110builds onlylinux/amd64:CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build ...Modern Go projects ship at minimum:
linux/amd64linux/arm64(ARM-based EC2/GCE, Apple Silicon Linux VMs, Raspberry Pi)darwin/arm64+darwin/amd64windows/amd64Users on anything else have to build from source.
2. No artifact integrity
The release uploads a bare
connectivitybinary — noSHA256SUMS, no signature, no SBOM. A user has no way to verify a downloaded binary matches what CI built. GitHub's TLS protects in transit, but doesn't prove anything about the build artifact's lineage.3. No container image
connectivity monitoris almost always deployed as a sidecar/daemon. Every consumer currently has to write their own Dockerfile.4. Build configuration is duplicated
build.shandrelease.ymlindependently define the same ldflags pattern:build.sh:release.yml:Differences (intentional?):
-s -w,-trimpath,BuildTaintedvalue, timestamp format. When the version metadata schema changes, both have to change in lockstep — drift is inevitable.Suggested fixes (pick what fits, in order of value)
Multi-arch
Either a matrix:
Or switch to
goreleaser, which handles multi-arch, archives, checksums, SBOMs, container images, and Homebrew taps from a single.goreleaser.yaml. For this project's scope, goreleaser would replacebuild.shANDrelease.ymland remove the duplication entirely.Integrity
If using a matrix:
Consider
cosign sign-blob/ Sigstore for keyless signing on top.Container image
A trivial multi-arch image (alongside the release):
Publish to GHCR (
ghcr.io/dolph/connectivity:${TAG}) usingdocker/build-push-action.Deduplicate build config
Extract version-ldflags into a single source of truth — a
make ldflagstarget, aversion.shhelper, or just commit to goreleaser which centralizes it.Impact
A maintainer-grade release pipeline catches its own regressions (failed cross-compile, broken ldflags) before users do, and removes future "user can't install on Mac" / "no checksums" / "no image" requests.
Relates to #13 (toolchain), #22 (deps).