Skip to content

Commit d1be1bc

Browse files
committed
ci(stack): fail loudly when CipherStash live-test secrets are missing
The live suites gate themselves on CS_WORKSPACE_CRN / CS_CLIENT_ID / CS_CLIENT_KEY / CS_CLIENT_ACCESS_KEY (vitest `describe.skip`, Deno `test.ignore`). If any secret is unset, rotated, or absent (e.g. a fork PR), those suites silently skip and CI goes green with ZERO live encryption coverage — no signal that the whole v3 live matrix never ran. Add a `require-cs-secrets` local composite action that asserts all four vars are present and fails the job otherwise, and wire it into every credential-dependent job: - tests.yml: run-tests, e2e-tests, wasm-e2e-tests - prisma-next-e2e.yml - prisma-example-readme-e2e.yml The wasm-e2e-tests job already had an inline version of this guard; it's now folded into the shared action so the check lives in one place. Note: run-tests-bun is intentionally left unguarded — it is `continue-on-error: true` (and runs vitest with `|| true`), so a guard there could not fail CI regardless.
1 parent 63ca540 commit d1be1bc

4 files changed

Lines changed: 95 additions & 13 deletions

File tree

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Require CipherStash secrets
2+
description: >-
3+
Fail the job when any CS_* credential is missing. The live test suites gate
4+
themselves on these vars (vitest `describe.skip`, Deno `test.ignore`), so a
5+
rotated / cleared / fork-PR-absent secret would make them silently skip and
6+
let CI go green with ZERO live coverage. This turns that silent skip into a
7+
loud failure. Requires the repo to be checked out first (local action path).
8+
9+
inputs:
10+
workspace-crn:
11+
description: secrets.CS_WORKSPACE_CRN
12+
required: true
13+
client-id:
14+
description: secrets.CS_CLIENT_ID
15+
required: true
16+
client-key:
17+
description: secrets.CS_CLIENT_KEY
18+
required: true
19+
client-access-key:
20+
description: secrets.CS_CLIENT_ACCESS_KEY
21+
required: true
22+
23+
runs:
24+
using: composite
25+
steps:
26+
- name: Assert CS_* secrets are present
27+
shell: bash
28+
env:
29+
CS_WORKSPACE_CRN: ${{ inputs.workspace-crn }}
30+
CS_CLIENT_ID: ${{ inputs.client-id }}
31+
CS_CLIENT_KEY: ${{ inputs.client-key }}
32+
CS_CLIENT_ACCESS_KEY: ${{ inputs.client-access-key }}
33+
run: |
34+
missing=0
35+
for v in CS_WORKSPACE_CRN CS_CLIENT_ID CS_CLIENT_KEY CS_CLIENT_ACCESS_KEY; do
36+
if [ -z "${!v}" ]; then
37+
echo "::error::Required secret $v is not set on this runner — live test suites would silently skip."
38+
missing=1
39+
fi
40+
done
41+
if [ "$missing" -ne 0 ]; then
42+
exit 1
43+
fi

.github/workflows/prisma-example-readme-e2e.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,16 @@ jobs:
6565
- name: Install dependencies
6666
run: pnpm install --frozen-lockfile
6767

68+
# A missing / rotated / fork-PR-absent secret makes the walkthrough skip
69+
# its live steps silently, hiding regressions behind a green job. Fail loud.
70+
- name: Require CipherStash secrets
71+
uses: ./.github/actions/require-cs-secrets
72+
with:
73+
workspace-crn: ${{ secrets.CS_WORKSPACE_CRN }}
74+
client-id: ${{ secrets.CS_CLIENT_ID }}
75+
client-key: ${{ secrets.CS_CLIENT_KEY }}
76+
client-access-key: ${{ secrets.CS_CLIENT_ACCESS_KEY }}
77+
6878
# Build via turbo so `^build` on `@cipherstash/prisma-next` and
6979
# its `@cipherstash/stack` peer is honoured. The test's
7080
# `pnpm install` subprocess inside `examples/prisma/` is a no-op

.github/workflows/prisma-next-e2e.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,17 @@ jobs:
6767
- name: Install dependencies
6868
run: pnpm install --frozen-lockfile
6969

