-
Notifications
You must be signed in to change notification settings - Fork 0
313 lines (270 loc) · 9.49 KB
/
rust.yml
File metadata and controls
313 lines (270 loc) · 9.49 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
name: CI
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
on:
push:
branches: [main]
paths:
- 'src/**'
- 'Cargo.toml'
- 'Cargo.lock'
- 'BUILD.bazel'
- 'MODULE.bazel'
- '.github/workflows/rust.yml'
pull_request:
paths:
- 'src/**'
- 'Cargo.toml'
- 'Cargo.lock'
- 'BUILD.bazel'
- 'MODULE.bazel'
- '.github/workflows/rust.yml'
env:
CARGO_TERM_COLOR: always
RUST_VERSION: "1.90.0"
jobs:
build-matrix:
name: ${{ matrix.build-system }} on ${{ matrix.os }}
# Stays on ubuntu-latest: matrix includes macos-latest and bazel build-system uses cachix/install-nix-action; smithy is Linux-only and doesn't ship Nix or Bazel.
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
build-system: [cargo, bazel]
steps:
- name: Checkout code
uses: actions/checkout@v4
# Cargo build and test
- name: Cargo Build
if: matrix.build-system == 'cargo'
run: cargo build --verbose
- name: Cargo Test
if: matrix.build-system == 'cargo'
run: cargo test --verbose
- name: Build Examples
if: matrix.build-system == 'cargo'
run: |
echo "Building Wasmtime integration example"
cd examples/wasmtime-loader
cargo build --release --verbose
- name: Test Wasmtime Example
if: matrix.build-system == 'cargo'
run: |
echo "Testing Wasmtime integration example"
cd examples/wasmtime-loader
# Test: Verify binary runs and shows help
cargo run --release -- --help
# Bazel setup and builds
- name: Install Nix
if: matrix.build-system == 'bazel'
uses: cachix/install-nix-action@v30
with:
nix_path: nixpkgs=channel:nixos-unstable
- name: Setup Bazel
if: matrix.build-system == 'bazel'
uses: bazel-contrib/setup-bazel@0.15.0
with:
bazelisk-cache: true
disk-cache: ${{ runner.os }}-bazel
repository-cache: true
- name: Build Core Library (Bazel)
if: matrix.build-system == 'bazel'
run: bazel build //src/lib:wsc
- name: Build Signing Component (Bazel)
if: matrix.build-system == 'bazel'
run: bazel build //src/component:signing_lib
- name: Build CLI Component (Bazel)
if: matrix.build-system == 'bazel'
run: bazel build //src/cli:wasmsign_cli
# Audit 2026-04-30 finding C-7 (partial): Bazel CI now ATTEMPTS to
# run tests, not just validate that targets compile. continue-on-error
# is retained because (a) macOS Bazel toolchain has unrelated issues
# observed in this batch and (b) `bazel test //...` exposes test
# targets that may be platform-specific. Once the macOS bazel-test
# baseline is green for one full week, lift this mask.
- name: Test (Bazel)
if: matrix.build-system == 'bazel'
run: bazel test --build_tests_only --test_output=errors //src/...
continue-on-error: true # WIP — see audit C-7 partial closure
- name: Validate Build Outputs (Bazel)
if: matrix.build-system == 'bazel'
run: |
echo "✅ Querying build outputs:"
# Query actual output files for each target
echo "Component library outputs:"
bazel cquery //src/component:signing_lib --output=files 2>/dev/null || echo " (query failed)"
echo "CLI binary outputs:"
bazel cquery //src/cli:wasmsign_cli --output=files 2>/dev/null || echo " (query failed)"
# List what's actually in bazel-bin
echo ""
echo "Contents of bazel-bin/src/component/:"
ls -lh bazel-bin/src/component/ 2>/dev/null || echo " (directory not found)"
echo ""
echo "Contents of bazel-bin/src/cli/:"
ls -lh bazel-bin/src/cli/ 2>/dev/null || echo " (directory not found)"
# Find any WASM files (if built with --platforms flag)
echo ""
echo "Searching for WASM files:"
find bazel-bin -name "*.wasm" -type f 2>/dev/null | while read wasm_file; do
echo " Found: $wasm_file"
file "$wasm_file"
done || echo " (no .wasm files found - native build only)"
- name: Upload Build Artifacts (Bazel)
if: matrix.build-system == 'bazel'
uses: actions/upload-artifact@v4
with:
name: bazel-outputs-${{ matrix.os }}
path: |
bazel-bin/src/component/**/*
bazel-bin/src/cli/**/*
!bazel-bin/**/*.d
!bazel-bin/**/*.rlib
retention-days: 7
if-no-files-found: warn
# Integration tests for keyless signing (requires OIDC)
keyless-integration:
name: Keyless Integration Tests
runs-on: [self-hosted, linux, x64, rust-cpu]
permissions:
id-token: write # Required for OIDC token
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Keyless Integration Tests
run: cargo test --test keyless_integration -- --ignored --nocapture
env:
RUST_LOG: debug
# Air-gapped verification end-to-end tests
airgapped-e2e:
name: Air-Gapped E2E Tests
runs-on: [self-hosted, linux, x64, rust-cpu]
permissions:
id-token: write # Required for OIDC token
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Air-Gapped Unit Tests
run: cargo test --test airgapped_e2e -- --nocapture
env:
RUST_LOG: info
- name: Run Air-Gapped Integration Tests (with OIDC)
run: cargo test --test airgapped_e2e -- --ignored --nocapture
env:
RUST_LOG: debug
# Example: Sign a WASM module and verify with air-gapped flow
sign-and-verify-example:
name: Sign & Verify Example
runs-on: [self-hosted, linux, x64, rust-cpu]
permissions:
id-token: write
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Build CLI
run: cargo build --release
- name: Generate bundle signing keypair
run: |
./target/release/wsc keygen -k /tmp/bundle-sk.key -K /tmp/bundle-pk.key
echo "Generated bundle signing keypair"
- name: Fetch and sign trust bundle from Sigstore
run: |
./target/release/wsc bundle fetch \
-o /tmp/trust-bundle.json \
--version 1 \
--validity-days 90 \
--sign /tmp/bundle-sk.key
echo "Fetched and signed trust bundle"
- name: Inspect trust bundle
run: ./target/release/wsc bundle inspect -i /tmp/trust-bundle.json
- name: Verify trust bundle signature
run: |
./target/release/wsc bundle verify \
-i /tmp/trust-bundle.json \
-K /tmp/bundle-pk.key
echo "Trust bundle signature verified"
- name: Create test WASM module
run: |
# Create a minimal valid WASM module
printf '\x00\x61\x73\x6d\x01\x00\x00\x00' > /tmp/test.wasm
echo "Created test WASM module"
- name: Sign WASM with keyless signing
run: |
./target/release/wsc sign --keyless \
-i /tmp/test.wasm \
-o /tmp/test-signed.wasm
echo "Signed WASM module with keyless signing"
- name: Verify keyless signature
run: |
./target/release/wsc verify --keyless \
-i /tmp/test-signed.wasm
echo "Verified keyless signature"
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: signed-wasm-artifacts
path: |
/tmp/trust-bundle.json
/tmp/bundle-pk.key
/tmp/test-signed.wasm
retention-days: 7
# Rekor verification tests with fresh data
rekor-verification:
name: Rekor Verification Tests (Fresh Data)
runs-on: [self-hosted, linux, x64, rust-cpu]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Fetch Fresh Rekor Data
id: update-rekor
run: |
./scripts/update-rekor-test-data.sh > rekor-data.txt 2>&1
echo "✅ Fetched fresh Rekor test data"
- name: Run Rekor Verification Tests
# Continue even if tests fail - data might be stale or API unavailable
continue-on-error: true
run: |
echo "📝 Note: These tests use hardcoded data and may fail if not recently updated"
cargo test signature::keyless::rekor_verifier::tests -- --ignored --nocapture
env:
RUST_LOG: debug
- name: Upload Rekor Data (on failure)
if: failure()
uses: actions/upload-artifact@v4
with:
name: rekor-fresh-data
path: rekor-data.txt
retention-days: 7
coverage:
name: Code Coverage
needs: [build-matrix]
runs-on: [self-hosted, linux, x64, rust-cpu]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
- uses: Swatinem/rust-cache@v2
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@v2
with:
tool: cargo-llvm-cov
- name: Generate coverage (LCOV + HTML)
run: |
cargo llvm-cov -p wsc --lcov --output-path lcov.info
cargo llvm-cov -p wsc --html --output-dir coverage-html
- name: Upload LCOV to Codecov
if: env.CODECOV_TOKEN != ''
uses: codecov/codecov-action@v4
with:
files: lcov.info
fail_ci_if_error: false
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- name: Upload HTML coverage report
uses: actions/upload-artifact@v4
with:
name: coverage-html
path: coverage-html/