@postman-cse/onboarding-bootstrap 1.1.0 → 1.2.1
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/README.md +205 -443
- package/action.yml +2 -2
- package/dist/action.cjs +308 -49
- package/dist/cli.cjs +308 -49
- package/dist/index.cjs +308 -49
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -1,166 +1,86 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Postman Workspace Bootstrap
|
|
2
2
|
|
|
3
3
|
[](https://github.com/postman-cs/postman-bootstrap-action/actions/workflows/ci.yml)
|
|
4
4
|
[](https://github.com/postman-cs/postman-bootstrap-action/releases)
|
|
5
5
|
[](https://www.npmjs.com/package/@postman-cse/onboarding-bootstrap)
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Provisions a Postman workspace from an OpenAPI spec, generating baseline, smoke, and contract collections in one step.
|
|
9
9
|
|
|
10
|
-
##
|
|
11
|
-
|
|
12
|
-
This action preserves the bootstrap slice of the API Catalog demo flow:
|
|
13
|
-
|
|
14
|
-
- create or reuse a Postman workspace
|
|
15
|
-
- assign the workspace to a configured governance group when a group name and `postman-access-token` are provided
|
|
16
|
-
- invite the requester and add workspace admins
|
|
17
|
-
- upload or update a remote spec in Spec Hub (after normalizing operation summaries — see below)
|
|
18
|
-
- optionally check for OpenAPI breaking changes before any Postman mutations
|
|
19
|
-
- lint the uploaded spec by UID with the Postman CLI
|
|
20
|
-
- generate missing baseline, smoke, and contract collections or reuse existing ones
|
|
21
|
-
- optionally refresh current collections from the latest spec or create release-scoped spec and collection assets
|
|
22
|
-
- inject generated tests and apply collection tags
|
|
23
|
-
- reuse committed `.postman/resources.yaml` state from the checked-out ref when present
|
|
24
|
-
|
|
25
|
-
The public customer preview contract uses kebab-case inputs and outputs and defaults `integration-backend` to `bifrost`.
|
|
26
|
-
|
|
27
|
-
### Git provider support
|
|
28
|
-
|
|
29
|
-
Workspace-to-repository linking via Bifrost supports both **GitHub** and **GitLab** (cloud and self-hosted) repository URLs. The `repo-url` value (or the auto-derived URL from CI environment variables) is stored as-is by Bifrost without provider-specific validation. URL normalization handles HTTPS, SSH (`git@`), and `.git` suffix variants for both providers.
|
|
30
|
-
The public customer preview contract uses kebab-case inputs and outputs and defaults `integration-backend` to `bifrost`.
|
|
31
|
-
|
|
32
|
-
For existing services, pass `workspace-id`, `spec-id`, and any existing collection IDs to rerun the bootstrap safely without creating duplicate Postman assets. When `.postman/resources.yaml` is present in the checked-out ref, the action also reuses its workspace/spec/collection mappings automatically.
|
|
33
|
-
|
|
34
|
-
Lifecycle behavior remains backward-compatible except for collection default mode:
|
|
35
|
-
|
|
36
|
-
- `collection-sync-mode: refresh`
|
|
37
|
-
- `spec-sync-mode: update`
|
|
38
|
-
|
|
39
|
-
If you do not set those inputs, the action refreshes collection pointers from the resolved spec and keeps one canonical spec update path.
|
|
40
|
-
|
|
41
|
-
### Bootstrap phase independence
|
|
42
|
-
|
|
43
|
-
**Bootstrap succeeds independently** — it creates or updates Postman workspace and collections even if a later stage (repo sync, Insights onboarding) fails. This is intentional:
|
|
44
|
-
|
|
45
|
-
- **Postman side is self-contained:** Workspace creation, spec upload, and collection generation do not depend on repository access or merge status.
|
|
46
|
-
- **Repository side is async:** Later stages may fail due to repo permissions, branch protection, or pending approval. Bootstrap completion is not blocked by these downstream concerns.
|
|
47
|
-
- **Idempotent reruns:** If a later stage fails, subsequent reruns of the action will reuse existing Postman assets (via `workspace-id`, `spec-id`, collection IDs) and focus on the failed stage without recreating everything.
|
|
48
|
-
|
|
49
|
-
**When bootstrap fails:** The action stops and does not proceed to repo sync. Postman assets are left in the state they reached before the failure. Clear error messages identify which required bootstrap step failed (for example, spec lint or collection generation). Optional workspace enrichment steps, such as governance assignment and requester invitation, warn and continue so created workspaces and collections remain usable.
|
|
50
|
-
|
|
51
|
-
This layered design means customers can:
|
|
52
|
-
1. Verify Postman workspace health independently.
|
|
53
|
-
2. Debug repository issues (branch protection, permissions) separately from Postman provisioning.
|
|
54
|
-
3. Reuse existing Postman assets when fixing downstream failures.
|
|
55
|
-
|
|
56
|
-
### Team ID derivation
|
|
10
|
+
## Usage
|
|
57
11
|
|
|
58
|
-
|
|
12
|
+
```yaml
|
|
13
|
+
name: Bootstrap Postman workspace
|
|
14
|
+
on:
|
|
15
|
+
push:
|
|
16
|
+
branches: [main]
|
|
59
17
|
|
|
60
|
-
|
|
18
|
+
jobs:
|
|
19
|
+
bootstrap:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v5
|
|
23
|
+
- uses: postman-cs/postman-bootstrap-action@v1
|
|
24
|
+
with:
|
|
25
|
+
project-name: core-payments
|
|
26
|
+
spec-url: https://example.com/openapi.yaml
|
|
27
|
+
postman-api-key: ${{ secrets.POSTMAN_API_KEY }}
|
|
28
|
+
```
|
|
61
29
|
|
|
62
|
-
|
|
30
|
+
Provide either `spec-url` (public HTTPS) or `spec-path` (a file in the checked-out repo). See [Obtaining Credentials](docs/credentials.md) for how to generate `postman-api-key` and the optional `postman-access-token`.
|
|
63
31
|
|
|
64
|
-
|
|
32
|
+
## Examples
|
|
65
33
|
|
|
66
|
-
|
|
67
|
-
2. If multiple sub-teams are detected and no `workspace-team-id` is provided, the action fails with a list of available sub-teams and their numeric IDs.
|
|
68
|
-
3. Set `workspace-team-id` to the desired sub-team ID to proceed.
|
|
34
|
+
### Load the spec from the repository
|
|
69
35
|
|
|
70
|
-
|
|
36
|
+
For Git-first workflows, read the OpenAPI document directly from the checked-out workspace instead of hosting it over HTTPS:
|
|
71
37
|
|
|
72
38
|
```yaml
|
|
39
|
+
- uses: actions/checkout@v5
|
|
73
40
|
- uses: postman-cs/postman-bootstrap-action@v1
|
|
74
41
|
with:
|
|
75
42
|
project-name: core-payments
|
|
76
|
-
spec-
|
|
77
|
-
workspace-team-id: '132319'
|
|
43
|
+
spec-path: apis/core-payments/openapi.yaml
|
|
78
44
|
postman-api-key: ${{ secrets.POSTMAN_API_KEY }}
|
|
79
45
|
```
|
|
80
46
|
|
|
81
|
-
|
|
47
|
+
### Rerun safely for an existing service
|
|
82
48
|
|
|
83
|
-
|
|
84
|
-
workspace-team-id: ${{ vars.POSTMAN_WORKSPACE_TEAM_ID }}
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
**CLI usage:**
|
|
88
|
-
|
|
89
|
-
```bash
|
|
90
|
-
postman-bootstrap --workspace-team-id 132319 ...
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
Or via environment variable: `export POSTMAN_WORKSPACE_TEAM_ID=132319`
|
|
94
|
-
|
|
95
|
-
Non-org accounts (single team) are unaffected and do not need this input.
|
|
96
|
-
|
|
97
|
-
### Governance group assignment
|
|
98
|
-
|
|
99
|
-
Governance assignment is optional and customer-configured:
|
|
100
|
-
|
|
101
|
-
1. Set the repository custom property `postman-governance-group` to the Postman governance group name.
|
|
102
|
-
2. Set `postman-access-token` so the action can perform workspace enrichment after the workspace exists.
|
|
103
|
-
|
|
104
|
-
Example:
|
|
49
|
+
Pass `workspace-id`, `spec-id`, and existing collection IDs to rerun without creating duplicate Postman assets. When `.postman/resources.yaml` is committed on the checked-out ref, the action reuses its workspace, spec, and collection mappings automatically.
|
|
105
50
|
|
|
106
51
|
```yaml
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
52
|
+
- uses: postman-cs/postman-bootstrap-action@v1
|
|
53
|
+
with:
|
|
54
|
+
project-name: core-payments
|
|
55
|
+
workspace-id: ws-123
|
|
56
|
+
spec-id: spec-123
|
|
57
|
+
baseline-collection-id: col-baseline
|
|
58
|
+
smoke-collection-id: col-smoke
|
|
59
|
+
contract-collection-id: col-contract
|
|
60
|
+
spec-url: https://example.com/openapi.yaml
|
|
61
|
+
postman-api-key: ${{ secrets.POSTMAN_API_KEY }}
|
|
110
62
|
```
|
|
111
63
|
|
|
112
|
-
|
|
113
|
-
repository custom property. `governance-mapping-json` remains supported as a
|
|
114
|
-
domain-map fallback for older workflows.
|
|
64
|
+
### Create a versioned release set
|
|
115
65
|
|
|
116
|
-
|
|
117
|
-
expired, bootstrap logs a warning and continues with the created workspace,
|
|
118
|
-
spec, and collections.
|
|
119
|
-
|
|
120
|
-
### OpenAPI operation summaries (normalization)
|
|
121
|
-
|
|
122
|
-
Before upload to Spec Hub, the action parses JSON or YAML OpenAPI documents and adjusts **path operations** so collection generation is less likely to fail:
|
|
123
|
-
|
|
124
|
-
1. **Missing `summary`:** Uses `operationId` if present; otherwise falls back to `METHOD /path` (for example `GET /pets`).
|
|
125
|
-
2. **Very long `summary`:** Truncates to **200 characters** (with an ellipsis) so downstream limits are not exceeded.
|
|
126
|
-
|
|
127
|
-
This runs in `src/index.ts` before upload. If nothing under `paths` needs changing, the original document bytes are preserved. When normalization runs, the spec is re-serialized (JSON stays JSON; YAML stays YAML). Each fix emits a **warning** in the Actions log so you can improve the source spec over time. Invalid documents that cannot be parsed are left unchanged and a warning is logged.
|
|
128
|
-
|
|
129
|
-
### OpenAPI spec URL fetch safety
|
|
130
|
-
|
|
131
|
-
The root `spec-url` must be HTTPS and is fetched with pinned DNS resolution. The action blocks credential-bearing URLs, localhost/private/link-local/internal destinations, unsafe redirects, DNS rebinding attempts, and oversized OpenAPI resources before uploading content to Spec Hub. Root fetches are capped at 25 MiB, and fetch errors redact URL credentials, query strings, and fragments before logging.
|
|
132
|
-
|
|
133
|
-
### Loading the spec from the workspace (`spec-path`)
|
|
134
|
-
|
|
135
|
-
For Git-first workflows the spec is usually checked into the same repo that runs the action, so an HTTPS URL is redundant (or impossible without making the repo public). Pass `spec-path` instead of `spec-url` to read the document directly from the checked-out workspace:
|
|
66
|
+
Create a release-scoped spec and collection set instead of refreshing the canonical assets in place:
|
|
136
67
|
|
|
137
68
|
```yaml
|
|
138
|
-
- uses: actions/checkout@v5
|
|
139
69
|
- uses: postman-cs/postman-bootstrap-action@v1
|
|
140
70
|
with:
|
|
141
71
|
project-name: core-payments
|
|
142
|
-
spec-
|
|
72
|
+
spec-url: https://example.com/openapi.yaml
|
|
73
|
+
collection-sync-mode: version
|
|
74
|
+
spec-sync-mode: version
|
|
75
|
+
release-label: v1.1.1
|
|
143
76
|
postman-api-key: ${{ secrets.POSTMAN_API_KEY }}
|
|
144
77
|
```
|
|
145
78
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
### OpenAPI breaking-change check
|
|
79
|
+
When `release-label` is omitted, the action derives one from the git tag or branch. Details in [Lifecycle Modes](docs/lifecycle-and-operations.md).
|
|
149
80
|
|
|
150
|
-
|
|
81
|
+
### Fail the run on OpenAPI breaking changes
|
|
151
82
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
- `off`: default. No comparison runs and `openapi-changes` is not installed.
|
|
155
|
-
- `previous-spec`: compares the incoming Spec Hub upload content with the existing `spec-id` content. If there is no previous spec, the check is marked `skipped`.
|
|
156
|
-
- `pr-native`: compares `breaking-target-ref` or the detected PR target branch version of `spec-path` against the checked-out working tree. If no target-branch spec is available, it falls back to `breaking-baseline-spec-path` when configured.
|
|
157
|
-
- `baseline-only`: compares `breaking-baseline-spec-path` against the incoming spec. If the baseline file is missing, the check is marked `skipped`.
|
|
158
|
-
|
|
159
|
-
The action installs a pinned `pb33f/openapi-changes` release into the runner temp directory, verifies the archive checksum, validates archive paths before extraction, and runs the binary by absolute path. It does not require customers to preinstall the tool, and it does not use `npx`, global npm installs, or `curl | sh`.
|
|
160
|
-
|
|
161
|
-
Summary and log files default to `$RUNNER_TEMP/postman-bootstrap/`, so they are runner files, not committed repo changes. The markdown summary is also appended to the GitHub job summary when `$GITHUB_STEP_SUMMARY` is available. Pass `breaking-summary-path` or `breaking-log-path` only if your workflow wants explicit file locations for later `actions/upload-artifact` steps.
|
|
162
|
-
|
|
163
|
-
Example:
|
|
83
|
+
Compare the incoming contract before any Postman mutation. `pr-native` mode diffs the PR target branch version of `spec-path` against the working tree:
|
|
164
84
|
|
|
165
85
|
```yaml
|
|
166
86
|
- uses: actions/checkout@v5
|
|
@@ -176,153 +96,107 @@ Example:
|
|
|
176
96
|
postman-api-key: ${{ secrets.POSTMAN_API_KEY }}
|
|
177
97
|
```
|
|
178
98
|
|
|
179
|
-
|
|
99
|
+
Modes `off`, `previous-spec`, `pr-native`, and `baseline-only` are described in [OpenAPI Spec Handling](docs/spec-handling.md).
|
|
180
100
|
|
|
181
|
-
|
|
101
|
+
### Assign the workspace to a governance group
|
|
182
102
|
|
|
183
|
-
|
|
184
|
-
jobs:
|
|
185
|
-
bootstrap:
|
|
186
|
-
runs-on: ubuntu-latest
|
|
187
|
-
permissions:
|
|
188
|
-
actions: write
|
|
189
|
-
contents: read
|
|
190
|
-
steps:
|
|
191
|
-
- uses: actions/checkout@v5
|
|
192
|
-
- uses: postman-cs/postman-bootstrap-action@v1
|
|
193
|
-
with:
|
|
194
|
-
project-name: core-payments
|
|
195
|
-
domain: core-banking
|
|
196
|
-
domain-code: AF
|
|
197
|
-
requester-email: owner@example.com
|
|
198
|
-
workspace-admin-user-ids: 101,102
|
|
199
|
-
spec-url: https://example.com/openapi.yaml
|
|
200
|
-
github-token: ${{ github.token }}
|
|
201
|
-
postman-api-key: ${{ secrets.POSTMAN_API_KEY }}
|
|
202
|
-
postman-access-token: ${{ secrets.POSTMAN_ACCESS_TOKEN }}
|
|
103
|
+
Set the repository custom property `postman-governance-group`, then provide tokens so the action can perform workspace enrichment:
|
|
203
104
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
spec-id: spec-123
|
|
213
|
-
baseline-collection-id: col-baseline
|
|
214
|
-
smoke-collection-id: col-smoke
|
|
215
|
-
contract-collection-id: col-contract
|
|
216
|
-
spec-url: https://example.com/openapi.yaml
|
|
217
|
-
postman-api-key: ${{ secrets.POSTMAN_API_KEY }}
|
|
105
|
+
```yaml
|
|
106
|
+
- uses: postman-cs/postman-bootstrap-action@v1
|
|
107
|
+
with:
|
|
108
|
+
project-name: core-payments
|
|
109
|
+
spec-url: https://example.com/openapi.yaml
|
|
110
|
+
github-token: ${{ github.token }}
|
|
111
|
+
postman-api-key: ${{ secrets.POSTMAN_API_KEY }}
|
|
112
|
+
postman-access-token: ${{ secrets.POSTMAN_ACCESS_TOKEN }}
|
|
218
113
|
```
|
|
219
114
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
## Dynamic contract tests
|
|
115
|
+
For one-off runs, `governance-group` can be passed directly and overrides the repository custom property. `governance-mapping-json` remains supported as a domain-map fallback for older workflows. If the group configuration is missing, the group is not found, or the access token is expired, bootstrap logs a warning and continues with the created workspace, spec, and collections.
|
|
223
116
|
|
|
224
|
-
|
|
117
|
+
### Create the workspace under an org-mode sub-team
|
|
225
118
|
|
|
226
|
-
|
|
119
|
+
Postman organizations with multiple sub-teams require an explicit `workspace-team-id` for workspace creation:
|
|
227
120
|
|
|
228
|
-
|
|
229
|
-
-
|
|
230
|
-
|
|
231
|
-
-
|
|
232
|
-
-
|
|
233
|
-
-
|
|
234
|
-
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
Non-goals and limitations:
|
|
238
|
-
|
|
239
|
-
- Swagger 2.0, OAS webhooks, callbacks, and arbitrary user-authored collection requests are not fully validated.
|
|
240
|
-
- Runtime security checks prove credential presence and shape only; whether the server accepted the credential for the right reason is not proven, so security schemes are still warned as `CONTRACT_SECURITY_NOT_VALIDATED`. `mutualTLS` and unresolvable schemes are not checkable.
|
|
241
|
-
- Header `content`, unsupported schema dialects, and unsupported keywords fail closed. Non-JSON object schemas, validator-engine compile refusals, and reference graphs past the embed cap skip schema validation with `CONTRACT_NONJSON_SCHEMA_NOT_VALIDATED`/`CONTRACT_SCHEMA_NOT_COMPILED` warnings while Content-Type and body-presence checks still run; `discriminator` is stripped as an annotation and the underlying `oneOf`/`anyOf` still validates.
|
|
242
|
-
- Generated scripts target Newman/Postman runtime support for ES2020-compatible JavaScript and use compiled schemasafe IIFE validators. They do not use `pm.response.to.have.jsonSchema`, `eval`, or `new Function`.
|
|
243
|
-
|
|
244
|
-
OpenAPI semantics:
|
|
245
|
-
|
|
246
|
-
- OAS 3.0 `$ref` siblings are ignored, `nullable` is converted to JSON Schema unions, boolean exclusive min/max is converted, and response `writeOnly` properties are removed from response validation.
|
|
247
|
-
- `format` values that schemasafe asserts (`date-time`, `date`, `time`, `duration`, `email`, `hostname`, `ipv4`, `ipv6`, `uri`, `uri-reference`, `uri-template`, `uuid`, `json-pointer`, `relative-json-pointer`, `regex`) are validated; `format: int32` integers gain numeric range bounds; other formats (`int64`, `byte`, `binary`, vendor formats) are treated as annotations and stripped. `contentEncoding`, `contentMediaType`, and `contentSchema` are treated as annotations.
|
|
248
|
-
- OAS 3.1 `$ref` siblings are applied, the default dialect is JSON Schema 2020-12, supported `$schema` values are preserved, and unsupported custom dialects fail closed.
|
|
249
|
-
|
|
250
|
-
Security and size limits:
|
|
251
|
-
|
|
252
|
-
- Only HTTPS spec URLs and external refs are allowed.
|
|
253
|
-
- Localhost, loopback, link-local, RFC1918, RFC6598, IANA special-use IPv4/IPv6 ranges, IPv4-mapped IPv6, `.local`, and `.internal` destinations are blocked.
|
|
254
|
-
- DNS results are vetted and pinned into the HTTPS socket; redirects are fully revalidated.
|
|
255
|
-
- Limits: 5 redirects, 100 external refs, ref depth 20, 25 MiB per fetched resource, and 25 MiB total fetched bytes.
|
|
256
|
-
- Generated request scripts warn above 256 KiB and fail above 900 KiB; instrumented contract collection uploads fail above 4 MiB before upload. The bundled action is also reviewed for dependency-driven size growth.
|
|
257
|
-
|
|
258
|
-
Rollback behavior:
|
|
121
|
+
```yaml
|
|
122
|
+
- uses: postman-cs/postman-bootstrap-action@v1
|
|
123
|
+
with:
|
|
124
|
+
project-name: core-payments
|
|
125
|
+
spec-url: https://example.com/openapi.yaml
|
|
126
|
+
workspace-team-id: ${{ vars.POSTMAN_WORKSPACE_TEAM_ID }}
|
|
127
|
+
postman-api-key: ${{ secrets.POSTMAN_API_KEY }}
|
|
128
|
+
```
|
|
259
129
|
|
|
260
|
-
-
|
|
261
|
-
- For existing spec updates, the previous normalized spec content is fetched and hashed before update.
|
|
262
|
-
- If linting, collection generation, instrumentation, tagging, or linking fails after an existing spec update, the action best-effort restores the previous spec content.
|
|
263
|
-
- If rollback fails, the action emits `CONTRACT_SPEC_ROLLBACK_FAILED` with the previous content SHA-256 for manual restoration.
|
|
264
|
-
- Refresh mode stages generated baseline, smoke, and contract collections and instruments the temporary contract collection before updating any durable tracked collection. If a durable refresh update fails after another durable collection was updated, the action best-effort restores previously updated collection snapshots. Collection mutations after the refresh stage, such as later tagging/linking side effects, are not automatically rolled back; rerun the action after resolving the failure to reconcile generated collections with the restored spec.
|
|
130
|
+
See [Team Identity](docs/team-identity.md) for sub-team discovery and team-ID derivation.
|
|
265
131
|
|
|
266
|
-
|
|
267
|
-
| --- | --- | --- |
|
|
268
|
-
| `CONTRACT_SPEC_FETCH_BLOCKED` | Spec URL, ref URL, DNS result, redirect, or socket destination was not allowed. | Use public HTTPS spec/ref URLs that do not resolve to private or local networks. |
|
|
269
|
-
| `CONTRACT_SPEC_FETCH_FAILED` | Allowed HTTPS fetch failed or redirected too many times. | Check availability, status codes, and redirect chains. |
|
|
270
|
-
| `CONTRACT_REF_LIMIT_EXCEEDED` | External ref count exceeded the configured limit. | Reduce external ref fan-out or bundle the spec upstream. |
|
|
271
|
-
| `CONTRACT_REF_DEPTH_EXCEEDED` | Ref nesting exceeded the configured limit. | Flatten recursive/deep ref chains. |
|
|
272
|
-
| `CONTRACT_REF_SIZE_EXCEEDED` | A fetched resource or total fetched bytes exceeded limits. | Reduce spec/ref size or pre-bundle the document. |
|
|
273
|
-
| `CONTRACT_SPEC_PARSE_FAILED` | The fetched document was not valid JSON/YAML object content. | Fix the source document syntax. |
|
|
274
|
-
| `CONTRACT_SPEC_READ_FAILED` | The `spec-path` file could not be read from the workspace. | Verify the file exists at the configured path and that the workflow checked out the branch that contains it. |
|
|
275
|
-
| `CONTRACT_SPEC_VALIDATION_FAILED` | The bundled document failed OpenAPI validation. | Fix OpenAPI validation errors. |
|
|
276
|
-
| `CONTRACT_UNSUPPORTED_OPENAPI_VERSION` | The document was not OpenAPI 3.0 or 3.1. | Provide an OpenAPI 3.0/3.1 document. |
|
|
277
|
-
| `CONTRACT_NO_ELIGIBLE_OPERATIONS` | No eligible `paths` operations with responses were found. | Add path operations with responses. |
|
|
278
|
-
| `CONTRACT_OPERATION_NO_RESPONSES` | A `paths` operation had no response definitions. | Add at least one OpenAPI response to each path operation. |
|
|
279
|
-
| `CONTRACT_UNRESOLVED_REF` | A ref remained unresolved after secure bundling. | Fix the ref target or make the external ref HTTPS-accessible. |
|
|
280
|
-
| `CONTRACT_UNSUPPORTED_SCHEMA_DIALECT` | A schema declared an unsupported JSON Schema dialect. | Use draft-07 or 2020-12-compatible schemas. |
|
|
281
|
-
| `CONTRACT_SCHEMA_COMPILE_FAILED` | schemasafe could not compile a response/header schema. | Simplify or correct the unsupported schema. |
|
|
282
|
-
| `CONTRACT_STATIC_REQUEST_CHECK_FAILED` | Generated request missed a required non-security parameter or body. | Adjust generation options or the spec so generated requests include required shape. |
|
|
283
|
-
| `CONTRACT_SECURITY_NOT_VALIDATED` | Security requirements were detected but dynamic tests cannot prove auth at runtime. | Run dedicated auth tests and review generated requests for required credentials. |
|
|
284
|
-
| `CONTRACT_WEBHOOKS_NOT_VALIDATED` | OpenAPI webhooks were present but are not included in dynamic contract coverage. | Validate webhook behavior separately or model required behavior under `paths`. |
|
|
285
|
-
| `CONTRACT_CALLBACKS_NOT_VALIDATED` | Operation callbacks were present but are not included in dynamic contract coverage. | Validate callback behavior separately or add dedicated tests. |
|
|
286
|
-
| `CONTRACT_COOKIE_PARAM_NOT_VALIDATED` | A required cookie parameter cannot be statically required in generated requests. | Send the cookie in dedicated tests or move the parameter to a header/query location. |
|
|
287
|
-
| `CONTRACT_OPERATION_DEPRECATED` | A covered operation is marked `deprecated: true` in the OpenAPI document. | Plan removal of the deprecated operation or drop it from the spec when retired. |
|
|
288
|
-
| `CONTRACT_REQUEST_BODY_INCOMPLETE` | A parseable generated request body is missing top-level required properties. | Fix the spec example or regenerate the collection so generated bodies satisfy the request schema. |
|
|
289
|
-
| `CONTRACT_READONLY_PROPERTY_IN_REQUEST` | A generated request body includes properties the schema marks `readOnly`. | Remove readOnly properties from request examples; they belong in responses. |
|
|
290
|
-
| `CONTRACT_UNDOCUMENTED_QUERY_PARAM` | A generated request sends a query parameter the operation does not declare. | Declare the parameter in the OpenAPI operation or remove it from the generated request. |
|
|
291
|
-
| `CONTRACT_LINKS_NOT_VALIDATED` | Response links were present but link traversal is not part of dynamic contract coverage. | Validate linked operation chains with dedicated workflow tests. |
|
|
292
|
-
| `CONTRACT_PARAM_SERIALIZATION_NOT_VALIDATED` | A parameter declares non-default style, explode, or content serialization. | Validate the serialized form with dedicated tests; default-style parameters are covered. |
|
|
293
|
-
| `CONTRACT_NONJSON_SCHEMA_NOT_VALIDATED` | A non-JSON response media type declares an object schema that runtime tests cannot validate. | Validate XML or other non-JSON payloads with dedicated tests; Content-Type and body presence are still checked. |
|
|
294
|
-
| `CONTRACT_REQUEST_SCHEMA_NOT_VALIDATED` | A JSON request body schema could not be compiled into a runtime request validator. | Simplify the unsupported request schema construct named in the warning. |
|
|
295
|
-
| `CONTRACT_SCHEMA_NOT_COMPILED` | One schema could not be compiled by the validator engine, so its runtime check is skipped. | Review the named schema construct; other checks for the operation still run. |
|
|
296
|
-
| `CONTRACT_EXAMPLE_SCHEMA_MISMATCH` | A media-type example does not validate against its own schema. | Fix the example or the schema so the spec is self-consistent; generated requests are built from these examples. |
|
|
297
|
-
| `CONTRACT_ENCODING_MISMATCH` | A generated multipart field does not match its OpenAPI encoding object: a declared per-part `contentType` is missing or different, or a binary-typed field was not generated as a file part. | Regenerate the collection or align the encoding object with the intended part layout. |
|
|
298
|
-
| `CONTRACT_HEADER_SCHEMA_NOT_VALIDATED` | A response header declares a non-scalar schema, so its serialized value is checked for presence only. | Use a scalar header schema or validate the serialized header form with dedicated tests. |
|
|
299
|
-
| `CONTRACT_PATH_PARAM_NOT_VALIDATED` | Path parameter values are not validated at runtime. | Path templates drive operation matching; validate path value semantics with dedicated tests if needed. |
|
|
300
|
-
| `CONTRACT_DUPLICATE_OPERATION_MATCH` | Multiple OpenAPI operations share the same canonical request mapping candidate. | Disambiguate paths, server prefixes, or templated routes. |
|
|
301
|
-
| `CONTRACT_DUPLICATE_OPERATION_REQUEST` | More than one generated request mapped to the same contract operation. | Disambiguate paths/operations or generated requests. |
|
|
302
|
-
| `CONTRACT_OPERATION_COVERAGE_FAILED` | Generated contract collection did not cover every eligible operation. | Regenerate the collection or fix operation paths. |
|
|
303
|
-
| `CONTRACT_FORBIDDEN_SCRIPT_CONSTRUCT` | Generated script included a forbidden dynamic validation construct. | Report the schema that triggered unsafe generation. |
|
|
304
|
-
| `CONTRACT_SCRIPT_SIZE_EXCEEDED` | A generated request test script exceeded the per-script size gate. | Reduce schema complexity or split the API. |
|
|
305
|
-
| `CONTRACT_COLLECTION_SIZE_EXCEEDED` | Instrumented contract collection exceeded the size gate. | Reduce schema/operation count or split the API. |
|
|
306
|
-
| `CONTRACT_COLLECTION_ID_COLLISION` | Baseline, smoke, and contract IDs were not pairwise distinct. | Pass distinct collection IDs or clear stale IDs. |
|
|
307
|
-
| `CONTRACT_PLAN_MISSING` | Contract instrumentation ran without a preflight-generated contract plan. | Rerun with dynamic contract preflight enabled and report the failure if it persists. |
|
|
308
|
-
| `CONTRACT_SPEC_ROLLBACK_FAILED` | Best-effort previous spec restoration failed after a later error. | Restore the previous spec content manually using the emitted SHA-256. |
|
|
132
|
+
## Inputs
|
|
309
133
|
|
|
310
|
-
|
|
134
|
+
<!-- inputs-table:start -->
|
|
135
|
+
| Name | Description | Required | Default |
|
|
136
|
+
| --- | --- | --- | --- |
|
|
137
|
+
| `workspace-id` | Existing Postman workspace ID | no | |
|
|
138
|
+
| `spec-id` | Existing Postman spec ID | no | |
|
|
139
|
+
| `baseline-collection-id` | Existing baseline collection ID | no | |
|
|
140
|
+
| `smoke-collection-id` | Existing smoke collection ID | no | |
|
|
141
|
+
| `contract-collection-id` | Existing contract collection ID | no | |
|
|
142
|
+
| `sync-examples` | Whether linked spec/collection relations should enable example syncing | no | `true` |
|
|
143
|
+
| `collection-sync-mode` | Collection lifecycle policy (refresh or version) | no | `refresh` |
|
|
144
|
+
| `spec-sync-mode` | Spec lifecycle policy (update or version) | no | `update` |
|
|
145
|
+
| `release-label` | Optional release label used for versioned specs and collections | no | |
|
|
146
|
+
| `project-name` | Service project name | yes | |
|
|
147
|
+
| `domain` | Business domain for the service | no | |
|
|
148
|
+
| `domain-code` | Workspace naming prefix | no | |
|
|
149
|
+
| `governance-group` | Postman governance workspace group name. Overrides the postman-governance-group repository custom property and domain mapping. | no | |
|
|
150
|
+
| `requester-email` | Requester email for audit context | no | |
|
|
151
|
+
| `workspace-admin-user-ids` | Comma-separated workspace admin user ids | no | |
|
|
152
|
+
| `workspace-team-id` | Numeric sub-team ID for org-mode workspace creation. Required when the API key belongs to an org with multiple sub-teams. Run the action without this input to see available sub-teams listed in the error output. | no | |
|
|
153
|
+
| `spec-url` | HTTPS URL to the OpenAPI document to bootstrap. Provide either spec-url or spec-path. | no | |
|
|
154
|
+
| `spec-path` | Local filesystem path to the OpenAPI document (relative to the workspace). Provide either spec-url or spec-path. | no | |
|
|
155
|
+
| `openapi-version` | OpenAPI specification version override (3.0 or 3.1). When not set, the version is auto-detected from the spec content. | no | |
|
|
156
|
+
| `breaking-change-mode` | OpenAPI breaking-change comparison mode (off, pr-native, baseline-only, or previous-spec) | no | `off` |
|
|
157
|
+
| `breaking-baseline-spec-path` | Workspace-relative baseline OpenAPI spec path used by baseline-only mode and pr-native fallback | no | |
|
|
158
|
+
| `breaking-rules-path` | Workspace-relative openapi-changes rules file. Missing files are ignored. | no | `changes-rules.yaml` |
|
|
159
|
+
| `breaking-target-ref` | Optional target branch or git ref override for pr-native breaking-change comparisons | no | |
|
|
160
|
+
| `breaking-summary-path` | Optional markdown report output path. Defaults to a runner-temp file. | no | |
|
|
161
|
+
| `breaking-log-path` | Optional raw command log output path. Defaults to a runner-temp file. | no | |
|
|
162
|
+
| `governance-mapping-json` | Legacy JSON map of business domain to governance group name. Prefer governance-group or the postman-governance-group repository custom property. | no | `{}` |
|
|
163
|
+
| `github-token` | GitHub token used to read the postman-governance-group repository custom property | no | |
|
|
164
|
+
| `gh-fallback-token` | Fallback GitHub token used to read repository custom properties when github-token cannot | no | |
|
|
165
|
+
| `postman-api-key` | Postman API key used for bootstrap operations | yes | |
|
|
166
|
+
| `postman-access-token` | Postman access token used for governance and workspace mutations | no | |
|
|
167
|
+
| `credential-preflight` | Credential identity preflight policy. warn (default) logs a note and continues when postman-api-key and postman-access-token resolve to different parent orgs; enforce fails the run on that condition before any workspace is created; off skips the identity probes entirely (the reactive error guidance still applies). Promotion of the default to enforce is planned once the live e2e legs prove both directions. | no | `warn` |
|
|
168
|
+
| `integration-backend` | Integration backend for downstream workspace connectivity | no | `bifrost` |
|
|
169
|
+
| `folder-strategy` | Folder organization strategy for generated collections (Paths or Tags) | no | `Paths` |
|
|
170
|
+
| `nested-folder-hierarchy` | When folder-strategy is Tags, enables nested folder hierarchy | no | `false` |
|
|
171
|
+
| `request-name-source` | Determines how requests are named in generated collections (Fallback or URL) | no | `Fallback` |
|
|
172
|
+
| `postman-stack` | Postman stack profile | no | `prod` |
|
|
173
|
+
<!-- inputs-table:end -->
|
|
311
174
|
|
|
312
|
-
|
|
313
|
-
GitHub Actions users should continue using the `action.yml` interface.
|
|
175
|
+
## Outputs
|
|
314
176
|
|
|
315
|
-
|
|
177
|
+
<!-- outputs-table:start -->
|
|
178
|
+
| Name | Description | Required | Default |
|
|
179
|
+
| --- | --- | --- | --- |
|
|
180
|
+
| `workspace-id` | Postman workspace ID | n/a | n/a |
|
|
181
|
+
| `workspace-url` | Postman workspace URL | n/a | n/a |
|
|
182
|
+
| `workspace-name` | Postman workspace name | n/a | n/a |
|
|
183
|
+
| `spec-id` | Uploaded Postman spec ID | n/a | n/a |
|
|
184
|
+
| `baseline-collection-id` | Baseline collection ID | n/a | n/a |
|
|
185
|
+
| `smoke-collection-id` | Smoke collection ID | n/a | n/a |
|
|
186
|
+
| `contract-collection-id` | Contract collection ID | n/a | n/a |
|
|
187
|
+
| `collections-json` | JSON summary of generated collections | n/a | n/a |
|
|
188
|
+
| `lint-summary-json` | JSON summary of lint errors and warnings | n/a | n/a |
|
|
189
|
+
| `breaking-change-status` | OpenAPI breaking-change check status | n/a | n/a |
|
|
190
|
+
| `breaking-change-summary-json` | JSON summary of the OpenAPI breaking-change check | n/a | n/a |
|
|
191
|
+
<!-- outputs-table:end -->
|
|
192
|
+
|
|
193
|
+
## CLI usage (non-GitHub CI)
|
|
194
|
+
|
|
195
|
+
The same bootstrap is available as a CLI for GitLab CI, Bitbucket Pipelines, Azure DevOps, and other CI systems. GitHub Actions users should continue using the `action.yml` interface.
|
|
316
196
|
|
|
317
197
|
```bash
|
|
318
198
|
npm install -g @postman-cse/onboarding-bootstrap
|
|
319
|
-
```
|
|
320
199
|
|
|
321
|
-
The CLI package supports Node.js 24+ to match the GitHub Action runtime.
|
|
322
|
-
|
|
323
|
-
Basic usage:
|
|
324
|
-
|
|
325
|
-
```bash
|
|
326
200
|
postman-bootstrap \
|
|
327
201
|
--project-name core-payments \
|
|
328
202
|
--spec-url https://example.com/openapi.yaml \
|
|
@@ -332,9 +206,7 @@ postman-bootstrap \
|
|
|
332
206
|
--dotenv-path bootstrap.env
|
|
333
207
|
```
|
|
334
208
|
|
|
335
|
-
The CLI auto-detects the CI provider from environment variables for GitHub, GitLab, Bitbucket, and Azure DevOps.
|
|
336
|
-
It writes JSON to stdout, with all logs sent to stderr.
|
|
337
|
-
Use `--result-json` to write the JSON payload to a file, and `--dotenv-path` to emit shell-sourceable `KEY=VALUE` output with the `POSTMAN_BOOTSTRAP_` prefix.
|
|
209
|
+
The CLI package supports Node.js 24+ to match the GitHub Action runtime. It auto-detects the CI provider from environment variables for GitHub, GitLab, Bitbucket, and Azure DevOps, writes JSON to stdout, and sends all logs to stderr. Use `--result-json` to write the JSON payload to a file and `--dotenv-path` to emit shell-sourceable `KEY=VALUE` output with the `POSTMAN_BOOTSTRAP_` prefix.
|
|
338
210
|
|
|
339
211
|
Example GitLab CI job:
|
|
340
212
|
|
|
@@ -380,202 +252,92 @@ steps:
|
|
|
380
252
|
- publish: bootstrap.env
|
|
381
253
|
```
|
|
382
254
|
|
|
383
|
-
##
|
|
384
|
-
|
|
385
|
-
| Input | Default | Notes |
|
|
386
|
-
| --- | --- | --- |
|
|
387
|
-
| `workspace-id` | | Reuse an existing Postman workspace instead of creating one. |
|
|
388
|
-
| `spec-id` | | Update an existing Postman spec instead of uploading a new one. |
|
|
389
|
-
| `baseline-collection-id` | | Reuse an existing baseline collection. |
|
|
390
|
-
| `smoke-collection-id` | | Reuse an existing smoke collection. |
|
|
391
|
-
| `contract-collection-id` | | Reuse an existing contract collection. |
|
|
392
|
-
| `sync-examples` | `true` | Whether linked spec/collection relations should enable example syncing during cloud linkage. |
|
|
393
|
-
| `collection-sync-mode` | `refresh` | Collection lifecycle policy. `refresh` keeps the tracked collection IDs while updating them from the latest spec, and `version` creates or reuses release-scoped collections. |
|
|
394
|
-
| `spec-sync-mode` | `update` | Spec lifecycle policy. `update` keeps one canonical spec current in Spec Hub, while `version` creates or reuses a release-scoped spec asset. |
|
|
395
|
-
| `release-label` | | Optional release label used for versioned specs and collections. When omitted for versioned sync, the action derives one from GitHub tag or branch metadata. |
|
|
396
|
-
| `project-name` | | Service name used in workspace and asset naming. |
|
|
397
|
-
| `domain` | | Business domain metadata. Also used by the legacy `governance-mapping-json` fallback. |
|
|
398
|
-
| `domain-code` | | Short prefix used when constructing the workspace name. |
|
|
399
|
-
| `requester-email` | | Optional user invited into the workspace. |
|
|
400
|
-
| `workspace-admin-user-ids` | | Comma-separated Postman user IDs to grant admin access. |
|
|
401
|
-
| `workspace-team-id` | | Numeric sub-team ID for org-mode workspace creation. Required when the API key belongs to an org with multiple sub-teams. |
|
|
402
|
-
| `spec-url` | | HTTPS URL to the OpenAPI document. Provide either `spec-url` or `spec-path`. |
|
|
403
|
-
| `spec-path` | | Local filesystem path to the OpenAPI document, relative to the checked-out workspace (e.g. `apis/identity/openapi.yaml`). Use this when the spec lives in the repo and you don't want to host it over HTTPS. Provide either `spec-url` or `spec-path`. |
|
|
404
|
-
| `breaking-change-mode` | `off` | OpenAPI breaking-change comparison mode: `off`, `pr-native`, `baseline-only`, or `previous-spec`. |
|
|
405
|
-
| `breaking-baseline-spec-path` | | Workspace-relative baseline OpenAPI spec path used by `baseline-only` and as `pr-native` fallback. |
|
|
406
|
-
| `breaking-rules-path` | `changes-rules.yaml` | Workspace-relative `openapi-changes` rules file. Missing files are ignored. |
|
|
407
|
-
| `breaking-target-ref` | | Optional target branch or git ref override for `pr-native`. |
|
|
408
|
-
| `breaking-summary-path` | | Optional markdown report output path. Defaults to a runner-temp file. |
|
|
409
|
-
| `breaking-log-path` | | Optional raw command log output path. Defaults to a runner-temp file. |
|
|
410
|
-
| `governance-group` | | Postman governance group name. Overrides the `postman-governance-group` repository custom property and legacy domain mapping. |
|
|
411
|
-
| `governance-mapping-json` | `{}` | Legacy fallback map of `domain` value to Postman governance group name. Prefer the repository custom property or `governance-group`. |
|
|
412
|
-
| `github-token` | | GitHub token used to read the `postman-governance-group` repository custom property. |
|
|
413
|
-
| `gh-fallback-token` | | Fallback GitHub token used to read repository custom properties when `github-token` cannot. |
|
|
414
|
-
| `postman-api-key` | | Required for all Postman asset operations. |
|
|
415
|
-
| `postman-access-token` | | Required for governance assignment, cloud spec-to-collection syncing, and canonical workspace validation during reruns. |
|
|
416
|
-
| `integration-backend` | `bifrost` | Current public customer preview backend. |
|
|
417
|
-
|
|
418
|
-
## Lifecycle Modes
|
|
419
|
-
|
|
420
|
-
### Collection sync
|
|
255
|
+
## How it works
|
|
421
256
|
|
|
422
|
-
|
|
423
|
-
- `refresh`: baseline, smoke, and contract collections are regenerated from the resolved spec and become the current/default collection pointers.
|
|
424
|
-
- `version`: a release-scoped collection set is created or reused from the checked-out ref's state when available.
|
|
257
|
+
The action preserves the bootstrap slice of the API Catalog demo flow: create or reuse a Postman workspace, assign governance, invite the requester and workspace admins, upload or update the spec in Spec Hub, lint it with the Postman CLI, generate or reuse baseline, smoke, and contract collections, inject generated tests, apply tags, and reuse committed `.postman/resources.yaml` state when present. Inputs and outputs use kebab-case, and `integration-backend` defaults to `bifrost`.
|
|
425
258
|
|
|
426
|
-
|
|
259
|
+
- **Phase independence:** bootstrap succeeds on its own even when later pipeline stages (repo sync, Insights) fail, and reruns reuse existing assets. See [Bootstrap Phase Independence](docs/bootstrap-phase-independence.md).
|
|
260
|
+
- **Team identity:** the team ID is derived from `postman-api-key` via `/me`; org-mode tenants pass `workspace-team-id`. See [Team Identity](docs/team-identity.md).
|
|
261
|
+
- **Git providers:** workspace-to-repository linking supports GitHub and GitLab, cloud and self-hosted. See [Git Provider Support](docs/git-provider-support.md).
|
|
262
|
+
- **Spec handling:** operation summaries are normalized before upload, `spec-url` fetches are SSRF-hardened HTTPS with pinned DNS, and breaking-change comparison runs before any Postman mutation when enabled. See [OpenAPI Spec Handling](docs/spec-handling.md).
|
|
263
|
+
- **Lifecycle modes:** `collection-sync-mode` (`refresh`/`version`, legacy `reuse`), `spec-sync-mode` (`update`/`version`), release-label derivation, ref-native state, cloud spec-to-collection syncing, smoke monitoring, and the REST migration seam. See [Lifecycle Modes and Operational Reference](docs/lifecycle-and-operations.md).
|
|
264
|
+
- **Credentials:** `postman-api-key` handles standard Postman API operations; the optional `postman-access-token` unlocks governance assignment, cloud link/sync, and canonical workspace validation. See [Obtaining Credentials](docs/credentials.md).
|
|
427
265
|
|
|
428
|
-
|
|
429
|
-
- `version`: the action reuses the checked-out ref's `.postman/resources.yaml` spec mapping when present. If no mapping exists on the current ref, it creates a new release-scoped spec.
|
|
430
|
-
|
|
431
|
-
### Release label derivation
|
|
432
|
-
|
|
433
|
-
When versioned sync is requested and `release-label` is omitted, the action derives one using:
|
|
434
|
-
|
|
435
|
-
1. explicit `release-label`
|
|
436
|
-
2. Git tag name
|
|
437
|
-
3. branch name or ref metadata
|
|
438
|
-
|
|
439
|
-
If versioned sync is requested and no usable label can be derived, the run fails.
|
|
440
|
-
|
|
441
|
-
### Ref-native state
|
|
442
|
-
|
|
443
|
-
Current Postman asset state lives in `.postman/resources.yaml`.
|
|
444
|
-
|
|
445
|
-
- `update`, `refresh`, and legacy `reuse` modes resolve current-state mappings from the checked-out ref.
|
|
446
|
-
- `version` mode reuses only the checked-out ref's mappings; release history lives in git history and tags, not in a separate manifest file or repository variables.
|
|
447
|
-
|
|
448
|
-
### Cloud spec-to-collection syncing
|
|
449
|
-
|
|
450
|
-
After collections exist, bootstrap links them to the cloud specification and triggers a spec-side collection sync when `postman-access-token` is available.
|
|
451
|
-
|
|
452
|
-
- `sync-examples: true` (default) enables example syncing in that relation setup.
|
|
453
|
-
- `sync-examples: false` keeps the relation but disables example syncing.
|
|
454
|
-
- If `postman-access-token` is missing, bootstrap warns and skips the cloud link/sync step.
|
|
455
|
-
|
|
456
|
-
### Contract smoke monitoring
|
|
457
|
-
|
|
458
|
-
This repo includes `.github/workflows/contract-smoke.yml`, a scheduled live contract check for the upstream Postman APIs used by bootstrap.
|
|
459
|
-
|
|
460
|
-
Configure these repository secrets before enabling the workflow:
|
|
461
|
-
|
|
462
|
-
- `SMOKE_ORG_API_KEY`
|
|
463
|
-
- `SMOKE_ORG_ACCESS_TOKEN`
|
|
464
|
-
- `SMOKE_NON_ORG_API_KEY`
|
|
465
|
-
|
|
466
|
-
Configure this repository variable for the org-mode workspace creation check:
|
|
467
|
-
|
|
468
|
-
- `SMOKE_WORKSPACE_TEAM_ID=132319`
|
|
469
|
-
|
|
470
|
-
`132319` is the currently derived CSE sub-team ID under org `13347347`. The smoke job uses that value to verify `POST /workspaces` still accepts the explicit `teamId` payload required for org-mode tenants.
|
|
471
|
-
|
|
472
|
-
## Versioning Examples
|
|
473
|
-
|
|
474
|
-
Refresh the current collections in place while keeping one canonical spec:
|
|
475
|
-
|
|
476
|
-
```yaml
|
|
477
|
-
- uses: postman-cs/postman-bootstrap-action@v1
|
|
478
|
-
with:
|
|
479
|
-
project-name: core-payments
|
|
480
|
-
spec-url: https://example.com/openapi.yaml
|
|
481
|
-
collection-sync-mode: refresh
|
|
482
|
-
spec-sync-mode: update
|
|
483
|
-
postman-api-key: ${{ secrets.POSTMAN_API_KEY }}
|
|
484
|
-
```
|
|
485
|
-
|
|
486
|
-
Create a versioned spec and collection set on the checked-out ref:
|
|
487
|
-
|
|
488
|
-
```yaml
|
|
489
|
-
- uses: postman-cs/postman-bootstrap-action@v1
|
|
490
|
-
with:
|
|
491
|
-
project-name: core-payments
|
|
492
|
-
spec-url: https://example.com/openapi.yaml
|
|
493
|
-
collection-sync-mode: version
|
|
494
|
-
spec-sync-mode: version
|
|
495
|
-
release-label: v1.1.1
|
|
496
|
-
postman-api-key: ${{ secrets.POSTMAN_API_KEY }}
|
|
497
|
-
```
|
|
498
|
-
|
|
499
|
-
### Obtaining `postman-api-key`
|
|
500
|
-
|
|
501
|
-
The `postman-api-key` is a Postman API key (PMAK) used for all standard Postman API operations — creating workspaces, uploading specs, generating collections, exporting artifacts, and managing environments.
|
|
502
|
-
|
|
503
|
-
**To generate one:**
|
|
504
|
-
|
|
505
|
-
1. Open the Postman desktop app or web UI.
|
|
506
|
-
2. Go to **Settings** (gear icon) → **Account Settings** → **API Keys**.
|
|
507
|
-
3. Click **Generate API Key**, give it a label, and copy the key (starts with `PMAK-`).
|
|
508
|
-
4. Set it as a GitHub secret:
|
|
509
|
-
```bash
|
|
510
|
-
gh secret set POSTMAN_API_KEY --repo <owner>/<repo>
|
|
511
|
-
```
|
|
512
|
-
|
|
513
|
-
> **Note:** The PMAK is a long-lived key tied to your Postman account. It does not require periodic renewal like the `postman-access-token`.
|
|
514
|
-
|
|
515
|
-
### Obtaining `postman-access-token` (Customer Preview)
|
|
516
|
-
|
|
517
|
-
> **⚠️ Customer Preview limitation:** The `postman-access-token` input requires a manually-extracted session token. There is currently no public API to exchange a Postman API key (PMAK) for an access token programmatically. This manual step will be eliminated before GA.
|
|
518
|
-
|
|
519
|
-
The `postman-access-token` is a Postman session token required for workspace enrichment operations that the standard PMAK API key cannot perform, including governance group assignment, cloud spec-to-collection syncing, and canonical workspace validation during reruns. Without it, those steps degrade to warning-based behavior and name-based workspace fallback during provisioning.
|
|
520
|
-
|
|
521
|
-
**To obtain and configure the token:**
|
|
522
|
-
|
|
523
|
-
1. **Log in via the Postman CLI** (requires a browser):
|
|
524
|
-
```bash
|
|
525
|
-
postman login
|
|
526
|
-
```
|
|
527
|
-
This opens a browser window for Postman's PKCE OAuth flow. Complete the sign-in.
|
|
528
|
-
|
|
529
|
-
2. **Extract the access token** from the CLI credential store:
|
|
530
|
-
```bash
|
|
531
|
-
cat ~/.postman/postmanrc | jq -r '.login._profiles[].accessToken'
|
|
532
|
-
```
|
|
533
|
-
|
|
534
|
-
3. **Set it as a GitHub secret** on your repository or organization:
|
|
535
|
-
```bash
|
|
536
|
-
# Repository-level secret
|
|
537
|
-
gh secret set POSTMAN_ACCESS_TOKEN --repo <owner>/<repo>
|
|
266
|
+
## Dynamic contract tests
|
|
538
267
|
|
|
539
|
-
|
|
540
|
-
gh secret set POSTMAN_ACCESS_TOKEN --org <org> --visibility selected --repos <repo1>,<repo2>
|
|
541
|
-
```
|
|
542
|
-
Paste the token value when prompted.
|
|
268
|
+
Before any durable contract collection is overwritten, the action hardens the generated `[Contract]` collection against the resolved OpenAPI 3.0/3.1 document: it bundles and validates the spec, requires exactly one generated request per eligible operation, instruments each request with OpenAPI-derived runtime checks (status codes, headers, body presence, `Content-Type`, JSON schemas, security credential presence, request parameter and body values), and enforces script safety and size gates. Spec updates capture the previous content hash so failed runs can roll back, and refresh mode stages generated collections before touching durable ones.
|
|
543
269
|
|
|
544
|
-
|
|
270
|
+
Full pipeline, validation scope, OpenAPI semantics, limits, and rollback behavior are documented in [Dynamic Contract Tests](docs/dynamic-contract-tests.md).
|
|
545
271
|
|
|
546
|
-
|
|
272
|
+
## Errors
|
|
547
273
|
|
|
548
|
-
|
|
274
|
+
Dynamic contract failures and warnings use `CONTRACT_` error codes. Remediation guidance for each code:
|
|
549
275
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
276
|
+
| Error code | Meaning | Remediation |
|
|
277
|
+
| --- | --- | --- |
|
|
278
|
+
| `CONTRACT_SPEC_FETCH_BLOCKED` | Spec URL, ref URL, DNS result, redirect, or socket destination was not allowed. | Use public HTTPS spec/ref URLs that do not resolve to private or local networks. |
|
|
279
|
+
| `CONTRACT_SPEC_FETCH_FAILED` | Allowed HTTPS fetch failed or redirected too many times. | Check availability, status codes, and redirect chains. |
|
|
280
|
+
| `CONTRACT_REF_LIMIT_EXCEEDED` | External ref count exceeded the configured limit. | Reduce external ref fan-out or bundle the spec upstream. |
|
|
281
|
+
| `CONTRACT_REF_DEPTH_EXCEEDED` | Ref nesting exceeded the configured limit. | Flatten recursive/deep ref chains. |
|
|
282
|
+
| `CONTRACT_REF_SIZE_EXCEEDED` | A fetched resource or total fetched bytes exceeded limits. | Reduce spec/ref size or pre-bundle the document. |
|
|
283
|
+
| `CONTRACT_SPEC_PARSE_FAILED` | The fetched document was not valid JSON/YAML object content. | Fix the source document syntax. |
|
|
284
|
+
| `CONTRACT_SPEC_READ_FAILED` | The `spec-path` file could not be read from the workspace. | Verify the file exists at the configured path and that the workflow checked out the branch that contains it. |
|
|
285
|
+
| `CONTRACT_SPEC_VALIDATION_FAILED` | The bundled document failed OpenAPI validation. | Fix OpenAPI validation errors. |
|
|
286
|
+
| `CONTRACT_UNSUPPORTED_OPENAPI_VERSION` | The document was not OpenAPI 3.0 or 3.1. | Provide an OpenAPI 3.0/3.1 document. |
|
|
287
|
+
| `CONTRACT_NO_ELIGIBLE_OPERATIONS` | No eligible `paths` operations with responses were found. | Add path operations with responses. |
|
|
288
|
+
| `CONTRACT_OPERATION_NO_RESPONSES` | A `paths` operation had no response definitions. | Add at least one OpenAPI response to each path operation. |
|
|
289
|
+
| `CONTRACT_UNRESOLVED_REF` | A ref remained unresolved after secure bundling. | Fix the ref target or make the external ref HTTPS-accessible. |
|
|
290
|
+
| `CONTRACT_UNSUPPORTED_SCHEMA_DIALECT` | A schema declared an unsupported JSON Schema dialect. | Use draft-07 or 2020-12-compatible schemas. |
|
|
291
|
+
| `CONTRACT_SCHEMA_COMPILE_FAILED` | schemasafe could not compile a response/header schema. | Simplify or correct the unsupported schema. |
|
|
292
|
+
| `CONTRACT_STATIC_REQUEST_CHECK_FAILED` | Generated request missed a required non-security parameter or body. | Adjust generation options or the spec so generated requests include required shape. |
|
|
293
|
+
| `CONTRACT_SECURITY_NOT_VALIDATED` | Security requirements were detected but dynamic tests cannot prove auth at runtime. | Run dedicated auth tests and review generated requests for required credentials. |
|
|
294
|
+
| `CONTRACT_WEBHOOKS_NOT_VALIDATED` | OpenAPI webhooks were present but are not included in dynamic contract coverage. | Validate webhook behavior separately or model required behavior under `paths`. |
|
|
295
|
+
| `CONTRACT_CALLBACKS_NOT_VALIDATED` | Operation callbacks were present but are not included in dynamic contract coverage. | Validate callback behavior separately or add dedicated tests. |
|
|
296
|
+
| `CONTRACT_COOKIE_PARAM_NOT_VALIDATED` | A required cookie parameter cannot be included in generated requests, and the runtime test asserts its presence, so the contract run fails until the cookie is supplied at send time. | Attach the cookie via the cookie jar or a `Cookie` header in the run setup, or move the parameter to a header/query location. |
|
|
297
|
+
| `CONTRACT_OPERATION_DEPRECATED` | A covered operation is marked `deprecated: true` in the OpenAPI document. | Plan removal of the deprecated operation or drop it from the spec when retired. |
|
|
298
|
+
| `CONTRACT_REQUEST_BODY_INCOMPLETE` | A parseable generated request body is missing top-level required properties. | Fix the spec example or regenerate the collection so generated bodies satisfy the request schema. |
|
|
299
|
+
| `CONTRACT_READONLY_PROPERTY_IN_REQUEST` | A generated request body includes properties the schema marks `readOnly`. | Remove readOnly properties from request examples; they belong in responses. |
|
|
300
|
+
| `CONTRACT_UNDOCUMENTED_QUERY_PARAM` | A generated request sends a query parameter the operation does not declare. | Declare the parameter in the OpenAPI operation or remove it from the generated request. |
|
|
301
|
+
| `CONTRACT_LINKS_NOT_VALIDATED` | Response links were present but link traversal is not part of dynamic contract coverage. | Validate linked operation chains with dedicated workflow tests. |
|
|
302
|
+
| `CONTRACT_PARAM_SERIALIZATION_NOT_VALIDATED` | A parameter declares `allowReserved`, `content`, or a style/explode combination the runtime cannot decode. Exploded `form` arrays and non-exploded `form`/`spaceDelimited`/`pipeDelimited` arrays of scalars are decoded and validated, so they no longer warn. | Validate the remaining serialized forms with dedicated tests. |
|
|
303
|
+
| `CONTRACT_NONJSON_SCHEMA_NOT_VALIDATED` | A non-JSON response media type declares an object schema that runtime tests cannot validate. | Validate XML or other non-JSON payloads with dedicated tests; Content-Type and body presence are still checked. |
|
|
304
|
+
| `CONTRACT_REQUEST_SCHEMA_NOT_VALIDATED` | A JSON request body schema could not be compiled into a runtime request validator. | Simplify the unsupported request schema construct named in the warning. |
|
|
305
|
+
| `CONTRACT_SCHEMA_NOT_COMPILED` | One schema could not be compiled by the validator engine, so its runtime check is skipped. | Review the named schema construct; other checks for the operation still run. |
|
|
306
|
+
| `CONTRACT_EXAMPLE_SCHEMA_MISMATCH` | A media-type example does not validate against its own schema. | Fix the example or the schema so the spec is self-consistent; generated requests are built from these examples. |
|
|
307
|
+
| `CONTRACT_ENCODING_MISMATCH` | A generated form-body field does not match its OpenAPI encoding object: a declared multipart per-part `contentType` is missing or different, a binary-typed field was not generated as a file part, or a field declaring a JSON `contentType` carries an unparseable value. | Regenerate the collection or align the encoding object with the intended part layout. |
|
|
308
|
+
| `CONTRACT_ENCODING_HEADERS_NOT_VALIDATED` | A multipart encoding object declares per-part `headers`, which Postman formdata entries cannot carry, so they are not asserted. | Validate per-part headers with dedicated tests if the server depends on them. |
|
|
309
|
+
| `CONTRACT_FORM_FIELD_SCHEMA_MISMATCH` | A generated urlencoded or multipart text value does not validate against its scalar property schema. | Fix the spec example feeding the generated body, or correct the property schema. |
|
|
310
|
+
| `CONTRACT_DISCRIMINATOR_NOT_VALIDATED` | A `discriminator` has no sibling `oneOf`/`anyOf` of internal `$ref` members (typically allOf-parent inheritance), so its dispatch is not validated. | Restructure to the oneOf-plus-discriminator form, or rely on the still-validated composition keywords. |
|
|
311
|
+
| `CONTRACT_HEADER_SCHEMA_NOT_VALIDATED` | A response header declares an object or otherwise undecodable schema, so its serialized value is checked for presence only. Arrays of scalars are split on commas and validated. | Use a scalar or array-of-scalars header schema, or validate the serialized header form with dedicated tests. |
|
|
312
|
+
| `CONTRACT_PATH_PARAM_NOT_VALIDATED` | A path parameter declares a non-scalar schema or a serialization the runtime cannot decode, so its value is not validated. Scalar path parameters are validated at runtime against the resolved path segment. | Use a scalar path schema, or validate path value semantics with dedicated tests. |
|
|
313
|
+
| `CONTRACT_DUPLICATE_OPERATION_MATCH` | Multiple OpenAPI operations share the same canonical request mapping candidate. | Disambiguate paths, server prefixes, or templated routes. |
|
|
314
|
+
| `CONTRACT_DUPLICATE_OPERATION_REQUEST` | More than one generated request mapped to the same contract operation. | Disambiguate paths/operations or generated requests. |
|
|
315
|
+
| `CONTRACT_OPERATION_COVERAGE_FAILED` | Generated contract collection did not cover every eligible operation. | Regenerate the collection or fix operation paths. |
|
|
316
|
+
| `CONTRACT_FORBIDDEN_SCRIPT_CONSTRUCT` | Generated script included a forbidden dynamic validation construct. | Report the schema that triggered unsafe generation. |
|
|
317
|
+
| `CONTRACT_SCRIPT_SIZE_EXCEEDED` | A generated request test script exceeded the per-script size gate. | Reduce schema complexity or split the API. |
|
|
318
|
+
| `CONTRACT_COLLECTION_SIZE_EXCEEDED` | Instrumented contract collection exceeded the size gate. | Reduce schema/operation count or split the API. |
|
|
319
|
+
| `CONTRACT_COLLECTION_ID_COLLISION` | Baseline, smoke, and contract IDs were not pairwise distinct. | Pass distinct collection IDs or clear stale IDs. |
|
|
320
|
+
| `CONTRACT_PLAN_MISSING` | Contract instrumentation ran without a preflight-generated contract plan. | Rerun with dynamic contract preflight enabled and report the failure if it persists. |
|
|
321
|
+
| `CONTRACT_SPEC_ROLLBACK_FAILED` | Best-effort previous spec restoration failed after a later error. | Restore the previous spec content manually using the emitted SHA-256. |
|
|
561
322
|
|
|
562
|
-
##
|
|
323
|
+
## Resources
|
|
563
324
|
|
|
564
|
-
|
|
565
|
-
npm install
|
|
566
|
-
npm test
|
|
567
|
-
npm run typecheck
|
|
568
|
-
npm run build
|
|
569
|
-
```
|
|
325
|
+
Sibling actions in the Postman onboarding pipeline:
|
|
570
326
|
|
|
571
|
-
|
|
327
|
+
- [postman-cs/postman-api-onboarding-action](https://github.com/postman-cs/postman-api-onboarding-action): composite action that orchestrates the pipeline
|
|
328
|
+
- [postman-cs/postman-resolve-service-token-action](https://github.com/postman-cs/postman-resolve-service-token-action): mints a service-account access token and team ID
|
|
329
|
+
- [postman-cs/postman-aws-spec-discovery-action](https://github.com/postman-cs/postman-aws-spec-discovery-action): discovers AWS APIs and specs
|
|
330
|
+
- [postman-cs/postman-smoke-flow-action](https://github.com/postman-cs/postman-smoke-flow-action): applies a curated flow.yaml to the Smoke collection
|
|
331
|
+
- [postman-cs/postman-repo-sync-action](https://github.com/postman-cs/postman-repo-sync-action): syncs artifacts, environments, mocks, and monitors
|
|
332
|
+
- [postman-cs/postman-insights-onboarding-action](https://github.com/postman-cs/postman-insights-onboarding-action): links Insights to the workspace
|
|
572
333
|
|
|
573
|
-
|
|
334
|
+
Package and docs:
|
|
574
335
|
|
|
575
|
-
-
|
|
576
|
-
-
|
|
577
|
-
-
|
|
336
|
+
- npm package: [@postman-cse/onboarding-bootstrap](https://www.npmjs.com/package/@postman-cse/onboarding-bootstrap)
|
|
337
|
+
- [Postman API documentation](https://learning.postman.com/docs/developer/postman-api/intro-api/)
|
|
338
|
+
- [Postman Spec Hub](https://learning.postman.com/docs/design-apis/specifications/overview/)
|
|
339
|
+
- Local development: `npm install`, `npm test`, `npm run typecheck`, `npm run build` (produces the committed `dist/` bundles used by `action.yml`); regenerate the Inputs and Outputs tables with `npm run docs:tables`
|
|
578
340
|
|
|
579
|
-
##
|
|
341
|
+
## License
|
|
580
342
|
|
|
581
|
-
|
|
343
|
+
[MIT](LICENSE)
|