-
Notifications
You must be signed in to change notification settings - Fork 0
116 lines (107 loc) · 4.9 KB
/
Copy pathrelease.yml
File metadata and controls
116 lines (107 loc) · 4.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
name: Release (artifacts + signing)
# Builds release artifacts and signs them when a `v*` tag is pushed.
#
# The tag itself is cut by scripts/release.sh: it builds the React UI, makes a
# DETACHED commit embedding internal/ui/dist, tags it, and pushes ONLY the tag
# (main stays source-only). This workflow runs on that tag push and owns
# release ARTIFACTS + SIGNING — GoReleaser builds the cross-platform binaries,
# emits checksums + SBOMs, and cosign keyless-signs the checksums file so a
# .sig + .pem pair attaches to the release. That satisfies Scorecard's
# Packaging (a publishing workflow is detected) and Signed-Releases checks.
#
# release.sh embeds internal/ui/dist into the detached tagged commit, but this
# workflow rebuilds the UI (npm ci && npm run build) BEFORE invoking goreleaser
# anyway: `go build` only recompiles Go (never runs vite), so rebuilding here
# guarantees the embedded dist is present and current regardless of how the tag
# was produced.
#
# All third-party actions are SHA-pinned per Scorecard Pinned-Dependencies;
# pins are reused verbatim from security.yml / scorecard.yml where they overlap.
on:
push:
tags:
- 'v*'
# Manual re-release: run the CURRENT (default-branch) workflow against an
# already-pushed tag. GoReleaser's `release: mode: append` adds artifacts to
# the existing release WITHOUT mutating the immutable tag — used to recover a
# release whose original tag-push run failed.
workflow_dispatch:
inputs:
tag:
description: 'Existing tag to (re)build + sign (e.g. v0.3.1)'
required: true
# Workflow-level default: minimum needed for actions/checkout. The release job
# escalates to contents: write (create/append the GitHub release + upload
# assets) and id-token: write (cosign keyless OIDC).
permissions:
contents: read
jobs:
goreleaser:
name: GoReleaser (build · sbom · sign)
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
steps:
- name: Harden runner egress
# step-security/harden-runner v2.19.0
uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40
with:
egress-policy: audit
- name: Checkout tag
# actions/checkout v4.2.2
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
# On workflow_dispatch, build the supplied existing tag; on a tag
# push, the pushed ref. Full history so goreleaser version detection
# works.
ref: ${{ inputs.tag || github.ref }}
fetch-depth: 0
persist-credentials: false
- name: Set up Go
# actions/setup-go v6.2.0
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5
with:
go-version-file: go.mod
cache: true
- name: Set up Node
# actions/setup-node v6.4.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e
with:
node-version: '24'
- name: Build UI (embedded into the binary)
# The Go binary embeds internal/ui/dist via //go:embed; build it before
# goreleaser compiles. `npm run build` emits into internal/ui/dist.
run: |
cd ui
npm ci
npm run build
test -f ../internal/ui/dist/index.html
# vite's emptyOutDir wipes internal/ui/dist on rebuild, deleting the
# committed .gitkeep placeholder that script-cut release tags carry.
# Restore it so the working tree matches the tag and GoReleaser's
# dirty-state check passes (no-op for tags that don't track .gitkeep).
git -C "$GITHUB_WORKSPACE" checkout -- internal/ui/dist/.gitkeep 2>/dev/null || true
- name: Install cosign
# sigstore/cosign-installer v3.9.2 — provides `cosign` for the keyless
# signing step in .goreleaser.yaml (signs: cmd: cosign).
uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159
- name: Install syft
# anchore/sbom-action v0.24.0 (download-syft sub-action) — puts `syft`
# on PATH for the goreleaser `sboms:` step, which shells out to syft per
# archive. Without this goreleaser fails: `exec: "syft": not found`.
# Pin reused from security.yml.
uses: anchore/sbom-action/download-syft@e22c389904149dbc22b58101806040fa8d37a610
- name: Run GoReleaser
# goreleaser/goreleaser-action v6.2.1
uses: goreleaser/goreleaser-action@90a3faa9d0182683851fbfa97ca1a2cb983bfca3
with:
version: '~> v2'
args: release --clean
env:
# Pure-Go SQLite driver → cgo off (matches .goreleaser.yaml builds.env).
CGO_ENABLED: '0'
# Default token: goreleaser uses it to create/append the release.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# cosign keyless reads the OIDC token from these (set by id-token: write).
COSIGN_EXPERIMENTAL: '1'