-
Notifications
You must be signed in to change notification settings - Fork 0
142 lines (129 loc) · 6.09 KB
/
Copy pathrelease.yml
File metadata and controls
142 lines (129 loc) · 6.09 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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
name: release
# Two ways in, one pipeline. Pushing a v* tag releases that tag. The manual
# dispatch takes a version, creates the tag on main's head in-run, and
# releases it — the tag still exists afterwards, because goreleaser derives
# the version, the changelog range, and the GitHub Release from the tag
# itself. (The in-run tag push uses GITHUB_TOKEN, which deliberately does
# not re-trigger the tag event — the same run carries on to goreleaser.)
on:
push:
tags: ["v*"]
workflow_dispatch:
inputs:
bump:
description: "Which part of the version to bump"
type: choice
# No default, on purpose: with zero tags the base is v0.0.0, so a
# patch default would have minted v0.0.1 as the first-ever release.
# The dispatcher has to say what kind of release this is. (The tag
# step below refuses v0.0.x regardless, in case the UI ever
# preselects an option anyway.)
required: true
options: [patch, minor, major]
permissions:
contents: write
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
# Required for the changelog: goreleaser walks the history
# between tags.
fetch-depth: 0
# Fail here, not mid-goreleaser: the cask publish to karnstack/tap is
# the last thing goreleaser does, so a missing or powerless
# TAP_GITHUB_TOKEN would only surface after the GitHub release and
# artifacts are already live — a stranded half-release where the
# release page looks fine and `brew install karnstack/tap/flue` is
# broken. Prove the token exists and can see the tap before anything
# is tagged or published.
- name: Preflight the tap token
env:
GH_TOKEN: ${{ secrets.TAP_GITHUB_TOKEN }}
run: |
if [ -z "$GH_TOKEN" ]; then
echo "::error::TAP_GITHUB_TOKEN is not set. Add the repo secret (a token that can push to karnstack/tap) before releasing."
exit 1
fi
if ! gh api repos/karnstack/tap --silent; then
echo "::error::karnstack/tap is not reachable with TAP_GITHUB_TOKEN. Check that the repo exists and the token grants access to it."
exit 1
fi
# go, node, and pnpm from mise.toml — goreleaser's before hook runs
# `make web`, which needs all three, and so does the test gate below.
- name: Install the toolchain from mise.toml
uses: jdx/mise-action@v4
# mise-action caches the tools it installs, but not the pnpm store;
# cache it separately, keyed on the lockfile.
- name: Locate the pnpm store
id: pnpm-store
run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"
- name: Cache the pnpm store
uses: actions/cache@v6
with:
path: ${{ steps.pnpm-store.outputs.path }}
key: pnpm-store-${{ runner.os }}-${{ hashFiles('web/pnpm-lock.yaml', 'relay/pnpm-lock.yaml') }}
restore-keys: |
pnpm-store-${{ runner.os }}-
# The same test surface ci.yml runs, and it runs before the tag step
# on purpose: a tag is forever, so a broken main head has to fail the
# run while it is still untagged and unpublished — after tagging is
# too late.
- name: Lint and test
run: make lint test
# ubuntu-latest images ship shellcheck, so this step normally does
# nothing. The guard is what keeps it honest: the unconditional
# apt-get it replaces once sat on a bad mirror for 40+ minutes, and a
# step that exists only for the day the image drops the tool must not
# be able to hold CI hostage — hence also the timeout.
- name: Install shellcheck if the image lost it
timeout-minutes: 3
run: command -v shellcheck || (sudo apt-get update -qq && sudo apt-get install -y -qq shellcheck)
- name: Shellcheck the install script
run: shellcheck scripts/install.sh scripts/install_test.sh
- name: Install-script tests
run: bash scripts/install_test.sh
- name: Tag the next ${{ inputs.bump }} version
if: github.event_name == 'workflow_dispatch'
env:
BUMP: ${{ inputs.bump }}
run: |
# The next version comes from the latest existing v* tag. With no
# tags yet, the base is v0.0.0 — so the first minor-bump release
# is v0.1.0.
latest=$(git tag --list 'v*' --sort=-v:refname | head -n 1)
latest=${latest:-v0.0.0}
IFS=. read -r major minor patch <<< "${latest#v}"
case "$BUMP" in
major) version="v$((major + 1)).0.0" ;;
minor) version="v${major}.$((minor + 1)).0" ;;
patch) version="v${major}.${minor}.$((patch + 1))" ;;
esac
echo "releasing ${version} (latest was ${latest})" | tee -a "$GITHUB_STEP_SUMMARY"
# A v0.0.x result can only mean a patch bump off the tagless
# repo — nothing has shipped yet, so the first release must be at
# least v0.1.0. Refuse to mint it rather than publish it.
case "$version" in
v0.0.*)
echo "::error::refusing to tag ${version}: no release exists yet, so the first one must be at least v0.1.0. Re-run with bump=minor (or major)."
exit 1
;;
esac
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -a "$version" -m "$version"
git push origin "$version"
- name: Release
uses: goreleaser/goreleaser-action@v7
with:
distribution: goreleaser
version: "~> v2"
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# User-provided repo secret — the one manual setup step. It
# authorizes the cask push to karnstack/tap; the default
# GITHUB_TOKEN cannot write to another repository. The preflight
# step has already proven it non-empty and able to see the tap.
TAP_GITHUB_TOKEN: ${{ secrets.TAP_GITHUB_TOKEN }}