-
Notifications
You must be signed in to change notification settings - Fork 0
89 lines (81 loc) · 3.52 KB
/
release.yml
File metadata and controls
89 lines (81 loc) · 3.52 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
name: release
# CLI-MCP-13R2 — release pipeline for the `instant` CLI.
#
# Fires on a semver tag push (`v*.*.*`). Cross-compiles via GoReleaser,
# generates SBOMs, signs the checksum file with sigstore cosign (keyless
# OIDC), and publishes everything to the GitHub Release page.
#
# Why tag-driven instead of branch-driven: the other backend services in
# instanode.dev auto-deploy on every push to `master` (CLAUDE.md rule 15),
# but a CLI binary has a different shape — users install once and pin to
# the latest published release. Tagging is the canonical "this is a real
# release, not a transient build" signal.
on:
push:
tags:
- "v*.*.*"
# Default permissions are read-only. Each job grants the minimum scope it
# needs. `id-token: write` is required for sigstore keyless signing via
# the GitHub OIDC issuer.
permissions:
contents: read
jobs:
goreleaser:
name: build, sign, publish
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: write # publish artifacts to the release page
id-token: write # sigstore OIDC for keyless signing
attestations: write # SBOM attestation
steps:
# Full history + tags are required so GoReleaser can read the tag
# message and infer changelog scope.
- name: Checkout (full history + tags)
uses: actions/checkout@v6
with:
fetch-depth: 0
fetch-tags: true
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version-file: go.mod
# Third-party actions are PINNED to a commit SHA per CSO supply-chain
# policy. Renovate / Dependabot manages bumps; never use a floating
# tag in this workflow.
- name: Install cosign (sigstore)
# pinned: tag v3.7.0
uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6
with:
# v2.6.3 (latest v2 line). The v0.3.0 release run failed BEFORE
# goreleaser even started: goreleaser-action verifies its own
# download against checksums.txt.sigstore.json, and cosign v2.4.1
# cannot read the new-style protobuf sigstore bundle goreleaser
# v2.16.0 ships ("bundle does not contain cert for verification").
# Staying on the v2 line keeps our signs: invocation
# (sign-blob --output-signature/--output-certificate --yes)
# contract-identical.
cosign-release: 'v2.6.3'
- name: Install syft (SBOM)
# pinned: tag v0.20.0
uses: anchore/sbom-action/download-syft@e22c389904149dbc22b58101806040fa8d37a610
- name: Run GoReleaser
# pinned: tag v6.4.0
uses: goreleaser/goreleaser-action@5daf1e915a5f0af01ddbcd89a43b8061ff4f1a89
with:
distribution: goreleaser
version: "~> v2"
args: release --clean
env:
# GITHUB_TOKEN is the per-job, repo-scoped, short-lived token —
# NOT a long-lived PAT. GoReleaser uses it to upload the
# release artifacts to the same repo.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# HOMEBREW_TAP_TOKEN pushes the brew formula to
# InstaNode-dev/homebrew-tap (a cross-repo write the per-job
# GITHUB_TOKEN cannot do — it needs an operator-minted PAT with
# `repo` scope on the tap). When the secret is unset this
# resolves to "" and the brews.skip_upload guard in
# .goreleaser.yml skips the formula push WITHOUT failing the
# release.
HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}