zuplo 7.4.4 → 7.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/articles/ci-cd-azure/local-testing.mdx +22 -4
- package/docs/articles/ci-cd-bitbucket/local-testing.mdx +22 -4
- package/docs/articles/ci-cd-circleci/local-testing.mdx +21 -4
- package/docs/articles/ci-cd-github/deploy-and-test.mdx +28 -13
- package/docs/articles/ci-cd-github/local-testing.mdx +36 -16
- package/docs/articles/ci-cd-gitlab/local-testing.mdx +22 -4
- package/docs/articles/github-deployment-testing.mdx +118 -31
- package/docs/articles/testing-getting-started.mdx +220 -0
- package/docs/articles/testing-preview-environments.mdx +148 -0
- package/docs/articles/testing-recipes.mdx +429 -0
- package/docs/articles/testing.mdx +138 -408
- package/docs/mcp-gateway/auth/configuring-auth0.mdx +6 -5
- package/docs/mcp-gateway/auth/configuring-clerk.mdx +4 -4
- package/docs/mcp-gateway/auth/configuring-cognito.mdx +5 -4
- package/docs/mcp-gateway/auth/configuring-entra.mdx +5 -4
- package/docs/mcp-gateway/auth/configuring-generic-oidc.mdx +8 -8
- package/docs/mcp-gateway/auth/configuring-google.mdx +4 -4
- package/docs/mcp-gateway/auth/configuring-keycloak.mdx +4 -3
- package/docs/mcp-gateway/auth/configuring-logto.mdx +4 -4
- package/docs/mcp-gateway/auth/configuring-okta.mdx +3 -3
- package/docs/mcp-gateway/auth/configuring-onelogin.mdx +3 -3
- package/docs/mcp-gateway/auth/configuring-ping.mdx +3 -3
- package/docs/mcp-gateway/auth/configuring-workos.mdx +5 -4
- package/docs/mcp-gateway/auth/manual-oauth-testing.mdx +8 -8
- package/docs/mcp-gateway/auth/overview.mdx +17 -17
- package/docs/mcp-gateway/auth/upstream-oauth.mdx +5 -5
- package/docs/mcp-gateway/code-config/local-development.mdx +14 -12
- package/docs/mcp-gateway/code-config/overview.mdx +9 -4
- package/docs/mcp-gateway/connect-clients/chatgpt.mdx +114 -56
- package/docs/mcp-gateway/how-it-works.mdx +11 -9
- package/docs/mcp-gateway/introduction.mdx +3 -1
- package/docs/mcp-gateway/quickstart-local.mdx +7 -7
- package/docs/mcp-gateway/reference.mdx +58 -25
- package/docs/mcp-gateway/server-registry.mdx +179 -0
- package/docs/mcp-gateway/test-clients.mdx +2 -2
- package/docs/mcp-server/custom-tools.mdx +32 -0
- package/docs/programmable-api/mcp-gateway-plugin.mdx +137 -0
- package/docs/programmable-api/mcp-sdk.mdx +240 -0
- package/docs/self-hosted/overview.md +2 -0
- package/package.json +5 -5
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "Azure Pipelines: Local
|
|
3
|
-
sidebar_label: Local
|
|
2
|
+
title: "Azure Pipelines: Local testing in CI"
|
|
3
|
+
sidebar_label: Local testing in CI
|
|
4
|
+
description:
|
|
5
|
+
Start a local Zuplo dev server inside Azure Pipelines, poll it until it
|
|
6
|
+
answers, run your test suite, and only deploy if every test passes.
|
|
4
7
|
---
|
|
5
8
|
|
|
6
9
|
Test against a local Zuplo server before deploying anywhere.
|
|
@@ -29,7 +32,16 @@ stages:
|
|
|
29
32
|
- script: |
|
|
30
33
|
npx zuplo dev &
|
|
31
34
|
DEV_PID=$!
|
|
32
|
-
sleep
|
|
35
|
+
# Poll until the server answers — never a fixed sleep
|
|
36
|
+
deadline=$((SECONDS + 60))
|
|
37
|
+
until curl --fail --silent --output /dev/null http://localhost:9000/health; do
|
|
38
|
+
if (( SECONDS >= deadline )); then
|
|
39
|
+
echo "Local server did not start within 60s" >&2
|
|
40
|
+
kill $DEV_PID
|
|
41
|
+
exit 1
|
|
42
|
+
fi
|
|
43
|
+
sleep 1
|
|
44
|
+
done
|
|
33
45
|
npx zuplo test --endpoint http://localhost:9000
|
|
34
46
|
kill $DEV_PID
|
|
35
47
|
displayName: "Start local server and run tests"
|
|
@@ -54,6 +66,12 @@ stages:
|
|
|
54
66
|
|
|
55
67
|
Local tests run first. Only if they pass does deployment proceed.
|
|
56
68
|
|
|
57
|
-
|
|
69
|
+
The readiness poll replaces a fixed `sleep`. A sleep is a guess about startup
|
|
70
|
+
time that is wrong in both directions, and it is the most common reason a
|
|
71
|
+
gateway test suite "needs" a retry. The example polls `/health` — add an
|
|
72
|
+
unauthenticated health route if your gateway does not have one. See
|
|
73
|
+
[health checks](../health-checks.mdx).
|
|
74
|
+
|
|
75
|
+
## Next steps
|
|
58
76
|
|
|
59
77
|
- Add [multi-stage deployment](./multi-stage-deployment.mdx) with staging
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "Bitbucket Pipelines: Local
|
|
3
|
-
sidebar_label: Local
|
|
2
|
+
title: "Bitbucket Pipelines: Local testing in CI"
|
|
3
|
+
sidebar_label: Local testing in CI
|
|
4
|
+
description:
|
|
5
|
+
Start a local Zuplo dev server inside Bitbucket Pipelines, poll it until it
|
|
6
|
+
answers, run your test suite, and only deploy if every test passes.
|
|
4
7
|
---
|
|
5
8
|
|
|
6
9
|
Test against a local Zuplo server before deploying anywhere.
|
|
@@ -16,7 +19,16 @@ pipelines:
|
|
|
16
19
|
script:
|
|
17
20
|
- npm install
|
|
18
21
|
- npx zuplo dev &
|
|
19
|
-
|
|
22
|
+
# Poll until the server answers — never a fixed sleep
|
|
23
|
+
- |
|
|
24
|
+
deadline=$((SECONDS + 60))
|
|
25
|
+
until curl --fail --silent --output /dev/null http://localhost:9000/health; do
|
|
26
|
+
if (( SECONDS >= deadline )); then
|
|
27
|
+
echo "Local server did not start within 60s" >&2
|
|
28
|
+
exit 1
|
|
29
|
+
fi
|
|
30
|
+
sleep 1
|
|
31
|
+
done
|
|
20
32
|
- npx zuplo test --endpoint http://localhost:9000
|
|
21
33
|
- kill %1
|
|
22
34
|
|
|
@@ -29,6 +41,12 @@ pipelines:
|
|
|
29
41
|
|
|
30
42
|
Local tests run first. Only if they pass does deployment proceed.
|
|
31
43
|
|
|
32
|
-
|
|
44
|
+
The readiness poll replaces a fixed `sleep`. A sleep is a guess about startup
|
|
45
|
+
time that is wrong in both directions, and it is the most common reason a
|
|
46
|
+
gateway test suite "needs" a retry. The example polls `/health` — add an
|
|
47
|
+
unauthenticated health route if your gateway does not have one. See
|
|
48
|
+
[health checks](../health-checks.mdx).
|
|
49
|
+
|
|
50
|
+
## Next steps
|
|
33
51
|
|
|
34
52
|
- Add [multi-stage deployment](./multi-stage-deployment.mdx) with staging
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "CircleCI: Local
|
|
3
|
-
sidebar_label: Local
|
|
2
|
+
title: "CircleCI: Local testing in CI"
|
|
3
|
+
sidebar_label: Local testing in CI
|
|
4
|
+
description:
|
|
5
|
+
Start a local Zuplo dev server inside CircleCI, poll it until it answers, run
|
|
6
|
+
your test suite, and only deploy if every test passes.
|
|
4
7
|
---
|
|
5
8
|
|
|
6
9
|
Test against a local Zuplo server before deploying anywhere.
|
|
@@ -19,7 +22,15 @@ jobs:
|
|
|
19
22
|
name: Start local server and run tests
|
|
20
23
|
command: |
|
|
21
24
|
npx zuplo dev &
|
|
22
|
-
sleep
|
|
25
|
+
# Poll until the server answers — never a fixed sleep
|
|
26
|
+
deadline=$((SECONDS + 60))
|
|
27
|
+
until curl --fail --silent --output /dev/null http://localhost:9000/health; do
|
|
28
|
+
if (( SECONDS >= deadline )); then
|
|
29
|
+
echo "Local server did not start within 60s" >&2
|
|
30
|
+
exit 1
|
|
31
|
+
fi
|
|
32
|
+
sleep 1
|
|
33
|
+
done
|
|
23
34
|
npx zuplo test --endpoint http://localhost:9000
|
|
24
35
|
kill %1
|
|
25
36
|
|
|
@@ -45,6 +56,12 @@ workflows:
|
|
|
45
56
|
|
|
46
57
|
Local tests run first. Only if they pass does deployment proceed.
|
|
47
58
|
|
|
48
|
-
|
|
59
|
+
The readiness poll replaces a fixed `sleep`. A sleep is a guess about startup
|
|
60
|
+
time that is wrong in both directions, and it is the most common reason a
|
|
61
|
+
gateway test suite "needs" a retry. The example polls `/health` — add an
|
|
62
|
+
unauthenticated health route if your gateway does not have one. See
|
|
63
|
+
[health checks](../health-checks.mdx).
|
|
64
|
+
|
|
65
|
+
## Next steps
|
|
49
66
|
|
|
50
67
|
- Add [multi-stage deployment](./multi-stage-deployment.mdx) with staging
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "GitHub Actions: Deploy and
|
|
3
|
-
sidebar_label: Deploy and
|
|
2
|
+
title: "GitHub Actions: Deploy and test"
|
|
3
|
+
sidebar_label: Deploy and test
|
|
4
|
+
description:
|
|
5
|
+
Deploy to Zuplo from a GitHub Actions workflow, capture the deployment URL,
|
|
6
|
+
and run your test suite against the live environment to validate changes
|
|
7
|
+
before they reach production.
|
|
4
8
|
---
|
|
5
9
|
|
|
6
10
|
Run your test suite against the deployed environment to validate changes before
|
|
@@ -54,42 +58,53 @@ jobs:
|
|
|
54
58
|
|
|
55
59
|
This workflow:
|
|
56
60
|
|
|
57
|
-
1. Deploys to Zuplo and captures the deployment URL
|
|
58
|
-
2. Runs your test suite against the live deployment
|
|
59
|
-
3. Fails the workflow if any tests fail
|
|
61
|
+
1. Deploys to Zuplo and captures the deployment URL.
|
|
62
|
+
2. Runs your test suite against the live deployment.
|
|
63
|
+
3. Fails the workflow if any tests fail.
|
|
60
64
|
|
|
61
65
|
The deploy step passes `--environment` explicitly because this workflow runs on
|
|
62
66
|
both `push` and `pull_request` events. The expression
|
|
63
67
|
`${{ github.head_ref || github.ref_name }}` resolves to the branch name on
|
|
64
68
|
either trigger, so every run for a branch updates the same environment. Without
|
|
65
69
|
it, `pull_request` runs create a second environment named after the PR merge ref
|
|
66
|
-
instead of your branch
|
|
67
|
-
[PR
|
|
70
|
+
instead of your branch. For details, see
|
|
71
|
+
[PR preview environments](./pr-preview-environments.mdx).
|
|
68
72
|
|
|
69
|
-
##
|
|
73
|
+
## Write tests
|
|
74
|
+
|
|
75
|
+
`describe`, `it`, and `TestHelper` come from `@zuplo/test`, which a Zuplo
|
|
76
|
+
project already has through the `zuplo` package. Assertions use
|
|
77
|
+
[chai](https://www.chaijs.com/api/bdd/), which a new project does **not**
|
|
78
|
+
include. Install it first:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npm install --save-dev chai @types/chai
|
|
82
|
+
```
|
|
70
83
|
|
|
71
84
|
Place test files in the `tests` folder with the `.test.ts` extension:
|
|
72
85
|
|
|
73
86
|
```typescript title="tests/api.test.ts"
|
|
74
|
-
import { describe, it } from "@zuplo/test";
|
|
87
|
+
import { describe, it, TestHelper } from "@zuplo/test";
|
|
75
88
|
import { expect } from "chai";
|
|
76
89
|
|
|
77
90
|
describe("API", () => {
|
|
78
91
|
it("returns 200 for health check", async () => {
|
|
79
|
-
const response = await fetch(`${
|
|
92
|
+
const response = await fetch(`${TestHelper.TEST_URL}/health`);
|
|
80
93
|
expect(response.status).to.equal(200);
|
|
81
94
|
});
|
|
82
95
|
|
|
83
96
|
it("requires authentication", async () => {
|
|
84
|
-
const response = await fetch(`${
|
|
97
|
+
const response = await fetch(`${TestHelper.TEST_URL}/protected`);
|
|
85
98
|
expect(response.status).to.equal(401);
|
|
86
99
|
});
|
|
87
100
|
});
|
|
88
101
|
```
|
|
89
102
|
|
|
90
|
-
|
|
103
|
+
`TestHelper.TEST_URL` is the value passed to `--endpoint`, so the same files run
|
|
104
|
+
against every environment. For the full setup, see
|
|
105
|
+
[Get started with zuplo test](../testing-getting-started.mdx).
|
|
91
106
|
|
|
92
|
-
## Next
|
|
107
|
+
## Next steps
|
|
93
108
|
|
|
94
109
|
- Add [PR preview environments](./pr-preview-environments.mdx) with automatic
|
|
95
110
|
cleanup
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "GitHub Actions: Local
|
|
3
|
-
sidebar_label: Local
|
|
2
|
+
title: "GitHub Actions: Local testing in CI"
|
|
3
|
+
sidebar_label: Local testing in CI
|
|
4
|
+
description:
|
|
5
|
+
Start a local Zuplo dev server inside a GitHub Actions workflow, poll it until
|
|
6
|
+
it answers, run your test suite, and only deploy if every test passes.
|
|
4
7
|
---
|
|
5
8
|
|
|
6
9
|
Run tests against a local Zuplo development server before deploying anywhere.
|
|
@@ -35,9 +38,19 @@ jobs:
|
|
|
35
38
|
npx zuplo dev &
|
|
36
39
|
DEV_PID=$!
|
|
37
40
|
|
|
38
|
-
#
|
|
41
|
+
# Poll until the server answers, with a hard deadline. Never use a
|
|
42
|
+
# fixed sleep: it is flaky when the runner is slow and wasted CI
|
|
43
|
+
# minutes when it is fast.
|
|
39
44
|
echo "Waiting for local server to start..."
|
|
40
|
-
|
|
45
|
+
deadline=$((SECONDS + 60))
|
|
46
|
+
until curl --fail --silent --output /dev/null http://localhost:9000/health; do
|
|
47
|
+
if (( SECONDS >= deadline )); then
|
|
48
|
+
echo "Local server did not start within 60s" >&2
|
|
49
|
+
kill $DEV_PID
|
|
50
|
+
exit 1
|
|
51
|
+
fi
|
|
52
|
+
sleep 1
|
|
53
|
+
done
|
|
41
54
|
|
|
42
55
|
# Run tests against local server
|
|
43
56
|
npx zuplo test --endpoint http://localhost:9000
|
|
@@ -71,20 +84,27 @@ jobs:
|
|
|
71
84
|
|
|
72
85
|
This workflow:
|
|
73
86
|
|
|
74
|
-
1. Starts a local Zuplo server in the CI environment
|
|
75
|
-
2.
|
|
76
|
-
3.
|
|
77
|
-
4.
|
|
87
|
+
1. Starts a local Zuplo server in the CI environment.
|
|
88
|
+
2. Polls it until it answers, with a bounded deadline.
|
|
89
|
+
3. Runs your test suite against localhost.
|
|
90
|
+
4. Proceeds to deployment only if local tests pass.
|
|
91
|
+
5. Deploys to Zuplo (only on pushes to main).
|
|
78
92
|
|
|
79
|
-
|
|
93
|
+
The poll replaces a fixed `sleep`. A sleep is a guess about startup time that is
|
|
94
|
+
wrong in both directions, and it is the most common reason a gateway test suite
|
|
95
|
+
"needs" a retry. The example polls `/health` — add an unauthenticated health
|
|
96
|
+
route if your gateway does not have one. See
|
|
97
|
+
[health checks](../health-checks.mdx).
|
|
80
98
|
|
|
81
|
-
|
|
82
|
-
- **Catch syntax errors** — The local server validates your configuration
|
|
83
|
-
- **Test policies** — Verify authentication, rate limiting, and other policies
|
|
84
|
-
work correctly
|
|
85
|
-
- **No wasted deployments** — Don't deploy changes that will fail tests
|
|
99
|
+
## Why test locally first
|
|
86
100
|
|
|
87
|
-
|
|
101
|
+
- **Faster feedback** — local tests run without waiting for deployment.
|
|
102
|
+
- **Catch syntax errors** — the local server validates your configuration.
|
|
103
|
+
- **Test policies** — verify authentication, rate limiting, and other policies
|
|
104
|
+
work correctly.
|
|
105
|
+
- **No wasted deployments** — don't deploy changes that fail tests.
|
|
106
|
+
|
|
107
|
+
## Combine with remote tests
|
|
88
108
|
|
|
89
109
|
For maximum confidence, test both locally and against the deployed environment:
|
|
90
110
|
|
|
@@ -98,7 +118,7 @@ jobs:
|
|
|
98
118
|
# ... deploy and run tests against live environment ...
|
|
99
119
|
```
|
|
100
120
|
|
|
101
|
-
## Next
|
|
121
|
+
## Next steps
|
|
102
122
|
|
|
103
123
|
- Add [PR preview environments](./pr-preview-environments.mdx) for review
|
|
104
124
|
- Set up [multi-stage deployment](./multi-stage-deployment.mdx) with staging
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "GitLab CI/CD: Local
|
|
3
|
-
sidebar_label: Local
|
|
2
|
+
title: "GitLab CI/CD: Local testing in CI"
|
|
3
|
+
sidebar_label: Local testing in CI
|
|
4
|
+
description:
|
|
5
|
+
Start a local Zuplo dev server inside GitLab CI/CD, poll it until it answers,
|
|
6
|
+
run your test suite, and only deploy if every test passes.
|
|
4
7
|
---
|
|
5
8
|
|
|
6
9
|
Test against a local Zuplo server before deploying anywhere.
|
|
@@ -17,7 +20,16 @@ local-test:
|
|
|
17
20
|
script:
|
|
18
21
|
- npm install
|
|
19
22
|
- npx zuplo dev &
|
|
20
|
-
|
|
23
|
+
# Poll until the server answers, with a hard deadline — never a fixed sleep
|
|
24
|
+
- |
|
|
25
|
+
deadline=$((SECONDS + 60))
|
|
26
|
+
until curl --fail --silent --output /dev/null http://localhost:9000/health; do
|
|
27
|
+
if (( SECONDS >= deadline )); then
|
|
28
|
+
echo "Local server did not start within 60s" >&2
|
|
29
|
+
exit 1
|
|
30
|
+
fi
|
|
31
|
+
sleep 1
|
|
32
|
+
done
|
|
21
33
|
- npx zuplo test --endpoint http://localhost:9000
|
|
22
34
|
- kill %1
|
|
23
35
|
|
|
@@ -34,6 +46,12 @@ deploy:
|
|
|
34
46
|
|
|
35
47
|
Local tests run first. Only if they pass does deployment proceed.
|
|
36
48
|
|
|
37
|
-
|
|
49
|
+
The readiness poll replaces a fixed `sleep`. A sleep is a guess about startup
|
|
50
|
+
time that is wrong in both directions, and it is the most common reason a
|
|
51
|
+
gateway test suite "needs" a retry. The example polls `/health` — add an
|
|
52
|
+
unauthenticated health route if your gateway does not have one. See
|
|
53
|
+
[health checks](../health-checks.mdx).
|
|
54
|
+
|
|
55
|
+
## Next steps
|
|
38
56
|
|
|
39
57
|
- Add [multi-stage deployment](./multi-stage-deployment.mdx) with staging
|
|
@@ -1,27 +1,31 @@
|
|
|
1
1
|
---
|
|
2
|
-
title:
|
|
3
|
-
sidebar_label:
|
|
2
|
+
title: Test GitHub deployments
|
|
3
|
+
sidebar_label: Test deployments
|
|
4
|
+
description:
|
|
5
|
+
Trigger a GitHub Actions workflow on Zuplo's deployment_status event, run your
|
|
6
|
+
test suite against the preview URL, and make the result a required status
|
|
7
|
+
check so a gateway regression blocks the merge.
|
|
4
8
|
---
|
|
5
9
|
|
|
6
10
|
Run your test suite automatically after every Zuplo deployment without replacing
|
|
7
11
|
the built-in GitHub integration. This approach uses GitHub's `deployment_status`
|
|
8
|
-
event to trigger tests after Zuplo finishes deploying
|
|
12
|
+
event to trigger tests after Zuplo finishes deploying, and makes the result a
|
|
13
|
+
required status check so a gateway regression blocks the merge.
|
|
9
14
|
|
|
10
|
-
## Why
|
|
15
|
+
## Why trigger on deployment_status
|
|
11
16
|
|
|
12
|
-
Zuplo's GitHub integration
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
completes.
|
|
17
|
+
Zuplo's GitHub integration handles deployments — every push deploys
|
|
18
|
+
automatically with status checks in GitHub. Rather than replacing this with
|
|
19
|
+
custom CI/CD, extend it by running tests after each deployment completes.
|
|
16
20
|
|
|
17
21
|
This gives you:
|
|
18
22
|
|
|
19
|
-
- **Automatic deployments** —
|
|
20
|
-
- **Post-deploy testing** —
|
|
21
|
-
- **PR checks** —
|
|
22
|
-
- **No duplicate deploys** —
|
|
23
|
+
- **Automatic deployments** — keep the built-in integration
|
|
24
|
+
- **Post-deploy testing** — run tests against the live environment
|
|
25
|
+
- **PR checks** — tests block merging until they pass
|
|
26
|
+
- **No duplicate deploys** — tests run after Zuplo deploys, not instead of
|
|
23
27
|
|
|
24
|
-
##
|
|
28
|
+
## Set up the workflow
|
|
25
29
|
|
|
26
30
|
Create a workflow that triggers on the `deployment_status` event:
|
|
27
31
|
|
|
@@ -33,11 +37,14 @@ on:
|
|
|
33
37
|
|
|
34
38
|
jobs:
|
|
35
39
|
test:
|
|
36
|
-
|
|
40
|
+
name: Test API Gateway
|
|
41
|
+
# Only run when a Zuplo deployment succeeds and reports a URL
|
|
37
42
|
if: |
|
|
38
43
|
github.event.deployment_status.state == 'success' &&
|
|
39
44
|
github.event.deployment_status.environment_url != ''
|
|
40
45
|
runs-on: ubuntu-latest
|
|
46
|
+
env:
|
|
47
|
+
API_URL: ${{ github.event.deployment_status.environment_url }}
|
|
41
48
|
steps:
|
|
42
49
|
- uses: actions/checkout@v4
|
|
43
50
|
|
|
@@ -46,29 +53,74 @@ jobs:
|
|
|
46
53
|
node-version: 24
|
|
47
54
|
|
|
48
55
|
- name: Install dependencies
|
|
49
|
-
run: npm
|
|
56
|
+
run: npm ci
|
|
57
|
+
|
|
58
|
+
# A deployment reporting success is not the same as a gateway
|
|
59
|
+
# serving traffic. Poll with a hard deadline instead of sleeping.
|
|
60
|
+
- name: Wait for the gateway to be ready
|
|
61
|
+
run: |
|
|
62
|
+
deadline=$((SECONDS + 120))
|
|
63
|
+
until curl --fail --silent --output /dev/null "$API_URL/health"; do
|
|
64
|
+
if (( SECONDS >= deadline )); then
|
|
65
|
+
echo "Gateway at $API_URL not ready after 120s" >&2
|
|
66
|
+
exit 1
|
|
67
|
+
fi
|
|
68
|
+
sleep 2
|
|
69
|
+
done
|
|
50
70
|
|
|
51
71
|
- name: Run tests
|
|
52
|
-
run:
|
|
53
|
-
npx zuplo test --endpoint ${{
|
|
54
|
-
github.event.deployment_status.environment_url }}
|
|
72
|
+
run: npx zuplo test --endpoint "$API_URL"
|
|
55
73
|
```
|
|
56
74
|
|
|
57
|
-
|
|
75
|
+
The workflow reads the deployment URL once into `API_URL` and reuses it, so the
|
|
76
|
+
readiness check and the test run target the same environment.
|
|
58
77
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
78
|
+
:::caution{title="Poll for readiness, never sleep"}
|
|
79
|
+
|
|
80
|
+
`deployment_status` fires when the deployment is _accepted_, which can be
|
|
81
|
+
shortly before the environment is warm. A fixed `sleep` is a guess that is wrong
|
|
82
|
+
in both directions — flaky when the system is slow, wasted CI minutes when it is
|
|
83
|
+
fast. Tests fired into that gap fail, get retried, and the pipeline race gets
|
|
84
|
+
misfiled as flaky tests.
|
|
85
|
+
|
|
86
|
+
If your gateway has no unauthenticated health route, add one. See
|
|
87
|
+
[health checks](./health-checks.mdx).
|
|
88
|
+
|
|
89
|
+
:::
|
|
90
|
+
|
|
91
|
+
## How it works
|
|
92
|
+
|
|
93
|
+
1. You push code to GitHub.
|
|
94
|
+
2. Zuplo's integration deploys automatically.
|
|
95
|
+
3. Zuplo reports deployment status back to GitHub.
|
|
96
|
+
4. The `deployment_status` event triggers your workflow.
|
|
97
|
+
5. The workflow polls the deployment until it answers.
|
|
98
|
+
6. Your tests run against the deployed environment URL.
|
|
99
|
+
7. Test results appear as a check on the commit or pull request.
|
|
65
100
|
|
|
66
101
|
The `environment_url` from the deployment status contains your Zuplo environment
|
|
67
102
|
URL, so tests always run against the correct environment.
|
|
68
103
|
|
|
69
|
-
##
|
|
104
|
+
## Pass fixture credentials
|
|
105
|
+
|
|
106
|
+
Tests that exercise authenticated routes need fixture tokens or API keys. Keep
|
|
107
|
+
them in GitHub Actions secrets and pass them as environment variables. Inside
|
|
108
|
+
the test they are available on `TestHelper.environment`:
|
|
70
109
|
|
|
71
|
-
|
|
110
|
+
```yaml
|
|
111
|
+
- name: Run tests
|
|
112
|
+
env:
|
|
113
|
+
TENANT_A_JWT: ${{ secrets.PREVIEW_TENANT_A_JWT }}
|
|
114
|
+
run: npx zuplo test --endpoint "$API_URL"
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
API key buckets and rate limit state are per environment, so the credentials
|
|
118
|
+
must belong to the environment being tested. See
|
|
119
|
+
[testing preview environments](./testing-preview-environments.mdx).
|
|
120
|
+
|
|
121
|
+
## Filter by environment
|
|
122
|
+
|
|
123
|
+
To test specific environments only, such as staging or production:
|
|
72
124
|
|
|
73
125
|
```yaml
|
|
74
126
|
jobs:
|
|
@@ -79,15 +131,44 @@ jobs:
|
|
|
79
131
|
# ...
|
|
80
132
|
```
|
|
81
133
|
|
|
82
|
-
|
|
134
|
+
Against production, run only the read-only smoke subset rather than the whole
|
|
135
|
+
suite:
|
|
136
|
+
|
|
137
|
+
```yaml
|
|
138
|
+
- name: Run smoke tests
|
|
139
|
+
run: npx zuplo test --endpoint "$API_URL" --filter "smoke"
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Add to PR checks
|
|
83
143
|
|
|
84
144
|
GitHub automatically shows deployment status checks on pull requests. Your test
|
|
85
145
|
workflow results appear alongside them, giving reviewers confidence that both
|
|
86
146
|
deployment and tests succeeded.
|
|
87
147
|
|
|
88
|
-
|
|
148
|
+
To make the check blocking, add the workflow's job name to
|
|
149
|
+
[branch protection](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/about-protected-branches)
|
|
150
|
+
as a required status check. The example below marks both "Zuplo Deployment" and
|
|
151
|
+
"Test API Gateway" as required.
|
|
152
|
+
|
|
153
|
+

|
|
154
|
+
|
|
155
|
+
A developer who tries to merge before the tests pass sees the merge blocked.
|
|
156
|
+
|
|
157
|
+

|
|
89
158
|
|
|
90
|
-
|
|
159
|
+
:::warning
|
|
160
|
+
|
|
161
|
+
Do not add a blanket retry to the test job. If a test needs a rerun to pass, it
|
|
162
|
+
has a shared resource, a sleep, or the pipeline is reporting readiness before
|
|
163
|
+
the gateway is serving. A retry converts a debuggable signal into permanent
|
|
164
|
+
background noise. See [gateway test recipes](./testing-recipes.mdx) for the
|
|
165
|
+
determinism rules.
|
|
166
|
+
|
|
167
|
+
:::
|
|
168
|
+
|
|
169
|
+
## When to use custom CI/CD
|
|
170
|
+
|
|
171
|
+
This approach works well when you want to:
|
|
91
172
|
|
|
92
173
|
- Keep automatic deployments
|
|
93
174
|
- Run tests after deploy
|
|
@@ -96,6 +177,12 @@ This approach works great when you want to:
|
|
|
96
177
|
Consider [custom GitHub Actions](./custom-ci-cd-github.mdx) if you need:
|
|
97
178
|
|
|
98
179
|
- Approval gates before production
|
|
99
|
-
- Multi-stage deployments (staging
|
|
180
|
+
- Multi-stage deployments (staging then production)
|
|
100
181
|
- Tests that must pass before any deployment
|
|
101
182
|
- Tag-based or release-based deployments
|
|
183
|
+
|
|
184
|
+
## Related
|
|
185
|
+
|
|
186
|
+
- [Testing overview](./testing.mdx)
|
|
187
|
+
- [Get started with zuplo test](./testing-getting-started.mdx)
|
|
188
|
+
- [Testing preview environments](./testing-preview-environments.mdx)
|