-
Notifications
You must be signed in to change notification settings - Fork 0
231 lines (205 loc) · 7.95 KB
/
Copy pathrelease.yml
File metadata and controls
231 lines (205 loc) · 7.95 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
name: Release
on:
push:
tags:
- "v*"
permissions:
contents: write
jobs:
verify:
name: Verify release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 24
cache: npm
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- name: Verify all version sources match the tag
shell: bash
run: |
tag="${GITHUB_REF_NAME}"
npm_version="$(node -p "require('./package.json').version")"
cargo_version="$(sed -n 's/^version = "\(.*\)"/\1/p' src-tauri/Cargo.toml | head -1)"
tauri_version="$(node -p "require('./src-tauri/tauri.conf.json').version")"
echo "tag=${tag}"
echo "package.json=${npm_version}"
echo "Cargo.toml=${cargo_version}"
echo "tauri.conf.json=${tauri_version}"
ok=true
for v in "${cargo_version}" "${tauri_version}"; do
if [ "${v}" != "${npm_version}" ]; then
echo "::error::Version mismatch: package.json=${npm_version} but got ${v}"
ok=false
fi
done
if [ "${tag}" != "v${npm_version}" ]; then
echo "::error::Tag ${tag} does not match package.json version ${npm_version}"
ok=false
fi
if [ "${ok}" != "true" ]; then exit 1; fi
- name: Install dependencies
run: npm ci
# Frontend checks + rustfmt (fast). Full clippy/test run on Windows pack jobs
# and on main CI; keep tag verify from shipping unformatted Rust (CI gap that
# previously let Release succeed while the rust job failed on fmt).
- name: Frontend checks
run: npm run check:frontend
- name: Rust format check
run: cargo fmt --manifest-path src-tauri/Cargo.toml --check
# Single canonical changelog for Release body + latest.json notes + UpdateModal.
# Matrix pack jobs only consume this output (do not regenerate notes).
prepare-notes:
name: Prepare release notes
needs: verify
runs-on: ubuntu-latest
# generate-notes API requires contents:write (read-only GITHUB_TOKEN → 403).
permissions:
contents: write
outputs:
body: ${{ steps.gen.outputs.body }}
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 24
- name: Generate release notes
id: gen
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_TAG: ${{ github.ref_name }}
run: |
set -euo pipefail
node scripts/generate-release-notes.mjs | tee release-notes.md
echo "----- release notes -----"
cat release-notes.md
release:
name: ${{ matrix.name }}
needs: [verify, prepare-notes]
permissions:
contents: write
strategy:
fail-fast: false
matrix:
include:
- name: Windows x64
platform: windows-latest
rustTarget: ""
# NSIS installer is also the Windows updater artifact (.exe + .sig).
args: "--bundles nsis"
- name: macOS Apple Silicon
platform: macos-latest
rustTarget: aarch64-apple-darwin
# `app` is required for createUpdaterArtifacts (.app.tar.gz + .sig).
# DMG alone is only the first-install package — updater ignores it.
args: "--target aarch64-apple-darwin --bundles app,dmg"
- name: macOS Intel
platform: macos-latest
rustTarget: x86_64-apple-darwin
args: "--target x86_64-apple-darwin --bundles app,dmg"
runs-on: ${{ matrix.platform }}
timeout-minutes: 60
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 24
cache: npm
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.rustTarget }}
- uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri
- name: Install dependencies
run: npm ci
- name: Configure ad-hoc macOS signing
if: runner.os == 'macOS'
shell: bash
run: echo "APPLE_SIGNING_IDENTITY=-" >> "$GITHUB_ENV"
- name: Require updater signing key
shell: bash
env:
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
run: |
if [ -z "${TAURI_SIGNING_PRIVATE_KEY}" ]; then
echo "::error::TAURI_SIGNING_PRIVATE_KEY secret is empty — in-app updates cannot be signed."
exit 1
fi
- name: Build and publish installers
uses: tauri-apps/tauri-action@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Required for signed updater artifacts (must match pubkey in tauri.conf.json).
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
with:
tagName: ${{ github.ref_name }}
releaseName: "PinkCode ${{ github.ref_name }}"
# Same body on every matrix leg (from prepare-notes only).
releaseBody: ${{ needs.prepare-notes.outputs.body }}
releaseDraft: false
prerelease: false
# Publishes latest.json for tauri-plugin-updater endpoints.
uploadUpdaterJson: true
args: ${{ matrix.args }}
# Drop [bundle] so we don't get dmg.dmg / msi.msi / nsis.exe.
# Result: PinkCode_0.1.2_darwin_aarch64.dmg, …_windows_x64.msi, …_windows_x64.exe
# macOS updater: PinkCode_…_darwin_*.app.tar.gz (+ .sig)
releaseAssetNamePattern: "[name]_[version]_[platform]_[arch][ext]"
- name: Verify signed updater artifacts
shell: bash
run: |
set -euo pipefail
# Fail the job if this platform did not produce a minisign signature.
# Without .sig files, tauri-action omits the platform from latest.json
# and clients on that OS never see an update.
if [ "${{ runner.os }}" = "macOS" ]; then
target="${{ matrix.rustTarget }}"
root="src-tauri/target/${target}/release/bundle/macos"
echo "Looking for updater artifacts under ${root}"
ls -la "${root}" || true
sigs=( "${root}"/*.app.tar.gz.sig )
if [ ! -e "${sigs[0]}" ]; then
echo "::error::Missing macOS updater signature (*.app.tar.gz.sig). In-app updates will not work on Mac."
echo "Ensure createUpdaterArtifacts is true and --bundles includes app (not only dmg)."
exit 1
fi
tars=( "${root}"/*.app.tar.gz )
if [ ! -e "${tars[0]}" ]; then
echo "::error::Missing macOS updater bundle (*.app.tar.gz)."
exit 1
fi
echo "OK: $(basename "${tars[0]}") + $(basename "${sigs[0]}")"
else
root="src-tauri/target/release/bundle/nsis"
echo "Looking for updater artifacts under ${root}"
ls -la "${root}" || true
sigs=( "${root}"/*.sig )
if [ ! -e "${sigs[0]}" ]; then
echo "::error::Missing Windows updater signature (*.sig)."
exit 1
fi
echo "OK: $(basename "${sigs[0]}")"
fi
# Patch latest.json: public download URLs + notes === release body (UpdateModal source).
rewrite-updater-json:
name: Patch latest.json for updater
needs: release
if: always() && needs.release.result == 'success'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 24
- name: Rewrite platform URLs and sync notes
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_TAG: ${{ github.ref_name }}
run: node scripts/rewrite-updater-json.mjs