Skip to content

Commit 3c90de3

Browse files
authored
Merge pull request #174 from Damidesign/cipipeline
ci pipeline workflow
2 parents e0eaeee + cbc1a46 commit 3c90de3

1 file changed

Lines changed: 89 additions & 118 deletions

File tree

.github/workflows/ci.yml

Lines changed: 89 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@ name: CI
22

33
on:
44
push:
5-
branches: [main, "feat/**", "fix/**"]
5+
branches:
6+
- main
67
pull_request:
8+
branches:
9+
- main
710

8-
env:
9-
CARGO_TERM_COLOR: always
11+
permissions:
12+
contents: read
1013

1114
jobs:
1215
# ── Soroban ABI golden-vector drift guard ────────────────────────────────
@@ -46,58 +49,73 @@ jobs:
4649
contract:
4750
name: Contract (Rust / Soroban)
4851
runs-on: ubuntu-latest
49-
env:
50-
RUSTFLAGS: "-D warnings"
5152
steps:
5253
- uses: actions/checkout@v4
53-
54-
- uses: dtolnay/rust-toolchain@stable
55-
with:
56-
targets: wasm32-unknown-unknown
57-
components: rustfmt, clippy
58-
59-
- uses: actions/cache@v4
54+
- uses: actions/setup-node@v4
6055
with:
61-
path: |
62-
~/.cargo/registry
63-
~/.cargo/git
64-
target
65-
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
66-
67-
- run: cargo fmt --all -- --check
68-
- run: cargo clippy --target wasm32-unknown-unknown --release -- -D warnings
69-
- run: cargo test
70-
- run: cargo build --target wasm32-unknown-unknown --release
71-
72-
- name: Record wasm SHA-256
73-
run: sha256sum target/wasm32-unknown-unknown/release/niffyinsure.wasm | tee niffyinsure.wasm.sha256
74-
75-
- name: Simulate wasm drift (staging acceptance test)
56+
node-version: '20'
57+
- name: Determine package manager
58+
id: pkgmgr
7659
run: |
77-
ACTUAL=$(cat niffyinsure.wasm.sha256 | awk '{print $1}')
78-
EXPECTED=$(jq -r '.contracts[0].expectedWasmHash' contracts/deployment-registry.json)
79-
# In CI the registry holds a placeholder; drift is detected when they differ.
80-
# In staging, set NIFFYINSURE_EXPECTED_WASM_HASH to a known-wrong value to
81-
# verify the alert path fires. Exit 0 here — alerting is runtime, not build-time.
82-
if [ "$EXPECTED" = "\${NIFFYINSURE_EXPECTED_WASM_HASH}" ]; then
83-
echo "Registry uses env placeholder — skipping drift comparison in CI"
84-
elif [ "$ACTUAL" != "$EXPECTED" ]; then
85-
echo "::warning::Wasm drift detected: expected=$EXPECTED actual=$ACTUAL"
60+
if [ -f pnpm-lock.yaml ]; then
61+
echo "manager=pnpm" >> "$GITHUB_OUTPUT"
62+
elif [ -f package-lock.json ]; then
63+
echo "manager=npm" >> "$GITHUB_OUTPUT"
64+
elif [ -f yarn.lock ]; then
65+
echo "manager=yarn" >> "$GITHUB_OUTPUT"
8666
else
87-
echo "Wasm hash matches registry: $ACTUAL"
67+
echo "manager=npm" >> "$GITHUB_OUTPUT"
8868
fi
89-
90-
- uses: actions/upload-artifact@v4
69+
- name: Setup pnpm when needed
70+
if: steps.pkgmgr.outputs.manager == 'pnpm'
71+
uses: pnpm/action-setup@v2
72+
with:
73+
version: 8
74+
- name: Cache node modules
75+
uses: actions/cache@v4
9176
with:
92-
name: niffyinsure-wasm-${{ github.sha }}
9377
path: |
94-
target/wasm32-unknown-unknown/release/niffyinsure.wasm
95-
niffyinsure.wasm.sha256
96-
retention-days: 30
78+
node_modules
79+
~/.pnpm-store
80+
key: ${{ runner.os }}-node-${{ steps.pkgmgr.outputs.manager }}-${{ hashFiles('**/package-lock.json', '**/pnpm-lock.yaml', '**/yarn.lock') }}
81+
restore-keys: ${{ runner.os }}-node-${{ steps.pkgmgr.outputs.manager }}-
82+
- name: Cache .next cache
83+
uses: actions/cache@v4
84+
with:
85+
path: .next/cache
86+
key: ${{ runner.os }}-next-cache-${{ hashFiles('**/package-lock.json', '**/pnpm-lock.yaml', '**/yarn.lock') }}
87+
restore-keys: ${{ runner.os }}-next-cache-
88+
- name: Install dependencies
89+
run: |
90+
if [ "${{ steps.pkgmgr.outputs.manager }}" = "pnpm" ]; then
91+
pnpm install --frozen-lockfile
92+
else
93+
npm ci
94+
fi
95+
- name: Lint (fail on warnings)
96+
run: |
97+
if [ "${{ steps.pkgmgr.outputs.manager }}" = "pnpm" ]; then
98+
pnpm eslint --max-warnings=0 .
99+
else
100+
npm run lint -- --max-warnings=0
101+
fi
102+
- name: TypeScript compile
103+
run: |
104+
if [ "${{ steps.pkgmgr.outputs.manager }}" = "pnpm" ]; then
105+
pnpm tsc --noEmit
106+
else
107+
npm run build --if-present -- --noEmit
108+
fi
109+
- name: Build
110+
run: |
111+
if [ "${{ steps.pkgmgr.outputs.manager }}" = "pnpm" ]; then
112+
pnpm build
113+
else
114+
npm run build
115+
fi
97116
98-
# ── Backend ───────────────────────────────────────────────────────────────
99-
backend:
100-
name: Backend (Node / TypeScript)
117+
unit-tests:
118+
name: Unit tests
101119
runs-on: ubuntu-latest
102120
defaults:
103121
run:
@@ -121,82 +139,35 @@ jobs:
121139
122140
- uses: actions/setup-node@v4
123141
with:
124-
node-version: 22
125-
126-
- run: npm install
127-
- run: npm run lint
128-
- run: npm run build
129-
- run: npm test
130-
131-
# ── Dependency audit / supply-chain ─────────────────────────────────────
132-
# Policy: CRITICAL CVEs fail the build. HIGH CVEs produce a warning and
133-
# must be triaged within 7 days. Accepted risks require a signed-off entry
134-
# in docs/ops/audit-exceptions.md before the override label is applied.
135-
# Override process:
136-
# 1. Engineer opens a PR adding the CVE to audit-exceptions.md with
137-
# justification, mitigations, and a review-by date.
138-
# 2. A second engineer approves the PR.
139-
# 3. Add the GitHub label `audit-exception-approved` to the failing PR.
140-
# 4. Re-run this job — it will pass once the exception is documented.
141-
dependency-audit:
142-
name: Dependency Audit (npm / SBOM)
142+
node-version: '20'
143+
- name: Install dependencies
144+
run: npm ci
145+
- name: Run unit tests
146+
run: npm test
147+
148+
e2e-tests:
149+
name: Playwright E2E tests
143150
runs-on: ubuntu-latest
151+
needs: quality-build
144152
steps:
145153
- uses: actions/checkout@v4
146-
147154
- uses: actions/setup-node@v4
148155
with:
149-
node-version: 22
150-
151-
- name: Audit backend dependencies
152-
working-directory: backend
153-
run: |
154-
npm install --ignore-scripts
155-
# Fail on critical; warn on high (exit 0 so we can capture output)
156-
npm audit --audit-level=critical
157-
npm audit --audit-level=high || echo "::warning::High-severity advisories found — triage within 7 days per audit policy"
158-
159-
- name: Audit frontend dependencies
160-
working-directory: frontend
161-
run: |
162-
npm ci --ignore-scripts
163-
npm audit --audit-level=critical
164-
npm audit --audit-level=high || echo "::warning::High-severity advisories found — triage within 7 days per audit policy"
165-
166-
- name: Generate SBOM (backend)
167-
working-directory: backend
168-
run: npx --yes @cyclonedx/cyclonedx-npm --output-format JSON --output-file ../sbom-backend.json
169-
170-
- name: Generate SBOM (frontend)
171-
working-directory: frontend
172-
run: npx --yes @cyclonedx/cyclonedx-npm --output-format JSON --output-file ../sbom-frontend.json
173-
174-
- uses: actions/upload-artifact@v4
156+
node-version: '20'
157+
- name: Install dependencies
158+
run: npm ci
159+
- name: Install Playwright browsers
160+
run: npx playwright install --with-deps
161+
- name: Run Playwright tests
162+
run: npx playwright test --reporter=html
163+
continue-on-error: true
164+
- name: Upload Playwright artifacts on failure
165+
if: failure()
166+
uses: actions/upload-artifact@v3
175167
with:
176-
name: sbom-${{ github.sha }}
168+
name: playwright-failure-${{ github.run_id }}
177169
path: |
178-
sbom-backend.json
179-
sbom-frontend.json
180-
retention-days: 90
181-
182-
# ── Frontend ──────────────────────────────────────────────────────────────
183-
frontend:
184-
name: Frontend (Next.js / TypeScript)
185-
runs-on: ubuntu-latest
186-
defaults:
187-
run:
188-
working-directory: frontend
189-
steps:
190-
- uses: actions/checkout@v4
191-
192-
- uses: actions/setup-node@v4
193-
with:
194-
node-version: 22
195-
cache: npm
196-
cache-dependency-path: frontend/package-lock.json
197-
198-
- run: npm ci
199-
- run: npm run lint
200-
- run: npm run check-docs
201-
- run: npm run build
202-
- run: npm test
170+
test-results
171+
playwright-report
172+
traces
173+
.playwright/traces

0 commit comments

Comments
 (0)