-
Notifications
You must be signed in to change notification settings - Fork 314
255 lines (225 loc) · 9.74 KB
/
Copy pathrelease.yml
File metadata and controls
255 lines (225 loc) · 9.74 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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
name: Release
on:
push:
branches:
- main
workflow_dispatch:
concurrency: ${{ github.workflow }}-${{ github.ref }}
jobs:
check-release:
name: Check for new version
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: read
outputs:
should_release: ${{ steps.check.outputs.should_release }}
needs_github_release: ${{ steps.check.outputs.needs_github_release }}
version: ${{ steps.check.outputs.version }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "24"
registry-url: "https://registry.npmjs.org"
- name: Compare package.json version to npm and check GitHub release
id: check
run: |
LOCAL_VERSION=$(node -p "require('./packages/native-sdk/package.json').version")
echo "Local version: $LOCAL_VERSION"
NPM_VERSION=$(npm view @native-sdk/cli version 2>/dev/null || echo "0.0.0")
echo "npm version: $NPM_VERSION"
if [ "$LOCAL_VERSION" != "$NPM_VERSION" ]; then
echo "Version changed: $NPM_VERSION -> $LOCAL_VERSION"
echo "should_release=true" >> "$GITHUB_OUTPUT"
echo "needs_github_release=true" >> "$GITHUB_OUTPUT"
else
echo "Version unchanged on npm, skipping publish"
echo "should_release=false" >> "$GITHUB_OUTPUT"
TAG="v$LOCAL_VERSION"
EXISTING_ASSETS=$(gh release view "$TAG" --json assets --jq '.assets[].name' 2>/dev/null || true)
missing=0
for asset in \
CHECKSUMS.txt \
native-sdk-darwin-arm64 \
native-sdk-darwin-x64 \
native-sdk-linux-arm64 \
native-sdk-linux-x64 \
native-sdk-linux-musl-arm64 \
native-sdk-linux-musl-x64 \
native-sdk-win32-arm64.exe \
native-sdk-win32-x64.exe
do
if ! printf '%s\n' "$EXISTING_ASSETS" | grep -Fx "$asset" >/dev/null; then
echo "Missing release asset: $asset"
missing=1
fi
done
if [ "$missing" -eq 0 ]; then
echo "GitHub release $TAG exists with native assets"
echo "needs_github_release=false" >> "$GITHUB_OUTPUT"
else
echo "GitHub release $TAG is missing native assets, will create/update it"
echo "needs_github_release=true" >> "$GITHUB_OUTPUT"
fi
fi
echo "version=$LOCAL_VERSION" >> "$GITHUB_OUTPUT"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
github-release:
name: Create GitHub Release
needs: check-release
if: needs.check-release.outputs.needs_github_release == 'true'
runs-on: macos-14
timeout-minutes: 10
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Zig
uses: vercel-labs/setup-zig@v1
with:
version: 0.16.0
- name: Extract changelog entry
run: |
VERSION="${{ needs.check-release.outputs.version }}"
awk '/<!-- release:start -->/{found=1; next} /<!-- release:end -->/{exit} found{print}' CHANGELOG.md > /tmp/release-notes.md
LINES=$(wc -l < /tmp/release-notes.md | tr -d ' ')
if [ "$LINES" -lt 2 ]; then
echo "Error: No release notes found between <!-- release:start --> and <!-- release:end --> markers in CHANGELOG.md"
exit 1
fi
echo "Extracted release notes for $VERSION ($LINES lines)"
- name: Build native release assets (all platforms)
run: |
# Cross-compiles the CLI for all eight platforms and writes the
# flat release assets + CHECKSUMS.txt into zig-out/release/.
bash packages/native-sdk/scripts/build-binaries.sh
- name: Create GitHub Release
run: |
VERSION="${{ needs.check-release.outputs.version }}"
TAG="v$VERSION"
if gh release view "$TAG" &>/dev/null; then
echo "Release $TAG already exists, updating assets"
else
echo "Creating release $TAG..."
gh release create "$TAG" \
--title "$TAG" \
--notes-file /tmp/release-notes.md
fi
gh release upload "$TAG" \
zig-out/release/native-sdk-* \
zig-out/release/CHECKSUMS.txt \
--clobber
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
publish:
name: Publish CLI to npm
needs: [check-release, github-release]
if: >-
always()
&& needs.check-release.outputs.should_release == 'true'
&& (needs.github-release.result == 'success' || needs.github-release.result == 'skipped')
runs-on: ubuntu-latest
timeout-minutes: 15
environment: Release
permissions:
contents: read
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "24"
registry-url: "https://registry.npmjs.org"
# Publishing uses npm trusted publishing (OIDC): the job's id-token
# permission lets npm mint short-lived credentials, so no npm token
# secret exists anywhere in this repo. All nine packages —
# @native-sdk/cli plus the eight @native-sdk/cli-* platform packages
# under packages/native-sdk/npm/ — must each be configured on
# npmjs.com with a GitHub Actions trusted publisher pointing at
# repository vercel-labs/native, workflow release.yml,
# environment Release. If a package is missing that configuration,
# npm publish fails loudly with an OIDC authentication error before
# anything is uploaded for that package. Trusted publishing requires
# npm >= 11.5.1, satisfied by the npm bundled with Node 24.
# @native-sdk/core (packages/core) joins that publish set the moment
# its "private" flag drops (see the publish step below) — its
# npmjs.com trusted-publisher configuration must exist BEFORE that
# flip lands.
- name: Check version sync
run: npm --prefix packages/native-sdk run version:check
- name: Check package scripts
run: npm --prefix packages/native-sdk run scripts:check
- name: Download release binaries
run: |
VERSION="${{ needs.check-release.outputs.version }}"
mkdir -p /tmp/native-sdk-release
gh release download "v$VERSION" \
--pattern 'native-sdk-*' \
--pattern 'CHECKSUMS.txt' \
--dir /tmp/native-sdk-release
(cd /tmp/native-sdk-release && sha256sum -c CHECKSUMS.txt)
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Stage binaries into the platform packages
run: |
# Release-asset name -> npm platform package (same table as
# packages/native-sdk/scripts/build-binaries.sh).
stage() {
asset="$1"; key="$2"; ext="$3"
mkdir -p "packages/native-sdk/npm/$key/bin"
cp "/tmp/native-sdk-release/$asset" "packages/native-sdk/npm/$key/bin/native$ext"
chmod 755 "packages/native-sdk/npm/$key/bin/native$ext"
}
stage native-sdk-darwin-arm64 darwin-arm64 ""
stage native-sdk-darwin-x64 darwin-x64 ""
stage native-sdk-linux-arm64 linux-arm64-gnu ""
stage native-sdk-linux-x64 linux-x64-gnu ""
stage native-sdk-linux-musl-arm64 linux-arm64-musl ""
stage native-sdk-linux-musl-x64 linux-x64-musl ""
stage native-sdk-win32-arm64.exe win32-arm64 ".exe"
stage native-sdk-win32-x64.exe win32-x64 ".exe"
- name: Publish to npm
run: |
VERSION="${{ needs.check-release.outputs.version }}"
# Platform packages first, so the main package's
# optionalDependencies pins are resolvable the moment it lands.
# Re-runs skip anything already on the registry at this version.
publish_dir() {
dir="$1"
name=$(node -p "require('./$dir/package.json').name")
if npm view "$name@$VERSION" version >/dev/null 2>&1; then
echo "$name@$VERSION already published, skipping"
return 0
fi
(cd "$dir" && npm publish --provenance --access public)
}
for dir in packages/native-sdk/npm/*/; do
publish_dir "${dir%/}"
done
# @native-sdk/core (packages/core) rides the same version and
# release gate as the CLI (sync-version.js stamps it; the
# version check above refuses a half-bumped tree).
#
# ============================ LOUD FLIP REQUIREMENT ==========
# packages/core/package.json keeps "private": true until the
# 0.5.0 cut BY DESIGN, and that field IS the publish switch:
# while private, the guard below skips the package (npm would
# refuse to publish it anyway); the 0.5.0 change that drops
# "private" makes this same step start publishing it with no
# workflow edit. Before dropping the flag, configure the
# @native-sdk/core trusted publisher on npmjs.com (see the note
# above) or the first public release fails here.
# =============================================================
if [ "$(node -p "require('./packages/core/package.json').private === true")" = "true" ]; then
echo "@native-sdk/core is private (pre-0.5.0): skipping publish by design"
else
publish_dir packages/core
fi
publish_dir packages/native-sdk