From 9ac493a4c3d605fe73fec871e32bc99218e9cd10 Mon Sep 17 00:00:00 2001 From: Kim Gustyr Date: Wed, 29 Jul 2026 11:28:28 +0100 Subject: [PATCH 1/5] ci: build release binaries with goreleaser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Six targets, matching the cross-compile job: linux, darwin and windows on amd64 and arm64. CGO_ENABLED=0 costs nothing — go-keyring shells out to `security` on macOS and talks D-Bus on Linux, neither of which needs cgo. The tag drives everything: release-please creates it and the release, then `mode: append` uploads the archives into that release without touching the notes it wrote. beep boop --- .github/workflows/release.yml | 28 +++++++++++++++++++++++ .goreleaser.yaml | 43 +++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 .github/workflows/release.yml create mode 100644 .goreleaser.yaml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..21589d2 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,28 @@ +name: Release + +on: + push: + tags: ["v*"] + +permissions: + contents: read + +jobs: + goreleaser: + runs-on: ubuntu-latest + permissions: + contents: write # upload release artifacts + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + fetch-depth: 0 + persist-credentials: false + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 + with: + go-version-file: go.mod + - uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7.2.3 + with: + version: "~> v2" + args: release --clean + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.goreleaser.yaml b/.goreleaser.yaml new file mode 100644 index 0000000..d45c9a8 --- /dev/null +++ b/.goreleaser.yaml @@ -0,0 +1,43 @@ +version: 2 + +builds: + - binary: flagsmith + env: + - CGO_ENABLED=0 + flags: + - -trimpath + # .Tag, not .Version: `flagsmith --version` should print the tag verbatim, + # and internal/version.IsRelease expects the leading v. + ldflags: + - -s -w -X github.com/Flagsmith/flagsmith-cli/internal/version.Version={{ .Tag }} + mod_timestamp: "{{ .CommitTimestamp }}" + goos: + - linux + - darwin + - windows + goarch: + - amd64 + - arm64 + +archives: + - name_template: "flagsmith_{{ .Version }}_{{ .Os }}_{{ .Arch }}" + formats: + - tar.gz + format_overrides: + - goos: windows + formats: + - zip + files: + - LICENSE + - README.md + +checksum: + name_template: checksums.txt + +# changelog handled by release-please. +changelog: + disable: true + +release: + mode: append + prerelease: auto From 46d2640837215d134a83eee8fb54ae4109e3ab5d Mon Sep 17 00:00:00 2001 From: Kim Gustyr Date: Wed, 29 Jul 2026 21:53:48 +0100 Subject: [PATCH 2/5] ci: attest release archives MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit goreleaser has no attestation of its own — the documented route is actions/attest after it runs. subject-checksums attests every file listed in checksums.txt, so all six archives are covered without naming them. Verify with `gh attestation verify --owner Flagsmith `. beep boop --- .github/workflows/release.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 21589d2..05bd1a3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,6 +12,8 @@ jobs: runs-on: ubuntu-latest permissions: contents: write # upload release artifacts + id-token: write # attest artifacts + attestations: write steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -26,3 +28,7 @@ jobs: args: release --clean env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # Attests every file listed in the checksum file. + - uses: actions/attest@508db95dd578ae2727ebd6217d5ba78e4fbda05d # v4.2.1 + with: + subject-checksums: ./dist/checksums.txt From ea25e8d386325885d1cc78f6240a0133b42e467d Mon Sep 17 00:00:00 2001 From: Kim Gustyr Date: Thu, 30 Jul 2026 12:18:57 +0100 Subject: [PATCH 3/5] ci: mark beta releases as Latest GitHub will not let a prerelease be Latest ("Drafts and prereleases cannot be set as latest"), and the prerelease flag is not separable from the -beta version: release-please derives it from the version itself. So clear the flag after publishing instead. The condition takes itself out of service once 2.0.0 ships, since a stable release becomes Latest on its own. beep boop --- .github/workflows/release.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 05bd1a3..b3826fa 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,3 +32,10 @@ jobs: - uses: actions/attest@508db95dd578ae2727ebd6217d5ba78e4fbda05d # v4.2.1 with: subject-checksums: ./dist/checksums.txt + + # During public beta the newest beta is what people + # should land on, so clear it. + - if: contains(github.ref_name, '-beta') + run: gh release edit "$GITHUB_REF_NAME" --prerelease=false --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From cae365beaabf44ad8d5334c9ef8a4d3c9afaf22f Mon Sep 17 00:00:00 2001 From: Kim Gustyr Date: Thu, 30 Jul 2026 12:53:33 +0100 Subject: [PATCH 4/5] ci: never touch the notes release-please wrote MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `mode` governs the release notes, not the artifacts — those upload either way. append happens to be harmless while the changelog is disabled, since our notes are empty, but keep-existing says what we mean and stays correct if anyone enables the changelog later. beep boop --- .goreleaser.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index d45c9a8..41a6635 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -39,5 +39,5 @@ changelog: disable: true release: - mode: append + mode: keep-existing prerelease: auto From ab10f2996c6afa7781933c3e023ffdd2839b7d67 Mon Sep 17 00:00:00 2001 From: Kim Gustyr Date: Thu, 30 Jul 2026 13:04:17 +0100 Subject: [PATCH 5/5] fix: stop snapshot builds claiming to be a release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .Tag is the last release tag even under --snapshot, so every snapshot stamped v1.1.0 and IsRelease then pinned doc URLs to a tag the build has nothing to do with. Snapshots now stamp the snapshot version, v1.1.0-SNAPSHOT-090323e. Stamping the literal `dev` would not have worked: resolve() treats dev as unstamped and replaces it from debug.ReadBuildInfo, which yields a Go pseudo-version — correct, but it would show up in --version and the User-Agent as v1.1.1-0.20260730115333-090323eb8be5+dirty. beep boop --- .goreleaser.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 41a6635..228cb43 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -6,10 +6,9 @@ builds: - CGO_ENABLED=0 flags: - -trimpath - # .Tag, not .Version: `flagsmith --version` should print the tag verbatim, - # and internal/version.IsRelease expects the leading v. ldflags: - - -s -w -X github.com/Flagsmith/flagsmith-cli/internal/version.Version={{ .Tag }} + - >- + -s -w -X github.com/Flagsmith/flagsmith-cli/internal/version.Version={{ if .IsSnapshot }}v{{ .Version }}{{ else }}{{ .Tag }}{{ end }} mod_timestamp: "{{ .CommitTimestamp }}" goos: - linux