Fix clean VCS metadata for release builds

This commit is contained in:
rcourtman
2026-05-01 23:12:41 +01:00
parent b0464b6c59
commit c8e24f06d7
5 changed files with 36 additions and 2 deletions
+1
View File
@@ -130,6 +130,7 @@ jobs:
SERVER_LDFLAGS="$(if [ -n "${PULSE_LICENSE_PUBLIC_KEY:-}" ]; then ./scripts/release_ldflags.sh server --version "${VERSION}" --build-time "${BUILD_TIME}" --git-commit "${GIT_COMMIT}" --license-public-key "${PULSE_LICENSE_PUBLIC_KEY}"; else ./scripts/release_ldflags.sh server --version "${VERSION}" --build-time "${BUILD_TIME}" --git-commit "${GIT_COMMIT}"; fi)"
CGO_ENABLED=0 go build \
-ldflags="${SERVER_LDFLAGS}" \
-buildvcs=false \
-trimpath \
-o pulse ./cmd/pulse/
+14
View File
@@ -86,11 +86,13 @@ RUN --mount=type=cache,id=pulse-go-mod,target=/go/pkg/mod \
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \
-tags release \
-ldflags="${SERVER_LDFLAGS}" \
-buildvcs=false \
-trimpath \
-o pulse-linux-amd64 ./cmd/pulse && \
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build \
-tags release \
-ldflags="${SERVER_LDFLAGS}" \
-buildvcs=false \
-trimpath \
-o pulse-linux-arm64 ./cmd/pulse
@@ -111,50 +113,62 @@ RUN --mount=type=cache,id=pulse-go-mod,target=/go/pkg/mod \
AGENT_LDFLAGS="$(./scripts/release_ldflags.sh agent --version "${VERSION}" $(if [ -n "${UPDATE_PUBLIC_KEYS}" ]; then printf '%s %s' --update-public-keys "${UPDATE_PUBLIC_KEYS}"; fi))" && \
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \
-ldflags="${AGENT_LDFLAGS}" \
-buildvcs=false \
-trimpath \
-o pulse-agent-linux-amd64 ./cmd/pulse-agent && \
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build \
-ldflags="${AGENT_LDFLAGS}" \
-buildvcs=false \
-trimpath \
-o pulse-agent-linux-arm64 ./cmd/pulse-agent && \
CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=7 go build \
-ldflags="${AGENT_LDFLAGS}" \
-buildvcs=false \
-trimpath \
-o pulse-agent-linux-armv7 ./cmd/pulse-agent && \
CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=6 go build \
-ldflags="${AGENT_LDFLAGS}" \
-buildvcs=false \
-trimpath \
-o pulse-agent-linux-armv6 ./cmd/pulse-agent && \
CGO_ENABLED=0 GOOS=linux GOARCH=386 go build \
-ldflags="${AGENT_LDFLAGS}" \
-buildvcs=false \
-trimpath \
-o pulse-agent-linux-386 ./cmd/pulse-agent && \
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build \
-ldflags="${AGENT_LDFLAGS}" \
-buildvcs=false \
-trimpath \
-o pulse-agent-darwin-amd64 ./cmd/pulse-agent && \
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build \
-ldflags="${AGENT_LDFLAGS}" \
-buildvcs=false \
-trimpath \
-o pulse-agent-darwin-arm64 ./cmd/pulse-agent && \
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build \
-ldflags="${AGENT_LDFLAGS}" \
-buildvcs=false \
-trimpath \
-o pulse-agent-windows-amd64.exe ./cmd/pulse-agent && \
CGO_ENABLED=0 GOOS=windows GOARCH=arm64 go build \
-ldflags="${AGENT_LDFLAGS}" \
-buildvcs=false \
-trimpath \
-o pulse-agent-windows-arm64.exe ./cmd/pulse-agent && \
CGO_ENABLED=0 GOOS=windows GOARCH=386 go build \
-ldflags="${AGENT_LDFLAGS}" \
-buildvcs=false \
-trimpath \
-o pulse-agent-windows-386.exe ./cmd/pulse-agent && \
CGO_ENABLED=0 GOOS=freebsd GOARCH=amd64 go build \
-ldflags="${AGENT_LDFLAGS}" \
-buildvcs=false \
-trimpath \
-o pulse-agent-freebsd-amd64 ./cmd/pulse-agent && \
CGO_ENABLED=0 GOOS=freebsd GOARCH=arm64 go build \
-ldflags="${AGENT_LDFLAGS}" \
-buildvcs=false \
-trimpath \
-o pulse-agent-freebsd-arm64 ./cmd/pulse-agent
@@ -206,6 +206,12 @@ server-side update execution surfaces.
External helper binaries fetched by governed release workflows are part of
the same supply-chain boundary and must be checksum-verified before they are
executed.
Release-grade Go builds must use `scripts/release_ldflags.sh` as the
canonical source for embedded version, commit, license, and update trust-root
identity, and must disable Go's automatic VCS stamping with
`-buildvcs=false` in `scripts/build-release.sh`, `Dockerfile`, and the demo
deployment build so generated frontend or release-packet files cannot leak a
misleading dirty-tree marker into published binary metadata.
Release validation must prove that installer script download endpoints return
signature headers, and unified-agent download endpoints must return checksum and signature headers whose checksum value matches the served binary.
8. Add or change the non-secret Pulse Cloud public signup route smoke through
+3 -2
View File
@@ -32,6 +32,7 @@ fi
# Force static binaries so release artifacts run on older glibc hosts
export CGO_ENABLED=0
release_go_build_args=(-buildvcs=false -trimpath)
VERSION=${1:-$(cat VERSION)}
BUILD_DIR="build"
@@ -141,7 +142,7 @@ for i in "${!agent_build_order[@]}"; do
env $build_env go build \
-ldflags="${agent_ldflags}" \
-trimpath \
"${release_go_build_args[@]}" \
-o "$output_path" \
./cmd/pulse-agent
done
@@ -179,7 +180,7 @@ for i in "${!build_order[@]}"; do
env $build_env go build \
-tags release \
-ldflags="${server_ldflags}" \
-trimpath \
"${release_go_build_args[@]}" \
-o "$BUILD_DIR/pulse-$build_name" \
./cmd/pulse
done
@@ -47,6 +47,8 @@ func TestBuildReleaseUsesV6InstallScripts(t *testing.T) {
requiredScriptWiring := []string{
`agent_ldflags="$(./scripts/release_ldflags.sh agent --version "v${VERSION}" "${update_ldflags_args[@]}")"`,
`server_ldflags="$(./scripts/release_ldflags.sh server --version "v${VERSION}" --build-time "${build_time}" --git-commit "${git_commit}" "${license_ldflags_args[@]}" "${update_ldflags_args[@]}")"`,
`release_go_build_args=(-buildvcs=false -trimpath)`,
`"${release_go_build_args[@]}"`,
`RELEASE_PACKET_SBOM="pulse-v${VERSION}-release.sbom.spdx.json"`,
`pulse_release_prepare_signing_state "pulse-installer" "pulse-install"`,
`trap 'pulse_release_cleanup_signing_state' EXIT`,
@@ -60,6 +62,9 @@ func TestBuildReleaseUsesV6InstallScripts(t *testing.T) {
t.Fatalf("build-release.sh missing canonical ldflags wiring: %s", needle)
}
}
if builds, cleanBuilds := strings.Count(script, `env $build_env go build \`), strings.Count(script, `"${release_go_build_args[@]}"`); builds != cleanBuilds {
t.Fatalf("build-release.sh must disable automatic VCS stamping on every release go build: builds=%d clean_builds=%d", builds, cleanBuilds)
}
helperBytes, err := os.ReadFile(repoFile("scripts", "release_asset_common.sh"))
if err != nil {
@@ -278,6 +283,8 @@ func TestReleaseValidationRequiresSignedSidecars(t *testing.T) {
"`checksums.txt` is missing its `.sshsig` sidecar",
"release-packet SBOM is absent",
"download endpoints must return checksum and signature headers",
"must disable Go's automatic VCS stamping",
"`-buildvcs=false`",
}
for _, needle := range contractRequired {
if !strings.Contains(contract, needle) {
@@ -314,6 +321,7 @@ func TestDockerAndDemoBuildsUseCanonicalReleaseLdflags(t *testing.T) {
`mounted update signing key does not match PULSE_UPDATE_SIGNING_PUBLIC_KEY.`,
`./scripts/release_ldflags.sh server --version "${VERSION}" --build-time "${BUILD_TIME}" --git-commit "${GIT_COMMIT}"`,
`./scripts/release_ldflags.sh agent --version "${VERSION}"`,
`-buildvcs=false`,
`go run ./scripts/render_installers.go --source-dir ./scripts --output-dir /app/rendered-installers`,
`--allow-empty-installer-ssh-public-key`,
`ssh-keygen -q -Y sign -f "${OPENSSH_SIGNING_KEY}" -n pulse-install`,
@@ -340,6 +348,9 @@ func TestDockerAndDemoBuildsUseCanonicalReleaseLdflags(t *testing.T) {
strings.Contains(dockerfile, `FROM alpine:3.20 AS pulse-runtime-base`) {
t.Fatal("Dockerfile base images must be pinned by immutable @sha256 digests")
}
if builds, cleanBuilds := strings.Count(dockerfile, " go build \\"), strings.Count(dockerfile, "-buildvcs=false"); builds != cleanBuilds {
t.Fatalf("Dockerfile release go builds must all disable automatic VCS stamping: builds=%d clean_builds=%d", builds, cleanBuilds)
}
workflowBytes, err := os.ReadFile(repoFile(".github", "workflows", "deploy-demo-server.yml"))
if err != nil {
@@ -348,6 +359,7 @@ func TestDockerAndDemoBuildsUseCanonicalReleaseLdflags(t *testing.T) {
workflow := string(workflowBytes)
workflowRequired := []string{
`./scripts/release_ldflags.sh server --version "${VERSION}" --build-time "${BUILD_TIME}" --git-commit "${GIT_COMMIT}"`,
`-buildvcs=false`,
`demo-preview-v6`,
`demo-stable`,
`workflow_dispatch:`,