Skip to content

Commit 086cbf7

Browse files
aksOpsclaude
andauthored
ci(release): switch to goreleaser (scorecard Packaging → detected) (#43)
Swaps softprops/action-gh-release for goreleaser/goreleaser-action, which is what scorecard's Packaging check recognises. Keeps the matrix build (CGO + sqlite-vec needs native hosts for darwin-arm64) by feeding binaries into goreleaser's prebuilt builder. goreleaser handles: - archives (binary, no wrapper) - checksums (SHA256SUMS) - cosign signing (same keyless Sigstore as before) - GitHub release + auto-generated changelog Workflow still: - computes bump (workflow_dispatch input) - builds UI once, binaries in matrix - emits SLSA build provenance (attest-build-provenance v4.1.0) - uploads provenance bundle to the release Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 7d21e6c commit 086cbf7

2 files changed

Lines changed: 121 additions & 63 deletions

File tree

.github/workflows/release.yml

Lines changed: 52 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
name: release
22

3-
# Manually-triggered stable release. Pick bump (patch/minor/major);
4-
# the next vX.Y.Z tag is computed from the latest stable tag.
5-
#
6-
# Beta auto-tagging was removed: the scorecard Signed-Releases check
7-
# ignores prereleases, and most users download the latest stable tag.
8-
# Tag pushes are not a trigger so the workflow cannot recurse on its
9-
# own tag.
3+
# Manually-triggered stable release via goreleaser. Pick bump
4+
# (patch/minor/major); the next vX.Y.Z tag is computed from the
5+
# latest stable tag.
106
on:
117
workflow_dispatch:
128
inputs:
@@ -92,7 +88,7 @@ jobs:
9288
if-no-files-found: error
9389

9490
build:
95-
name: build ${{ matrix.suffix }}
91+
name: build ${{ matrix.goos }}-${{ matrix.goarch }}
9692
needs: [tag, ui]
9793
strategy:
9894
fail-fast: false
@@ -101,11 +97,9 @@ jobs:
10197
- runner: ubuntu-latest
10298
goos: linux
10399
goarch: amd64
104-
suffix: linux-amd64
105100
- runner: macos-latest
106101
goos: darwin
107102
goarch: arm64
108-
suffix: darwin-arm64
109103
runs-on: ${{ matrix.runner }}
110104
permissions:
111105
contents: read
@@ -126,77 +120,83 @@ jobs:
126120
path: ui/dist
127121

128122
- name: Build binary
129-
id: build
130123
run: |
131124
set -eu
132125
tag="${{ needs.tag.outputs.tag }}"
133126
sha="${{ github.sha }}"
134127
date="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
135128
pkg="github.com/RandomCodeSpace/docsiq/cmd"
136129
ldflags="-s -w -X ${pkg}.Version=${tag} -X ${pkg}.Commit=${sha} -X ${pkg}.Date=${date}"
137-
out="docsiq-${tag}-${{ matrix.suffix }}"
138-
go build -tags sqlite_fts5 -trimpath -ldflags="${ldflags}" -o "${out}" ./
139-
echo "binary=${out}" >> "$GITHUB_OUTPUT"
130+
go build -tags sqlite_fts5 -trimpath -ldflags="${ldflags}" -o docsiq ./
140131
141132
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
142133
with:
143-
name: binary-${{ matrix.suffix }}
144-
path: ${{ steps.build.outputs.binary }}
134+
name: binary-${{ matrix.goos }}-${{ matrix.goarch }}
135+
path: docsiq
145136
retention-days: 1
146137
if-no-files-found: error
147138

148139
release:
149-
name: sign + publish
140+
name: goreleaser
150141
needs: [tag, build]
151142
runs-on: ubuntu-latest
152143
permissions:
153144
contents: write
154-
id-token: write # required for cosign keyless signing
155-
attestations: write # required for actions/attest-build-provenance
145+
id-token: write # cosign keyless
146+
attestations: write # SLSA provenance
156147
steps:
157148
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
158149
with:
159150
fetch-depth: 0
160151

161-
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
152+
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
162153
with:
163-
pattern: binary-*
164-
merge-multiple: true
165-
path: dist/
154+
go-version-file: go.mod
166155

167156
- uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1
168157
with:
169-
# Pin v2.x — v3 changed sign-blob defaults to emit a Sigstore
170-
# bundle alongside, and our --output-signature/--output-certificate
171-
# flags aren't compatible with that new behaviour. Revisit v3 once
172-
# we're ready to switch to bundle-based attestations.
158+
# v2.x — v3 broke our sign-blob flag compatibility.
173159
cosign-release: 'v2.6.3'
174160

175-
- name: Sign binaries
161+
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
162+
with:
163+
pattern: binary-*
164+
path: downloaded/
165+
166+
- name: Lay out prebuilt/ for goreleaser
176167
run: |
177168
set -eu
178-
cd dist
179-
for f in docsiq-*; do
180-
case "$f" in *.sig|*.pem|SHA256SUMS*) continue ;; esac
181-
cosign sign-blob --yes \
182-
--output-signature "${f}.sig" \
183-
--output-certificate "${f}.pem" \
184-
"$f"
169+
mkdir -p prebuilt
170+
for dir in downloaded/binary-*; do
171+
rest=$(basename "$dir" | sed 's/^binary-//')
172+
goos="${rest%-*}"
173+
goarch="${rest##*-}"
174+
target_dir="prebuilt/docsiq_${goos}_${goarch}"
175+
mkdir -p "$target_dir"
176+
cp "$dir/docsiq" "$target_dir/docsiq"
177+
chmod +x "$target_dir/docsiq"
185178
done
179+
ls -R prebuilt/
186180
187-
- name: Generate SHA256SUMS (+ signature)
181+
- name: Create + push tag
182+
env:
183+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
188184
run: |
189185
set -eu
190-
cd dist
191-
sha256sum docsiq-* > SHA256SUMS
192-
cosign sign-blob --yes \
193-
--output-signature SHA256SUMS.sig \
194-
--output-certificate SHA256SUMS.pem \
195-
SHA256SUMS
196-
197-
# SLSA build provenance — scorecard's Signed-Releases check asks
198-
# for in-toto attestations alongside the cosign sigs. The bundle
199-
# covers both binaries and SHA256SUMS.
186+
tag="${{ needs.tag.outputs.tag }}"
187+
git tag "$tag"
188+
git push origin "$tag"
189+
190+
- name: Run goreleaser
191+
uses: goreleaser/goreleaser-action@e24998b8b67b290c2fa8b7c14fcfa7de2c5c9b8c # v7.1.0
192+
with:
193+
distribution: goreleaser
194+
version: 'v2.15.4'
195+
args: release --clean
196+
env:
197+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
198+
GORELEASER_CURRENT_TAG: ${{ needs.tag.outputs.tag }}
199+
200200
- name: Generate SLSA build provenance
201201
id: attest
202202
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
@@ -206,22 +206,11 @@ jobs:
206206
dist/docsiq-*-darwin-arm64
207207
dist/SHA256SUMS
208208
209-
- name: Copy attestation into dist
209+
- name: Upload provenance to release
210+
env:
211+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
210212
run: |
211213
set -eu
212-
cp "${{ steps.attest.outputs.bundle-path }}" \
213-
dist/docsiq-${{ needs.tag.outputs.tag }}.intoto.jsonl
214-
215-
# softprops/action-gh-release is the pattern scorecard's Packaging
216-
# check recognises, replacing our ad-hoc `gh release create`.
217-
# Creates the tag on the triggering SHA when it doesn't yet exist.
218-
- name: Create GitHub release
219-
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
220-
with:
221-
tag_name: ${{ needs.tag.outputs.tag }}
222-
name: ${{ needs.tag.outputs.tag }}
223-
target_commitish: ${{ github.sha }}
224-
generate_release_notes: true
225-
make_latest: 'true'
226-
files: |
227-
dist/*
214+
tag="${{ needs.tag.outputs.tag }}"
215+
cp "${{ steps.attest.outputs.bundle-path }}" "docsiq-${tag}.intoto.jsonl"
216+
gh release upload "$tag" "docsiq-${tag}.intoto.jsonl"

.goreleaser.yaml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# goreleaser config — https://goreleaser.com
2+
#
3+
# We build docsiq natively on each target OS matrix job (linux-amd64
4+
# on ubuntu-latest, darwin-arm64 on macos-latest) because CGO +
5+
# sqlite-vec doesn't cross-compile cleanly. The matrix jobs upload
6+
# each binary, and this config picks them up via `builder: prebuilt`.
7+
version: 2
8+
9+
project_name: docsiq
10+
11+
builds:
12+
- id: docsiq
13+
builder: prebuilt
14+
goos: [linux, darwin]
15+
goarch: [amd64, arm64]
16+
targets:
17+
- linux_amd64
18+
- darwin_arm64
19+
prebuilt:
20+
path: 'prebuilt/docsiq_{{ .Os }}_{{ .Arch }}/docsiq'
21+
22+
archives:
23+
- formats:
24+
- binary
25+
name_template: 'docsiq-{{ .Tag }}-{{ .Os }}-{{ .Arch }}'
26+
27+
checksum:
28+
name_template: SHA256SUMS
29+
algorithm: sha256
30+
31+
signs:
32+
- cmd: cosign
33+
stdin: 'y'
34+
artifacts: all
35+
signature: '${artifact}.sig'
36+
certificate: '${artifact}.pem'
37+
args:
38+
- sign-blob
39+
- --yes
40+
- --output-signature=${signature}
41+
- --output-certificate=${certificate}
42+
- ${artifact}
43+
44+
release:
45+
name_template: '{{ .Tag }}'
46+
make_latest: 'true'
47+
footer: |
48+
### Verify
49+
50+
All artifacts are signed with [cosign](https://github.com/sigstore/cosign) keyless via Sigstore.
51+
52+
```sh
53+
cosign verify-blob \
54+
--certificate-identity-regexp 'https://github.com/RandomCodeSpace/docsiq/\.github/workflows/release\.yml.*' \
55+
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
56+
--certificate docsiq-{{ .Tag }}-linux-amd64.pem \
57+
--signature docsiq-{{ .Tag }}-linux-amd64.sig \
58+
docsiq-{{ .Tag }}-linux-amd64
59+
```
60+
61+
changelog:
62+
use: github
63+
sort: asc
64+
filters:
65+
exclude:
66+
- '^ci:'
67+
- '^docs:'
68+
- '^test:'
69+
- '^chore:'

0 commit comments

Comments
 (0)