From fcad24c2f07dd7ac917eb6f6574e351071bf4a78 Mon Sep 17 00:00:00 2001 From: Lukasz Raczylo Date: Thu, 20 Aug 2026 22:04:31 +0100 Subject: [PATCH] fix(ci): real source archive via git export-ignore, current stamping docs --- .gitattributes | 15 +++++++++++++++ .gitignore | 1 + .goreleaser.yaml | 36 +++++++++++++++--------------------- admin_test.go | 12 ++++++++++-- workflow-prepare.sh | 18 +++++++++--------- 5 files changed, 50 insertions(+), 32 deletions(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..5b9572b --- /dev/null +++ b/.gitattributes @@ -0,0 +1,15 @@ +# export-ignore controls what `git archive` leaves out of the tree it +# packs. GoReleaser's `source:` block runs `git archive` under the hood +# (.goreleaser.yaml), so these entries are the actual filter for the +# release source tarball — not the archive block's own file globs, which +# have no negation syntax and cannot exclude anything. +vendor/ export-ignore +integration/ export-ignore +tools/ export-ignore +docs/ export-ignore +examples/ export-ignore +testdata/ export-ignore +.superpowers/ export-ignore +.github/ export-ignore +*_test.go export-ignore +.gitattributes export-ignore diff --git a/.gitignore b/.gitignore index 3e4f00b..2d3ef47 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .superpowers/ *.wasm tools/yaegi-check/llmgw-yaegi-check +dist/ # Rendered from integration/traefik/dynamic.yml.tmpl by `make integration-up` # (INTEGRATION_REAL_BASEURL substitution) — generated, not source. diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 7b35096..4ae4df8 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -5,27 +5,21 @@ version: 2 builds: - skip: true -# Create source archive for GitHub releases -archives: - - formats: [tar.gz] - name_template: "{{ .ProjectName }}_v{{ .Version }}_source" - files: - - "*.go" - - "**/*.go" - - go.mod - - go.sum - - .traefik.yml - - LICENSE* - - README* - # Exclude test files and non-shipped dirs from release archive - - "!**/*_test.go" - - "!testdata/**" - - "!tools/**" - - "!integration/**" - - "!docs/**" - - "!examples/**" - - "!vendor/**" - - "!.superpowers/**" +# Source archive for GitHub releases, built with `git archive` under the +# hood. `git archive` reads .gitattributes export-ignore at the archived +# commit — that is the real filter for test files and non-shipped dirs +# (vendor/, tools/, integration/, docs/, examples/, testdata/, +# .superpowers/, .github/); see .gitattributes at the repo root. +# +# An `archives:` files-list with `!glob` excludes looked equivalent but was +# not: GoReleaser's archive fileglob has no negation, so every `!`-prefixed +# entry was a silent no-op and the tarball shipped every file the plain +# globs matched, tests and vendor included. `source:` avoids that trap +# entirely because it does not use the archive fileglob at all. +source: + enabled: true + format: tar.gz + name_template: "{{ .ProjectName }}_v{{ .Version }}_source" checksum: name_template: "{{ .ProjectName }}_v{{ .Version }}_checksums.txt" diff --git a/admin_test.go b/admin_test.go index 87f6474..43e14b3 100644 --- a/admin_test.go +++ b/admin_test.go @@ -8,6 +8,7 @@ import ( "net/http" "net/http/httptest" "net/url" + "regexp" "strings" "testing" "time" @@ -216,8 +217,15 @@ func TestAdminOverview_SortedShapeAndVersion(t *testing.T) { t.Fatalf("decode: %v", err) } - if got.Version != pluginVersion { - t.Errorf("version = %q, want %q", got.Version, pluginVersion) + // Assert shape, not identity: comparing against the pluginVersion const + // itself is tautological (it would pass even if the overview handler + // stopped reading pluginVersion at all, as long as it echoed some other + // copy of the same string). The real invariant is what version.go's + // stamping contract promises: either the unstamped dev sentinel, or a + // release semver a build stamped in. + versionShape := regexp.MustCompile(`^(0\.0\.0-dev|\d+\.\d+\.\d+)$`) + if got.Version == "" || !versionShape.MatchString(got.Version) { + t.Errorf("version = %q, want non-empty and matching %s", got.Version, versionShape) } if len(got.Providers) != 2 || got.Providers[0].Name != "alpha" || got.Providers[1].Name != "zeta" { diff --git a/workflow-prepare.sh b/workflow-prepare.sh index 65a287a..a52c88e 100755 --- a/workflow-prepare.sh +++ b/workflow-prepare.sh @@ -12,16 +12,16 @@ # $VERSION $VERSION_TAG $SEMVER $NEW_VERSION $RELEASE_VERSION # A leading "v"/"V" is stripped. # -# NOTE: go-release.yaml @main does not yet pass the computed version into this -# step's environment. Add it to the "Run workflow prepare script" step, e.g.: -# env: -# VERSION: ${{ needs.version.outputs.version }} # bare, no leading v +# go-release.yaml's release job already exposes the computed version to this +# script's environment (shared-actions commit 58ab34e, "Run workflow prepare +# script" step): VERSION carries the bare semver, VERSION_TAG the v-prefixed +# form. Stamping works end-to-end with no extra wiring in this repo. # # The shared workflow runs this script in its test, version AND release jobs, -# but only the release job has a computed version. So a missing version is a -# no-op (leave the dev sentinel) — NOT a hard failure, otherwise the test/version -# jobs would break. A malformed version that IS provided is a hard error. Wire -# the env only on the release job's prepare step (see header note above). +# but only the release job's step sets that env — the test/version jobs run +# it with no version at all. So a missing version is a no-op (leave the dev +# sentinel) — NOT a hard failure, otherwise the test/version jobs would +# break. A malformed version that IS provided is a hard error. set -euo pipefail FILE="version.go" @@ -33,7 +33,7 @@ VER="${VER#V}" if [ -z "$VER" ]; then if [ "${GITHUB_ACTIONS:-}" = "true" ]; then - echo "workflow-prepare: WARNING no version provided; leaving ${FILE} at the dev placeholder. If this is the release build, set 'env: VERSION: \${{ needs.version.outputs.version }}' on the release job's prepare step — otherwise the release ships 0.0.0-dev and the admin overview reports it." >&2 + echo "workflow-prepare: WARNING no version provided; leaving ${FILE} at the dev placeholder. Expected on the test/version jobs. If this is the release job, the shared workflow's VERSION wiring (shared-actions commit 58ab34e) has broken — the release will ship 0.0.0-dev and the admin overview will report it." >&2 else echo "workflow-prepare: no version provided; leaving dev placeholder in ${FILE} (local build)" fi