-
Notifications
You must be signed in to change notification settings - Fork 1
189 lines (165 loc) · 7.34 KB
/
Copy pathrelease.yml
File metadata and controls
189 lines (165 loc) · 7.34 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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
name: Release
# Trunk-based, per-merge releases: every push to `main` runs the CI gate, compiles
# standalone binaries, smoke-tests each one on its native OS/arch, and — only if
# everything above is green — hands off to semantic-release. semantic-release reads
# the conventional-commit history since the last release and, if there is a
# releasable `feat:`/`fix:`/breaking change, creates the version tag, the GitHub
# Release (with auto-generated notes as the changelog), and attaches the tarball +
# binaries built by the `build` job. No manual tag push (see #9; builds on the
# tag-triggered flow from #44, which this replaces).
#
# semantic-release publishes via the GitHub API using the default GITHUB_TOKEN, so
# the tag/release it creates does NOT re-trigger this workflow (GitHub does not fire
# `push` events for repo activity performed with the default token) — no loop risk.
on:
push:
branches: [main]
workflow_dispatch: {}
permissions:
contents: write # semantic-release: create the tag + GitHub Release
packages: write # @semantic-release/npm: publish @eqrm/ct-cli to GitHub Packages (npm.pkg.github.com)
jobs:
# CI gate + build the release assets every job below needs. Binaries are cross-
# compiled for all three targets from this single Linux runner — `bun build
# --compile` embeds a prebuilt runtime per target, so it doesn't need to run on
# the target OS to produce the binary (only to *execute* it, which is what the
# smoke-test jobs are for).
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run format:check
- run: npm run lint
- run: npm run typecheck
- run: npm test
- run: npm run build
# Pinned, not `latest`: the `release` job recompiles these very binaries and
# ships the recompiled ones, so both jobs must resolve the SAME bun — a bun
# release landing between the two jobs would otherwise mean the attached
# artifacts are not the ones the smoke tests ran (#116). Bump both together.
- uses: oven-sh/setup-bun@v2
with:
bun-version: 1.4.0
- name: Compile standalone binaries
run: bash .github/scripts/build-binaries.sh
# The release tarball is packed in the `release` job (via @semantic-release/exec)
# AFTER semantic-release bumps the version — packing it here would embed the
# placeholder 0.1.0 (see #84). The binaries + INSTALL.md below are version-agnostic
# assets the smoke jobs and release attach.
- name: Write install note
run: |
cat > release/INSTALL.md <<'EOF'
# Installing ct
## Standalone binary (no Node required)
```bash
# macOS, Apple Silicon
curl -L -o ct https://github.com/eqrm/ct-cli/releases/latest/download/ct-darwin-arm64
# macOS, Intel
curl -L -o ct https://github.com/eqrm/ct-cli/releases/latest/download/ct-darwin-x64
# Linux, x64
curl -L -o ct https://github.com/eqrm/ct-cli/releases/latest/download/ct-linux-x64
chmod +x ct
sudo mv ct /usr/local/bin/ct # or anywhere on your PATH
ct --help
```
## npm tarball (requires Node >= 20)
```bash
npm install -g https://github.com/eqrm/ct-cli/releases/latest/download/ct-cli.tgz
ct --help
```
EOF
- uses: actions/upload-artifact@v4
with:
name: release-assets
path: release/
retention-days: 1
if-no-files-found: error
# Each compiled binary is smoke-tested on its own native OS/arch — cross-compiled
# output can look fine and still fail to *run* jiti's dynamic TS transpilation at
# runtime, which is the whole risk of `bun build --compile` here (see
# .github/scripts/smoke-test-binary.sh for exactly what this does and doesn't prove).
smoke-darwin-arm64:
needs: build
runs-on: macos-14 # Apple Silicon
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: release-assets
path: release
- run: bash .github/scripts/smoke-test-binary.sh release/ct-darwin-arm64
smoke-darwin-x64:
needs: build
runs-on: macos-15 # Apple Silicon; executes the x64 binary via Rosetta 2 (macos-13 Intel runners are retired and queue forever)
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: release-assets
path: release
- run: bash .github/scripts/smoke-test-binary.sh release/ct-darwin-x64
smoke-linux-x64:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: release-assets
path: release
- run: bash .github/scripts/smoke-test-binary.sh release/ct-linux-x64
release:
needs: [smoke-darwin-arm64, smoke-darwin-x64, smoke-linux-x64]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
# semantic-release's commit-analyzer needs the full commit history since
# the last tag to compute the next version — a shallow checkout breaks it.
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 22
# The binaries are RECOMPILED here, inside semantic-release's prepare step,
# and the recompiled linux one is smoke-tested again there — see the
# @semantic-release/exec command below and #116. Keep this pin in lockstep
# with the `build` job's.
- uses: oven-sh/setup-bun@v2
with:
bun-version: 1.4.0
# @semantic-release/npm publishes the package from THIS working tree, so `dist/`
# must exist and devDependencies (tsup, via the `prepare` script) must be present
# here — the `release-assets` artifact only carries the binaries, not `dist/`.
- run: npm ci
- run: npm run build
- uses: actions/download-artifact@v4
with:
name: release-assets
path: release
- run: chmod +x release/ct-darwin-arm64 release/ct-darwin-x64 release/ct-linux-x64
# Pinned via npx rather than added as devDependencies (see #9) — this repo
# doesn't otherwise need semantic-release, so keep it out of package.json.
# @semantic-release/npm bumps the in-workspace version and publishes
# @eqrm/ct-cli to GitHub Packages (registry from package.json publishConfig);
# NPM_TOKEN=GITHUB_TOKEN authenticates against npm.pkg.github.com (needs the
# packages:write permission above). It only publishes when commit-analyzer
# finds a releasable change, and never to public npm (publishConfig pins the
# registry). Consumers in the org install it with just GITHUB_TOKEN — no PAT.
- name: Run semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
npx --yes \
-p semantic-release@24 \
-p @semantic-release/commit-analyzer@13 \
-p @semantic-release/release-notes-generator@14 \
-p @semantic-release/npm@12 \
-p @semantic-release/exec@6 \
-p @semantic-release/github@11 \
semantic-release