Skip to content

Commit a2bcbcf

Browse files
committed
refactor: use Docker mock server from GHCR instead of fetching spec
CI starts ghcr.io/nimbleway/sdk-mock-server (Prism + spec) as a container, then runs tests against it. setup.ts detects if Prism is already running (Docker case) or starts it locally (dev case with fetched spec).
1 parent 28b9459 commit a2bcbcf

2 files changed

Lines changed: 45 additions & 3 deletions

File tree

.github/workflows/ci.yml

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,12 @@ jobs:
125125
contract-tests:
126126
timeout-minutes: 10
127127
name: contract tests
128-
runs-on: ${{ github.repository == 'stainless-sdks/nimbleway-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
128+
runs-on: ubuntu-latest
129129
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
130130
permissions:
131131
contents: read
132132
pull-requests: write
133+
packages: read
133134
steps:
134135
- uses: actions/checkout@v6
135136

@@ -149,8 +150,19 @@ jobs:
149150
- name: Build SDK
150151
run: ./scripts/build
151152

152-
- name: Fetch OpenAPI spec
153-
run: pnpm --filter sdk-contract-tests run fetch-spec
153+
- name: Log in to GHCR
154+
uses: docker/login-action@v3
155+
with:
156+
registry: ghcr.io
157+
username: ${{ github.actor }}
158+
password: ${{ secrets.GITHUB_TOKEN }}
159+
160+
- name: Start mock server
161+
run: |
162+
docker run -d --name prism-mock -p 4010:4010 \
163+
ghcr.io/nimbleway/sdk-mock-server:latest
164+
timeout 30 bash -c 'until curl -sf http://127.0.0.1:4010/ >/dev/null 2>&1; do sleep 1; done'
165+
echo "Mock server ready"
154166
155167
- name: Run contract tests
156168
id: tests
@@ -167,6 +179,10 @@ jobs:
167179
echo "total=$TOTAL" >> "$GITHUB_OUTPUT"
168180
echo "files=$FILES" >> "$GITHUB_OUTPUT"
169181
182+
- name: Stop mock server
183+
if: always()
184+
run: docker rm -f prism-mock 2>/dev/null || true
185+
170186
- name: Generate coverage reports
171187
if: always() && steps.tests.outcome == 'success'
172188
run: |

contract-tests/src/setup.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,21 @@ const PRISM_BIN = resolve(CONTRACT_TESTS_ROOT, 'node_modules', '.bin', 'prism');
1010
const PRISM_PORT = process.env.PRISM_PORT || '4010';
1111
const SPEC_PATH = process.env.OPENAPI_SPEC_PATH || join(__dirname, '..', 'spec', 'openapi.yaml');
1212

13+
function checkPrism(port: string): Promise<boolean> {
14+
return new Promise((resolve) => {
15+
const req = http.get(`http://127.0.0.1:${port}/`, (res) => {
16+
res.resume();
17+
resolve(true);
18+
});
19+
req.on('error', () => resolve(false));
20+
req.setTimeout(1000, () => {
21+
req.destroy();
22+
resolve(false);
23+
});
24+
req.end();
25+
});
26+
}
27+
1328
function waitForPrism(port: string, timeoutMs = 30_000): Promise<void> {
1429
const start = Date.now();
1530
return new Promise((resolve, reject) => {
@@ -32,8 +47,16 @@ function waitForPrism(port: string, timeoutMs = 30_000): Promise<void> {
3247
}
3348

3449
let prismProcess: ChildProcess | null = null;
50+
let managedByUs = false;
3551

3652
export async function setup() {
53+
const alreadyRunning = await checkPrism(PRISM_PORT);
54+
55+
if (alreadyRunning) {
56+
console.log(`Prism mock server already running on port ${PRISM_PORT} (external/Docker)`);
57+
return;
58+
}
59+
3760
console.log(`Starting Prism mock server on port ${PRISM_PORT}...`);
3861
console.log(`Spec: ${SPEC_PATH}`);
3962

@@ -48,12 +71,15 @@ export async function setup() {
4871
);
4972

5073
prismProcess.unref();
74+
managedByUs = true;
5175

5276
await waitForPrism(PRISM_PORT);
5377
console.log(`Prism mock server ready on http://127.0.0.1:${PRISM_PORT}`);
5478
}
5579

5680
export async function teardown() {
81+
if (!managedByUs) return;
82+
5783
if (prismProcess?.pid) {
5884
try {
5985
process.kill(-prismProcess.pid, 'SIGTERM');

0 commit comments

Comments
 (0)