1+ # Jobs run in parallel by default (no `needs:` between backend/frontend/contract).
2+ # Only db-backup-drill and wasm-size have explicit sequencing requirements.
3+ #
4+ # Parallelism layout:
5+ # backend ──────────────────────────────────────────────────────┐
6+ # backend-migrations ──────────────────────────────────────────┐ │
7+ # frontend ──────────────────────────────────────────────────┐ │ │
8+ # contract ──────────────────────────────────────────────┐ │ │ │
9+ # │ │ │ │
10+ # wasm-size (needs: contract) ──────────────────────────►│ │ │ │
11+ # db-backup-drill (needs: backend-migrations) ──────────►│ │ │ │
12+ # ci-gate (needs: all) ─────────────────────────────────►└───┘─┘─┘
113name : CI
214
315on :
5769 cache : ' npm'
5870 cache-dependency-path : backend/package-lock.json
5971
72+ - name : Check package-lock is up to date
73+ run : |
74+ npm install --package-lock-only --ignore-scripts
75+ git diff --exit-code package-lock.json || {
76+ echo "::error::package-lock.json is out of sync with package.json. Run 'npm install' locally and commit the updated lockfile."
77+ exit 1
78+ }
79+ working-directory : backend
80+
6081 - name : Install dependencies
6182 run : npm ci
6283 working-directory : backend
@@ -152,6 +173,15 @@ jobs:
152173 cache : ' npm'
153174 cache-dependency-path : frontend/package-lock.json
154175
176+ - name : Check package-lock is up to date
177+ run : |
178+ npm install --package-lock-only --ignore-scripts
179+ git diff --exit-code package-lock.json || {
180+ echo "::error::package-lock.json is out of sync with package.json. Run 'npm install' locally and commit the updated lockfile."
181+ exit 1
182+ }
183+ working-directory : frontend
184+
155185 - name : Install dependencies
156186 run : npm ci
157187 working-directory : frontend
@@ -252,9 +282,12 @@ jobs:
252282 ${{ runner.os }}-contract-target-
253283
254284 - name : Install toolchain
255- run : rustup component add rustfmt clippy
285+ run : rustup component add rustfmt clippy llvm-tools-preview
256286 working-directory : contract
257287
288+ - name : Install cargo-llvm-cov
289+ uses : taiki-e/install-action@cargo-llvm-cov
290+
258291 - name : Check formatting
259292 run : cargo fmt --check
260293 working-directory : contract
@@ -263,8 +296,23 @@ jobs:
263296 run : cargo clippy --all-targets --all-features
264297 working-directory : contract
265298
266- - name : Run tests
267- run : cargo test --all-features
299+ - name : Run tests with coverage
300+ run : cargo llvm-cov --all-features --lcov --output-path lcov.info
301+ working-directory : contract
302+
303+ - name : Upload coverage report
304+ uses : actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
305+ with :
306+ name : contract-coverage-lcov
307+ path : contract/lcov.info
308+ retention-days : 30
309+ if-no-files-found : error
310+
311+ - name : Write coverage summary
312+ run : |
313+ echo "## Contract Coverage" >> $GITHUB_STEP_SUMMARY
314+ echo "" >> $GITHUB_STEP_SUMMARY
315+ cargo llvm-cov report --summary-only 2>&1 | tail -5 >> $GITHUB_STEP_SUMMARY
268316 working-directory : contract
269317
270318 - name : Build
@@ -358,3 +406,24 @@ jobs:
358406 done < <(find "$WASM_DIR" -maxdepth 1 -name '*.wasm' -print0 | sort -z)
359407 TOTAL_KIB=$(echo "scale=1; $TOTAL / 1024" | bc)
360408 echo "| **TOTAL** | **$TOTAL** | **$TOTAL_KIB** |" >> $GITHUB_STEP_SUMMARY
409+
410+ # Single required status check for branch protection.
411+ # All parallel jobs must pass before a PR can merge.
412+ ci-gate :
413+ name : CI Gate
414+ runs-on : ubuntu-latest
415+ if : always()
416+ needs :
417+ - backend
418+ - backend-migrations
419+ - frontend
420+ - contract
421+ - wasm-size
422+ - db-backup-drill
423+ steps :
424+ - name : Check all jobs passed
425+ run : |
426+ results='${{ toJSON(needs) }}'
427+ echo "$results" | grep -q '"result": "failure"' && exit 1
428+ echo "$results" | grep -q '"result": "cancelled"' && exit 1
429+ echo "All parallel jobs passed."
0 commit comments