70+
# The global-setup hook hard-errors without CS_WORKSPACE_CRN, but a
71+
# missing sibling secret could still degrade coverage silently — assert
72+
# all four up front so a rotated / fork-PR-absent secret fails loudly.
73+
- name: Require CipherStash secrets
74+
uses: ./.github/actions/require-cs-secrets
75+
with:
76+
workspace-crn: ${{ secrets.CS_WORKSPACE_CRN }}
77+
client-id: ${{ secrets.CS_CLIENT_ID }}
78+
client-key: ${{ secrets.CS_CLIENT_KEY }}
79+
client-access-key: ${{ secrets.CS_CLIENT_ACCESS_KEY }}
80+
7081
# Write the CS_* credentials and the harness DATABASE_URL into the
7182
# example app's .env so the runtime + the `prisma-next migration
7283
# apply` invocation in global-setup both pick them up. The harness

.github/workflows/tests.yml

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,16 @@ jobs:
5959
- name: Install dependencies
6060
run: pnpm install --frozen-lockfile
6161

62+
# Fail loudly if any live-test credential is missing, so the v3 live
63+
# matrix (and every other `describeLive` suite) can't silently skip.
64+
- name: Require CipherStash secrets
65+
uses: ./.github/actions/require-cs-secrets
66+
with:
67+
workspace-crn: ${{ secrets.CS_WORKSPACE_CRN }}
68+
client-id: ${{ secrets.CS_CLIENT_ID }}
69+
client-key: ${{ secrets.CS_CLIENT_KEY }}
70+
client-access-key: ${{ secrets.CS_CLIENT_ACCESS_KEY }}
71+
6272
- name: Type tests (stack)
6373
run: pnpm --filter @cipherstash/stack run test:types
6474

@@ -152,6 +162,16 @@ jobs:
152162
- name: Install dependencies
153163
run: pnpm install --frozen-lockfile
154164

165+
# Auth-dependent `e2e/` suites skip themselves without these vars — a
166+
# silent skip would hide regressions behind a green job. Fail loudly.
167+
- name: Require CipherStash secrets
168+
uses: ./.github/actions/require-cs-secrets
169+
with:
170+
workspace-crn: ${{ secrets.CS_WORKSPACE_CRN }}
171+
client-id: ${{ secrets.CS_CLIENT_ID }}
172+
client-key: ${{ secrets.CS_CLIENT_KEY }}
173+
client-access-key: ${{ secrets.CS_CLIENT_ACCESS_KEY }}
174+
155175
# Run the standalone `e2e/` workspace via turbo so the `^build`
156176
# dep on the `test:e2e` task builds cli + wizard first. CLI's own
157177
# E2E (`packages/cli/tests/e2e/**`) is covered by the `run-tests`
@@ -219,19 +239,17 @@ jobs:
219239
- name: Build stack
220240
run: pnpm exec turbo run build --filter @cipherstash/stack
221241

222-
# roundtrip.test.ts skips itself (Deno.test.ignore) when any of
223-
# the four CS_* env vars is missing — that's the right behaviour
224-
# for local runs, but in CI a silent skip would mean a rotated /
225-
# cleared secret hides a real WASM regression behind a green job.
226-
# Fail loudly instead.
227-
- name: Assert CS_* secrets are present
228-
run: |
229-
for v in CS_WORKSPACE_CRN CS_CLIENT_ID CS_CLIENT_KEY CS_CLIENT_ACCESS_KEY; do
230-
if [ -z "${!v}" ]; then
231-
echo "::error::Required secret $v is not set on this runner — the WASM smoke test would silently skip."
232-
exit 1
233-
fi
234-
done
242+
# roundtrip.test.ts skips itself (Deno.test.ignore) when any of the four
243+
# CS_* env vars is missing — fine locally, but in CI a silent skip would
244+
# let a rotated / cleared secret hide a real WASM regression behind a
245+
# green job. Fail loudly instead.
246+
- name: Require CipherStash secrets
247+
uses: ./.github/actions/require-cs-secrets
248+
with:
249+
workspace-crn: ${{ secrets.CS_WORKSPACE_CRN }}
250+
client-id: ${{ secrets.CS_CLIENT_ID }}
251+
client-key: ${{ secrets.CS_CLIENT_KEY }}
252+
client-access-key: ${{ secrets.CS_CLIENT_ACCESS_KEY }}
235253

236254
- name: Run Deno WASM smoke test
237255
working-directory: e2e/wasm

0 commit comments

Comments
 (0)