@postman-cse/onboarding-bootstrap 0.9.1 → 0.10.0
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/.github/workflows/contract-smoke.yml +155 -0
- package/.omc/sessions/b36ac16d-ce26-4e94-ae7e-dd817f2430a3.json +8 -0
- package/CLAUDE.md +57 -0
- package/README.md +124 -12
- package/action.yml +17 -18
- package/dist/cli.cjs +231 -489
- package/dist/index.cjs +226 -480
- package/package.json +3 -2
- package/src/cli.ts +5 -11
- package/src/contracts.ts +24 -24
- package/src/index.ts +253 -323
- package/src/lib/postman/postman-assets-client.ts +27 -4
- package/tests/bootstrap-action.test.ts +565 -79
- package/tests/cli.test.ts +12 -6
- package/tests/contract.test.ts +20 -3
- package/tests/postman-assets-client.test.ts +153 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
name: Contract Smoke Tests
|
|
2
|
+
on:
|
|
3
|
+
schedule:
|
|
4
|
+
- cron: '0 8 * * *' # daily at 8 AM UTC
|
|
5
|
+
workflow_dispatch: {}
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
bootstrap-smoke:
|
|
9
|
+
name: Bootstrap API Contract
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
- uses: actions/setup-node@v4
|
|
14
|
+
with:
|
|
15
|
+
node-version: '20'
|
|
16
|
+
- name: Verify GET /me (org-mode key)
|
|
17
|
+
env:
|
|
18
|
+
PMAK: ${{ secrets.SMOKE_ORG_API_KEY }}
|
|
19
|
+
run: |
|
|
20
|
+
set -euo pipefail
|
|
21
|
+
response=$(curl -sf -H "X-Api-Key: $PMAK" https://api.getpostman.com/me)
|
|
22
|
+
echo "$response" | jq -e '.user.teamId' > /dev/null || { echo "CONTRACT DRIFT: GET /me missing user.teamId"; exit 1; }
|
|
23
|
+
echo "GET /me: user.teamId=$(echo "$response" | jq -r '.user.teamId')"
|
|
24
|
+
|
|
25
|
+
- name: Verify GET /me (non-org key)
|
|
26
|
+
env:
|
|
27
|
+
PMAK: ${{ secrets.SMOKE_NON_ORG_API_KEY }}
|
|
28
|
+
run: |
|
|
29
|
+
set -euo pipefail
|
|
30
|
+
response=$(curl -sf -H "X-Api-Key: $PMAK" https://api.getpostman.com/me)
|
|
31
|
+
echo "$response" | jq -e '.user.teamId' > /dev/null || { echo "CONTRACT DRIFT: GET /me missing user.teamId"; exit 1; }
|
|
32
|
+
echo "GET /me: user.teamId=$(echo "$response" | jq -r '.user.teamId')"
|
|
33
|
+
|
|
34
|
+
- name: Verify GET /teams (org-mode key)
|
|
35
|
+
env:
|
|
36
|
+
PMAK: ${{ secrets.SMOKE_ORG_API_KEY }}
|
|
37
|
+
run: |
|
|
38
|
+
set -euo pipefail
|
|
39
|
+
response=$(curl -sf -H "X-Api-Key: $PMAK" https://api.getpostman.com/teams)
|
|
40
|
+
echo "$response" | jq -e '.data | type == "array"' > /dev/null || { echo "CONTRACT DRIFT: GET /teams .data is not an array"; exit 1; }
|
|
41
|
+
count=$(echo "$response" | jq '.data | length')
|
|
42
|
+
echo "GET /teams: $count teams returned"
|
|
43
|
+
if [ "$count" -gt 1 ]; then
|
|
44
|
+
# Org-mode: verify organizationId is present on at least one team
|
|
45
|
+
org_count=$(echo "$response" | jq '[.data[] | select(.organizationId != null)] | length')
|
|
46
|
+
if [ "$org_count" -eq 0 ]; then
|
|
47
|
+
echo "CONTRACT DRIFT: GET /teams returned $count teams but none have organizationId"
|
|
48
|
+
exit 1
|
|
49
|
+
fi
|
|
50
|
+
echo "GET /teams: $org_count teams have organizationId"
|
|
51
|
+
# Verify required fields
|
|
52
|
+
echo "$response" | jq -e '.data[] | select(.id and .name)' > /dev/null || { echo "CONTRACT DRIFT: team items missing id or name"; exit 1; }
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
- name: Verify GET /teams (non-org key)
|
|
56
|
+
env:
|
|
57
|
+
PMAK: ${{ secrets.SMOKE_NON_ORG_API_KEY }}
|
|
58
|
+
run: |
|
|
59
|
+
set -euo pipefail
|
|
60
|
+
response=$(curl -sf -H "X-Api-Key: $PMAK" https://api.getpostman.com/teams)
|
|
61
|
+
echo "$response" | jq -e '.data | type == "array"' > /dev/null || { echo "CONTRACT DRIFT: GET /teams .data is not an array"; exit 1; }
|
|
62
|
+
count=$(echo "$response" | jq '.data | length')
|
|
63
|
+
echo "GET /teams: $count teams (non-org, expecting 0 or 1)"
|
|
64
|
+
|
|
65
|
+
- name: Verify POST /workspaces with teamId (org-mode)
|
|
66
|
+
env:
|
|
67
|
+
PMAK: ${{ secrets.SMOKE_ORG_API_KEY }}
|
|
68
|
+
WORKSPACE_TEAM_ID: ${{ vars.SMOKE_WORKSPACE_TEAM_ID }}
|
|
69
|
+
run: |
|
|
70
|
+
set -euo pipefail
|
|
71
|
+
ts=$(date +%s)
|
|
72
|
+
response=$(curl -sf -X POST \
|
|
73
|
+
-H "X-Api-Key: $PMAK" \
|
|
74
|
+
-H "Content-Type: application/json" \
|
|
75
|
+
-d "{\"workspace\":{\"name\":\"__smoke_test_${ts}\",\"type\":\"team\",\"description\":\"Contract smoke test - safe to delete\",\"teamId\":${WORKSPACE_TEAM_ID}}}" \
|
|
76
|
+
https://api.getpostman.com/workspaces)
|
|
77
|
+
ws_id=$(echo "$response" | jq -r '.workspace.id')
|
|
78
|
+
if [ -z "$ws_id" ] || [ "$ws_id" = "null" ]; then
|
|
79
|
+
echo "CONTRACT DRIFT: POST /workspaces did not return workspace.id"
|
|
80
|
+
echo "Response: $response"
|
|
81
|
+
exit 1
|
|
82
|
+
fi
|
|
83
|
+
echo "POST /workspaces: created workspace $ws_id"
|
|
84
|
+
|
|
85
|
+
# Cleanup
|
|
86
|
+
curl -sf -X DELETE -H "X-Api-Key: $PMAK" "https://api.getpostman.com/workspaces/$ws_id" > /dev/null
|
|
87
|
+
echo "Cleanup: deleted workspace $ws_id"
|
|
88
|
+
|
|
89
|
+
- name: Verify POST /workspaces without teamId (non-org)
|
|
90
|
+
env:
|
|
91
|
+
PMAK: ${{ secrets.SMOKE_NON_ORG_API_KEY }}
|
|
92
|
+
run: |
|
|
93
|
+
set -euo pipefail
|
|
94
|
+
ts=$(date +%s)
|
|
95
|
+
response=$(curl -sf -X POST \
|
|
96
|
+
-H "X-Api-Key: $PMAK" \
|
|
97
|
+
-H "Content-Type: application/json" \
|
|
98
|
+
-d "{\"workspace\":{\"name\":\"__smoke_test_${ts}\",\"type\":\"team\",\"description\":\"Contract smoke test - safe to delete\"}}" \
|
|
99
|
+
https://api.getpostman.com/workspaces)
|
|
100
|
+
ws_id=$(echo "$response" | jq -r '.workspace.id')
|
|
101
|
+
if [ -z "$ws_id" ] || [ "$ws_id" = "null" ]; then
|
|
102
|
+
echo "CONTRACT DRIFT: POST /workspaces (no teamId) did not return workspace.id"
|
|
103
|
+
echo "Response: $response"
|
|
104
|
+
exit 1
|
|
105
|
+
fi
|
|
106
|
+
echo "POST /workspaces (no teamId): created workspace $ws_id"
|
|
107
|
+
|
|
108
|
+
# Cleanup
|
|
109
|
+
curl -sf -X DELETE -H "X-Api-Key: $PMAK" "https://api.getpostman.com/workspaces/$ws_id" > /dev/null
|
|
110
|
+
echo "Cleanup: deleted workspace $ws_id"
|
|
111
|
+
|
|
112
|
+
bifrost-smoke:
|
|
113
|
+
name: Bifrost API Contract
|
|
114
|
+
runs-on: ubuntu-latest
|
|
115
|
+
steps:
|
|
116
|
+
- uses: actions/checkout@v4
|
|
117
|
+
- name: Verify Bifrost API key creation
|
|
118
|
+
env:
|
|
119
|
+
ACCESS_TOKEN: ${{ secrets.SMOKE_ORG_ACCESS_TOKEN }}
|
|
120
|
+
run: |
|
|
121
|
+
set -euo pipefail
|
|
122
|
+
ts=$(date +%s)
|
|
123
|
+
response=$(curl -sf -X POST \
|
|
124
|
+
-H "x-access-token: $ACCESS_TOKEN" \
|
|
125
|
+
-H "Content-Type: application/json" \
|
|
126
|
+
-d "{\"method\":\"POST\",\"path\":\"/scim/v2/keys\",\"body\":{\"name\":\"smoke-test-${ts}\",\"description\":\"Contract smoke - safe to delete\"}}" \
|
|
127
|
+
https://bifrost-premium-https-v4.gw.postman.com)
|
|
128
|
+
# Verify PMAK-shaped key returned
|
|
129
|
+
key=$(echo "$response" | jq -r '.apikey.key // .key // empty')
|
|
130
|
+
if [ -z "$key" ]; then
|
|
131
|
+
echo "CONTRACT DRIFT: Bifrost API key creation did not return apikey.key"
|
|
132
|
+
echo "Response: $(echo "$response" | head -c 500)"
|
|
133
|
+
exit 1
|
|
134
|
+
fi
|
|
135
|
+
echo "Bifrost key creation: key starts with $(echo "$key" | head -c 10)..."
|
|
136
|
+
|
|
137
|
+
session-smoke:
|
|
138
|
+
name: Session Validation Contract
|
|
139
|
+
runs-on: ubuntu-latest
|
|
140
|
+
steps:
|
|
141
|
+
- uses: actions/checkout@v4
|
|
142
|
+
- name: Verify iapub session endpoint
|
|
143
|
+
env:
|
|
144
|
+
ACCESS_TOKEN: ${{ secrets.SMOKE_ORG_ACCESS_TOKEN }}
|
|
145
|
+
run: |
|
|
146
|
+
set -euo pipefail
|
|
147
|
+
response=$(curl -sf \
|
|
148
|
+
-H "x-access-token: $ACCESS_TOKEN" \
|
|
149
|
+
https://iapub.postman.co/api/sessions/current)
|
|
150
|
+
echo "$response" | jq -e '.session.identity.team' > /dev/null || {
|
|
151
|
+
echo "CONTRACT DRIFT: iapub session endpoint missing session.identity.team"
|
|
152
|
+
echo "Response shape: $(echo "$response" | jq 'keys')"
|
|
153
|
+
exit 1
|
|
154
|
+
}
|
|
155
|
+
echo "Session validation: team=$(echo "$response" | jq -r '.session.identity.team')"
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# postman-bootstrap-action
|
|
2
|
+
|
|
3
|
+
Creates or reuses a Postman workspace, uploads/updates an OpenAPI spec to Spec Hub, generates baseline/smoke/contract collections, assigns governance, and persists repo variables. Dual entry: GitHub Action (`dist/index.cjs`) and CLI (`dist/cli.cjs`).
|
|
4
|
+
|
|
5
|
+
## Structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
src/
|
|
9
|
+
index.ts # Main orchestration: inputs -> workspace -> spec -> collections -> lint -> outputs
|
|
10
|
+
cli.ts # CLI adapter: reads flags/env, wraps runBootstrap(), writes JSON/dotenv
|
|
11
|
+
contracts.ts # Input/output type definitions
|
|
12
|
+
lib/
|
|
13
|
+
postman/
|
|
14
|
+
postman-assets-client.ts # Custom Postman API client (workspaces, specs, collections, envs, users)
|
|
15
|
+
internal-integration-adapter.ts # Bifrost proxy adapter (governance, workspace linking, system envs)
|
|
16
|
+
workspace-selection.ts # Canonical workspace resolution (new vs existing, fallback to repo vars)
|
|
17
|
+
github/
|
|
18
|
+
github-api-client.ts # GitHub repo variable read/write, workflow file APIs
|
|
19
|
+
repo/
|
|
20
|
+
context.ts # Auto-detect repo URL, provider, branch from CI env vars
|
|
21
|
+
retry.ts # Exponential backoff
|
|
22
|
+
secrets.ts # Secret masking utility
|
|
23
|
+
http-error.ts # Typed HTTP error class
|
|
24
|
+
tests/ # vitest unit tests
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Commands
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm ci && npm test && npm run typecheck && npm run build
|
|
31
|
+
npm run check:dist # build + git diff --exit-code (CI integrity)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Key Behaviors
|
|
35
|
+
|
|
36
|
+
- **Workspace selection**: Checks input `workspace-id` -> repo variable `POSTMAN_WORKSPACE_ID` -> creates new. Canonical workspace validation uses access-token via Bifrost.
|
|
37
|
+
- **Spec normalization**: Before upload, fixes missing/long `summary` fields in OpenAPI operations to prevent downstream collection generation failures.
|
|
38
|
+
- **Collection generation**: Calls `POST /specs/{id}/generations/collection` to create baseline/smoke/contract collections. Injects generated tests and applies tags.
|
|
39
|
+
- **Lint**: Installs Postman CLI, runs `postman spec lint` against uploaded spec UID, parses JSON output for errors/warnings.
|
|
40
|
+
- **Team ID**: Auto-derived from `GET /me` using the API key. `POSTMAN_TEAM_ID` env var overrides.
|
|
41
|
+
- **Repo variables**: Persists `POSTMAN_WORKSPACE_ID`, `POSTMAN_SPEC_UID`, collection UIDs, lint counts as GitHub repo variables for rerun idempotency.
|
|
42
|
+
|
|
43
|
+
## Postman API Endpoints Used
|
|
44
|
+
|
|
45
|
+
- `POST /workspaces`, `GET /workspaces` -- workspace CRUD
|
|
46
|
+
- `POST /specs`, `PATCH /specs/{id}/files/{path}` -- spec upload/update
|
|
47
|
+
- `POST /specs/{id}/generations/collection` -- collection generation
|
|
48
|
+
- `GET /collections/{id}`, `PUT /collections/{id}` -- collection update/test injection
|
|
49
|
+
- `PUT /collections/{id}/tags` -- collection tagging
|
|
50
|
+
- `GET /me` -- team ID derivation
|
|
51
|
+
- Bifrost: governance assignment, workspace-to-repo linking
|
|
52
|
+
|
|
53
|
+
## Gotchas
|
|
54
|
+
|
|
55
|
+
- `postman-assets-client.ts` has a DEPRECATED URL normalization alias -- do not extend it
|
|
56
|
+
- Spec upload re-serializes JSON/YAML; original bytes are preserved only when no normalization is needed
|
|
57
|
+
- `@actions/core` is used directly for GitHub Actions; CLI mode uses `ConsoleReporter` (logs to stderr, JSON to stdout)
|
package/README.md
CHANGED
|
@@ -12,8 +12,9 @@ This action preserves the bootstrap slice of the API Catalog demo flow:
|
|
|
12
12
|
- upload or update a remote spec in Spec Hub (after normalizing operation summaries — see below)
|
|
13
13
|
- lint the uploaded spec by UID with the Postman CLI
|
|
14
14
|
- generate missing baseline, smoke, and contract collections or reuse existing ones
|
|
15
|
+
- optionally refresh current collections from the latest spec or create release-scoped spec and collection assets
|
|
15
16
|
- inject generated tests and apply collection tags
|
|
16
|
-
-
|
|
17
|
+
- reuse committed `.postman/resources.yaml` state from the checked-out ref when present
|
|
17
18
|
|
|
18
19
|
The public open-alpha contract uses kebab-case inputs and outputs and defaults `integration-backend` to `bifrost`.
|
|
19
20
|
|
|
@@ -22,12 +23,55 @@ The public open-alpha contract uses kebab-case inputs and outputs and defaults `
|
|
|
22
23
|
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.
|
|
23
24
|
The public open-alpha contract uses kebab-case inputs and outputs and defaults `integration-backend` to `bifrost`.
|
|
24
25
|
|
|
25
|
-
For existing services, pass `workspace-id`, `spec-id`, and any existing collection IDs to rerun the bootstrap safely without creating duplicate Postman assets. When
|
|
26
|
+
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.
|
|
27
|
+
|
|
28
|
+
Lifecycle behavior remains backward-compatible except for collection default mode:
|
|
29
|
+
|
|
30
|
+
- `collection-sync-mode: refresh`
|
|
31
|
+
- `spec-sync-mode: update`
|
|
32
|
+
|
|
33
|
+
If you do not set those inputs, the action refreshes collection pointers from the resolved spec and keeps one canonical spec update path.
|
|
26
34
|
|
|
27
35
|
### Team ID derivation
|
|
28
36
|
|
|
29
37
|
The action automatically derives the Postman Team ID from your `postman-api-key` via the `/me` API. There is no need to supply a separate team ID input. If the environment variable `POSTMAN_TEAM_ID` is set, that value takes precedence.
|
|
30
38
|
|
|
39
|
+
### Org-mode teams
|
|
40
|
+
|
|
41
|
+
Postman organizations with multiple sub-teams (squads) require an explicit `workspace-team-id` to create workspaces. The Postman API does not allow workspace creation at the organization level -- a specific sub-team must own each workspace.
|
|
42
|
+
|
|
43
|
+
**How it works:**
|
|
44
|
+
|
|
45
|
+
1. The action calls `GET /teams` to check if the API key belongs to an org-mode account.
|
|
46
|
+
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.
|
|
47
|
+
3. Set `workspace-team-id` to the desired sub-team ID to proceed.
|
|
48
|
+
|
|
49
|
+
**Example (GitHub Actions):**
|
|
50
|
+
|
|
51
|
+
```yaml
|
|
52
|
+
- uses: postman-cs/postman-bootstrap-action@v0
|
|
53
|
+
with:
|
|
54
|
+
project-name: core-payments
|
|
55
|
+
spec-url: https://example.com/openapi.yaml
|
|
56
|
+
workspace-team-id: '132319'
|
|
57
|
+
postman-api-key: ${{ secrets.POSTMAN_API_KEY }}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
To persist the sub-team ID across runs, store it as a repository variable:
|
|
61
|
+
|
|
62
|
+
```yaml
|
|
63
|
+
workspace-team-id: ${{ vars.POSTMAN_WORKSPACE_TEAM_ID }}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**CLI usage:**
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
postman-bootstrap --workspace-team-id 132319 ...
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Or via environment variable: `export POSTMAN_WORKSPACE_TEAM_ID=132319`
|
|
73
|
+
|
|
74
|
+
Non-org accounts (single team) are unaffected and do not need this input.
|
|
31
75
|
### OpenAPI operation summaries (normalization)
|
|
32
76
|
|
|
33
77
|
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:
|
|
@@ -56,13 +100,9 @@ jobs:
|
|
|
56
100
|
requester-email: owner@example.com
|
|
57
101
|
workspace-admin-user-ids: 101,102
|
|
58
102
|
spec-url: https://example.com/openapi.yaml
|
|
59
|
-
environments-json: '["prod","stage"]'
|
|
60
|
-
system-env-map-json: '{"prod":"uuid-prod","stage":"uuid-stage"}'
|
|
61
103
|
governance-mapping-json: '{"core-banking":"Core Banking"}'
|
|
62
104
|
postman-api-key: ${{ secrets.POSTMAN_API_KEY }}
|
|
63
105
|
postman-access-token: ${{ secrets.POSTMAN_ACCESS_TOKEN }}
|
|
64
|
-
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
65
|
-
gh-fallback-token: ${{ secrets.GH_FALLBACK_TOKEN }}
|
|
66
106
|
|
|
67
107
|
bootstrap-existing:
|
|
68
108
|
runs-on: ubuntu-latest
|
|
@@ -80,7 +120,7 @@ jobs:
|
|
|
80
120
|
postman-api-key: ${{ secrets.POSTMAN_API_KEY }}
|
|
81
121
|
```
|
|
82
122
|
|
|
83
|
-
If you want the action to discover prior bootstrap state automatically on reruns,
|
|
123
|
+
If you want the action to discover prior bootstrap state automatically on reruns, commit `.postman/resources.yaml` and run the action on the ref whose state you want to reuse.
|
|
84
124
|
|
|
85
125
|
## CLI Usage (Non-GitHub CI)
|
|
86
126
|
|
|
@@ -162,22 +202,94 @@ steps:
|
|
|
162
202
|
| `baseline-collection-id` | | Reuse an existing baseline collection. |
|
|
163
203
|
| `smoke-collection-id` | | Reuse an existing smoke collection. |
|
|
164
204
|
| `contract-collection-id` | | Reuse an existing contract collection. |
|
|
205
|
+
| `collection-sync-mode` | `refresh` | Collection lifecycle policy. `reuse` keeps existing collections, `refresh` regenerates the current collection set from the latest spec, and `version` creates or reuses release-scoped collections. |
|
|
206
|
+
| `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. |
|
|
207
|
+
| `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. |
|
|
165
208
|
| `project-name` | | Service name used in workspace and asset naming. |
|
|
166
209
|
| `domain` | | Business domain used for governance assignment. |
|
|
167
210
|
| `domain-code` | | Short prefix used when constructing the workspace name. |
|
|
168
211
|
| `requester-email` | | Optional user invited into the workspace. |
|
|
169
212
|
| `workspace-admin-user-ids` | | Comma-separated Postman user IDs to grant admin access. |
|
|
213
|
+
| `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. |
|
|
170
214
|
| `spec-url` | | Required registry-backed OpenAPI document URL. |
|
|
171
|
-
| `environments-json` | `["prod"]` | Environment slugs preserved in outputs and repo variables. |
|
|
172
|
-
| `system-env-map-json` | `{}` | Map of environment slug to system environment ID. |
|
|
173
215
|
| `governance-mapping-json` | `{}` | Map of domain to governance group name. |
|
|
174
216
|
| `postman-api-key` | | Required for all Postman asset operations. |
|
|
175
217
|
| `postman-access-token` | | Required for governance assignment and canonical workspace validation during reruns. |
|
|
176
|
-
| `github-token` | | Enables repository variable persistence and rerun fallback discovery. |
|
|
177
|
-
| `gh-fallback-token` | | Optional fallback token for repository variable APIs. |
|
|
178
|
-
| `github-auth-mode` | `github_token_first` | Auth mode for repository variable APIs. |
|
|
179
218
|
| `integration-backend` | `bifrost` | Current public open-alpha backend. |
|
|
180
219
|
|
|
220
|
+
## Lifecycle Modes
|
|
221
|
+
|
|
222
|
+
### Collection sync
|
|
223
|
+
|
|
224
|
+
- `reuse`: existing collection IDs are reused when available.
|
|
225
|
+
- `refresh`: baseline, smoke, and contract collections are regenerated from the resolved spec and become the current/default collection pointers.
|
|
226
|
+
- `version`: a release-scoped collection set is created or reused from the checked-out ref's state when available.
|
|
227
|
+
|
|
228
|
+
### Spec sync
|
|
229
|
+
|
|
230
|
+
- `update`: canonical behavior. The current spec in Spec Hub is updated from `spec-url`.
|
|
231
|
+
- `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.
|
|
232
|
+
|
|
233
|
+
### Release label derivation
|
|
234
|
+
|
|
235
|
+
When versioned sync is requested and `release-label` is omitted, the action derives one using:
|
|
236
|
+
|
|
237
|
+
1. explicit `release-label`
|
|
238
|
+
2. Git tag name
|
|
239
|
+
3. branch name or ref metadata
|
|
240
|
+
|
|
241
|
+
If versioned sync is requested and no usable label can be derived, the run fails.
|
|
242
|
+
|
|
243
|
+
### Ref-native state
|
|
244
|
+
|
|
245
|
+
Current Postman asset state lives in `.postman/resources.yaml`.
|
|
246
|
+
|
|
247
|
+
- `update` and `reuse` modes resolve current-state mappings from the checked-out ref.
|
|
248
|
+
- `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.
|
|
249
|
+
|
|
250
|
+
### Contract smoke monitoring
|
|
251
|
+
|
|
252
|
+
This repo includes `.github/workflows/contract-smoke.yml`, a scheduled live contract check for the upstream Postman APIs used by bootstrap.
|
|
253
|
+
|
|
254
|
+
Configure these repository secrets before enabling the workflow:
|
|
255
|
+
|
|
256
|
+
- `SMOKE_ORG_API_KEY`
|
|
257
|
+
- `SMOKE_ORG_ACCESS_TOKEN`
|
|
258
|
+
- `SMOKE_NON_ORG_API_KEY`
|
|
259
|
+
|
|
260
|
+
Configure this repository variable for the org-mode workspace creation check:
|
|
261
|
+
|
|
262
|
+
- `SMOKE_WORKSPACE_TEAM_ID=132319`
|
|
263
|
+
|
|
264
|
+
`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.
|
|
265
|
+
|
|
266
|
+
## Versioning Examples
|
|
267
|
+
|
|
268
|
+
Refresh the current collections in place while keeping one canonical spec:
|
|
269
|
+
|
|
270
|
+
```yaml
|
|
271
|
+
- uses: postman-cs/postman-bootstrap-action@v0
|
|
272
|
+
with:
|
|
273
|
+
project-name: core-payments
|
|
274
|
+
spec-url: https://example.com/openapi.yaml
|
|
275
|
+
collection-sync-mode: refresh
|
|
276
|
+
spec-sync-mode: update
|
|
277
|
+
postman-api-key: ${{ secrets.POSTMAN_API_KEY }}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Create a versioned spec and collection set on the checked-out ref:
|
|
281
|
+
|
|
282
|
+
```yaml
|
|
283
|
+
- uses: postman-cs/postman-bootstrap-action@v0
|
|
284
|
+
with:
|
|
285
|
+
project-name: core-payments
|
|
286
|
+
spec-url: https://example.com/openapi.yaml
|
|
287
|
+
collection-sync-mode: version
|
|
288
|
+
spec-sync-mode: version
|
|
289
|
+
release-label: v1.1.1
|
|
290
|
+
postman-api-key: ${{ secrets.POSTMAN_API_KEY }}
|
|
291
|
+
```
|
|
292
|
+
|
|
181
293
|
### Obtaining `postman-api-key`
|
|
182
294
|
|
|
183
295
|
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.
|
package/action.yml
CHANGED
|
@@ -17,6 +17,17 @@ inputs:
|
|
|
17
17
|
contract-collection-id:
|
|
18
18
|
description: Existing contract collection ID
|
|
19
19
|
required: false
|
|
20
|
+
collection-sync-mode:
|
|
21
|
+
description: Collection lifecycle policy (reuse, refresh, or version)
|
|
22
|
+
required: false
|
|
23
|
+
default: refresh
|
|
24
|
+
spec-sync-mode:
|
|
25
|
+
description: Spec lifecycle policy (update or version)
|
|
26
|
+
required: false
|
|
27
|
+
default: update
|
|
28
|
+
release-label:
|
|
29
|
+
description: Optional release label used for versioned specs and collections
|
|
30
|
+
required: false
|
|
20
31
|
project-name:
|
|
21
32
|
description: Service project name
|
|
22
33
|
required: true
|
|
@@ -32,17 +43,15 @@ inputs:
|
|
|
32
43
|
workspace-admin-user-ids:
|
|
33
44
|
description: Comma-separated workspace admin user ids
|
|
34
45
|
required: false
|
|
46
|
+
workspace-team-id:
|
|
47
|
+
description: >-
|
|
48
|
+
Numeric sub-team ID for org-mode workspace creation. Required when the
|
|
49
|
+
API key belongs to an org with multiple sub-teams. Run the action without
|
|
50
|
+
this input to see available sub-teams listed in the error output.
|
|
51
|
+
required: false
|
|
35
52
|
spec-url:
|
|
36
53
|
description: URL to the OpenAPI document to bootstrap
|
|
37
54
|
required: true
|
|
38
|
-
environments-json:
|
|
39
|
-
description: JSON array of environment slugs to preserve in bootstrap outputs
|
|
40
|
-
required: false
|
|
41
|
-
default: '["prod"]'
|
|
42
|
-
system-env-map-json:
|
|
43
|
-
description: JSON map of environment slug to system environment id
|
|
44
|
-
required: false
|
|
45
|
-
default: '{}'
|
|
46
55
|
governance-mapping-json:
|
|
47
56
|
description: JSON map of business domain to governance group name
|
|
48
57
|
required: false
|
|
@@ -53,16 +62,6 @@ inputs:
|
|
|
53
62
|
postman-access-token:
|
|
54
63
|
description: Postman access token used for governance and workspace mutations
|
|
55
64
|
required: false
|
|
56
|
-
github-token:
|
|
57
|
-
description: GitHub token for repo variable persistence
|
|
58
|
-
required: false
|
|
59
|
-
gh-fallback-token:
|
|
60
|
-
description: Fallback token for repository variable APIs
|
|
61
|
-
required: false
|
|
62
|
-
github-auth-mode:
|
|
63
|
-
description: GitHub auth mode for repository variable APIs
|
|
64
|
-
required: false
|
|
65
|
-
default: github_token_first
|
|
66
65
|
integration-backend:
|
|
67
66
|
description: Integration backend for downstream workspace connectivity
|
|
68
67
|
required: false
|