-
Notifications
You must be signed in to change notification settings - Fork 161
355 lines (298 loc) · 12.8 KB
/
Copy pathrelease.yml
File metadata and controls
355 lines (298 loc) · 12.8 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
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
name: Build and Release to R2
on:
push:
tags:
- 'v*' # Trigger when pushing tags starting with v, e.g., v1.0.0
jobs:
build-and-upload:
runs-on: ${{ matrix.target.runner }}
strategy:
fail-fast: true # if it is set to true, then one job failed the other jobs will be cancelled together.
matrix:
component: [libra]
target:
- { rust: x86_64-unknown-linux-gnu, os: linux, arch: amd64, runner: ubuntu-latest }
- { rust: aarch64-unknown-linux-gnu, os: linux, arch: arm64, runner: ubuntu-24.04-arm }
- { rust: aarch64-apple-darwin, os: darwin, arch: arm64, runner: macos-latest }
- { rust: x86_64-pc-windows-msvc, os: windows, arch: amd64, runner: windows-latest }
steps:
- name: Checkout code
uses: actions/checkout@v5
with:
submodules: recursive
- name: Set up Rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
target: ${{ matrix.target.rust }}
- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: "22"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@11.10.0 --activate
- name: Install web dependencies
run: pnpm --dir web install --frozen-lockfile
- name: Install Linux dependencies
if: matrix.target.os == 'linux'
run: |
sudo apt-get update
- name: Cache cargo registry
uses: actions/cache@v5
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo index
uses: actions/cache@v5
with:
path: ~/.cargo/git
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo build
uses: actions/cache@v5
with:
path: target
key: ${{ runner.os }}-cargo-build-target-${{ matrix.target.rust }}-${{ hashFiles('**/Cargo.lock') }}
# plan-20260714 §A.11: release binaries must NEVER enable the
# `test-upgrade` feature (its compile-time trust-root/endpoint injection
# would let a build override the production trust root). The build below
# passes an explicit feature list; this guard fails the release if the
# test feature is ever spliced into the release build command.
- name: Reject test-upgrade feature in release build
if: matrix.target.os != 'windows'
shell: bash
run: |
if grep -nE -- '--features[^\n]*test-upgrade' .github/workflows/release.yml; then
echo "::error::release.yml must not build with the test-upgrade feature"
exit 1
fi
- name: Build Binary (Unix)
if: matrix.target.os != 'windows'
shell: bash
run: |
VERSION=${GITHUB_REF_NAME}
BINARY_NAME="${{ matrix.component }}-${{ matrix.target.os }}-${{ matrix.target.arch }}"
echo "Building $BINARY_NAME for target ${{ matrix.target.rust }}..."
RUSTFLAGS="-C strip=symbols" cargo build --locked --release --features keyring --target ${{ matrix.target.rust }}
# Create build directory and copy binary
mkdir -p build
cp target/${{ matrix.target.rust }}/release/${{ matrix.component }} build/$BINARY_NAME
# Make binary executable
chmod +x build/$BINARY_NAME
# Generate sha256 for Homebrew tap updates and CDN verification
if command -v sha256sum >/dev/null 2>&1; then
sha256sum "build/$BINARY_NAME" | awk '{print $1}' > "build/$BINARY_NAME.sha256"
else
shasum -a 256 "build/$BINARY_NAME" | awk '{print $1}' > "build/$BINARY_NAME.sha256"
fi
echo "Built binary: $BINARY_NAME"
- name: Build Binary (Windows)
if: matrix.target.os == 'windows'
shell: pwsh
run: |
$version = $env:GITHUB_REF_NAME
$binaryName = "${{ matrix.component }}-${{ matrix.target.os }}-${{ matrix.target.arch }}"
Write-Output "Building $binaryName for target ${{ matrix.target.rust }}..."
$env:RUSTFLAGS = "-C strip=symbols -C link-args=/STACK:0x1000000"
cargo build --locked --release --features keyring --target ${{ matrix.target.rust }}
# Create build directory and copy binary
New-Item -ItemType Directory -Force -Path "build" | Out-Null
Copy-Item "target\${{ matrix.target.rust }}\release\${{ matrix.component }}.exe" "build\$binaryName.exe"
Write-Output "Built binary: $binaryName"
- name: Upload to Cloudflare R2 (Unix)
if: matrix.target.os != 'windows'
shell: bash
env:
RCLONE_CONFIG_R2_TYPE: s3
RCLONE_CONFIG_R2_PROVIDER: Cloudflare
RCLONE_CONFIG_R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
RCLONE_CONFIG_R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
RCLONE_CONFIG_R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }}
RCLONE_CONFIG_R2_ACL: private
run: |
# Install rclone
if [[ "${{ matrix.target.os }}" == "darwin" ]]; then
brew install rclone
else
curl https://rclone.org/install.sh | sudo bash
fi
# Upload binaries to R2
rclone copy ./build/ r2:${{ secrets.R2_BUCKET_NAME }}/libra/releases/${{ github.ref_name }}/ -v
echo "Upload completed for ${{ matrix.component }}-${{ matrix.target.os }}-${{ matrix.target.arch }}"
- name: Upload Homebrew sha256 artifact
if: matrix.target.os != 'windows'
continue-on-error: true
uses: actions/upload-artifact@v5
with:
name: homebrew-sha256-${{ matrix.target.os }}-${{ matrix.target.arch }}
path: build/${{ matrix.component }}-${{ matrix.target.os }}-${{ matrix.target.arch }}.sha256
if-no-files-found: error
- name: Upload to Cloudflare R2 (Windows)
if: matrix.target.os == 'windows'
shell: pwsh
env:
RCLONE_CONFIG_R2_TYPE: s3
RCLONE_CONFIG_R2_PROVIDER: Cloudflare
RCLONE_CONFIG_R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
RCLONE_CONFIG_R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
RCLONE_CONFIG_R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }}
RCLONE_CONFIG_R2_ACL: private
run: |
# Install rclone via choco
choco install rclone -y
# Upload binaries to R2
rclone copy ./build/ r2:${{ secrets.R2_BUCKET_NAME }}/libra/releases/${{ github.ref_name }}/ -v
Write-Output "Upload completed for ${{ matrix.component }}-${{ matrix.target.os }}-${{ matrix.target.arch }}"
update-homebrew-tap:
needs: build-and-upload
runs-on: ubuntu-latest
permissions:
contents: read
actions: read
steps:
- name: Download darwin arm64 sha256 artifact
uses: actions/download-artifact@v5
continue-on-error: true
with:
name: homebrew-sha256-darwin-arm64
path: homebrew-sha256/darwin-arm64
- name: Download linux amd64 sha256 artifact
uses: actions/download-artifact@v5
continue-on-error: true
with:
name: homebrew-sha256-linux-amd64
path: homebrew-sha256/linux-amd64
- name: Download linux arm64 sha256 artifact
uses: actions/download-artifact@v5
continue-on-error: true
with:
name: homebrew-sha256-linux-arm64
path: homebrew-sha256/linux-arm64
- name: Update Homebrew tap
shell: bash
env:
HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
GITHUB_REF_NAME: ${{ github.ref_name }}
run: |
set +e
warn() {
local message="$1"
echo "::warning::$message"
{
echo "### Homebrew tap update warning"
echo
echo "$message"
} >> "$GITHUB_STEP_SUMMARY"
}
run_step() {
local description="$1"
shift
"$@"
local status=$?
if [[ $status -ne 0 ]]; then
warn "$description failed with exit code $status."
exit 0
fi
}
if [[ -z "${HOMEBREW_TAP_TOKEN:-}" ]]; then
warn "HOMEBREW_TAP_TOKEN is not configured; skipping Homebrew tap update."
exit 0
fi
run_step "Install GitHub CLI" bash -c 'type gh >/dev/null 2>&1 || (sudo apt-get update && sudo apt-get install -y gh)'
read_sha() {
local path="$1"
local value
value="$(tr -d '[:space:]' < "$path")" || return 1
[[ "$value" =~ ^[0-9a-f]{64}$ ]] || return 1
printf '%s' "$value"
}
darwin_arm64_sha="$(read_sha homebrew-sha256/darwin-arm64/libra-darwin-arm64.sha256)"
if [[ $? -ne 0 ]]; then
warn "darwin arm64 sha256 artifact is missing or invalid."
exit 0
fi
linux_amd64_sha="$(read_sha homebrew-sha256/linux-amd64/libra-linux-amd64.sha256)"
if [[ $? -ne 0 ]]; then
warn "linux amd64 sha256 artifact is missing or invalid."
exit 0
fi
linux_arm64_sha="$(read_sha homebrew-sha256/linux-arm64/libra-linux-arm64.sha256)"
if [[ $? -ne 0 ]]; then
warn "linux arm64 sha256 artifact is missing or invalid."
exit 0
fi
export GH_TOKEN="$HOMEBREW_TAP_TOKEN"
run_step "Configure GitHub CLI git authentication" gh auth setup-git
run_step "Checkout homebrew-libra tap" gh repo clone libra-tools/homebrew-libra homebrew-libra
cd homebrew-libra || {
warn "homebrew-libra checkout directory was not created."
exit 0
}
run_step "Update Homebrew formula" scripts/update-formula.sh "$GITHUB_REF_NAME" "$darwin_arm64_sha" "$linux_amd64_sha" "$linux_arm64_sha"
grep -q "version \"${GITHUB_REF_NAME#v}\"" Formula/libra.rb &&
grep -q "https://download.libra.tools/libra/releases/${GITHUB_REF_NAME}/libra-darwin-arm64" Formula/libra.rb &&
grep -q "https://download.libra.tools/libra/releases/${GITHUB_REF_NAME}/libra-linux-amd64" Formula/libra.rb &&
grep -q "https://download.libra.tools/libra/releases/${GITHUB_REF_NAME}/libra-linux-arm64" Formula/libra.rb
if [[ $? -ne 0 ]]; then
warn "Formula/libra.rb did not contain the expected version and CDN URLs after update."
exit 0
fi
if git diff --quiet -- Formula/libra.rb; then
{
echo "### Homebrew tap update"
echo
echo "Formula/libra.rb already matches ${GITHUB_REF_NAME}."
} >> "$GITHUB_STEP_SUMMARY"
exit 0
fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
run_step "Commit Homebrew formula update" git commit -am "Update libra formula to ${GITHUB_REF_NAME}"
run_step "Push Homebrew formula update" git push origin HEAD
{
echo "### Homebrew tap update"
echo
echo "Updated Formula/libra.rb for ${GITHUB_REF_NAME}."
} >> "$GITHUB_STEP_SUMMARY"
verify-homebrew-formula:
needs: update-homebrew-tap
runs-on: macos-latest
steps:
- name: Install and verify Homebrew formula
shell: bash
env:
GITHUB_REF_NAME: ${{ github.ref_name }}
run: |
set +e
warn() {
local message="$1"
echo "::warning::$message"
{
echo "### Homebrew formula verification warning"
echo
echo "$message"
} >> "$GITHUB_STEP_SUMMARY"
}
if ! brew tap libra-tools/libra; then
warn "Failed to tap libra-tools/libra; skipping Homebrew formula verification."
exit 0
fi
if ! brew install libra-tools/libra/libra; then
warn "Failed to install libra-tools/libra/libra; skipping version verification."
exit 0
fi
if ! actual_version="$(libra --version 2>&1)"; then
warn "The installed libra binary failed to report its version."
exit 0
fi
expected_version="libra ${GITHUB_REF_NAME#v}"
if [[ "$actual_version" != "$expected_version" ]]; then
warn "Installed version '$actual_version' does not match expected version '$expected_version'."
exit 0
fi
{
echo "### Homebrew formula verification"
echo
echo "Verified $expected_version from libra-tools/libra."
} >> "$GITHUB_STEP_SUMMARY"