@postman-cse/onboarding-repo-sync 2.1.19 → 2.3.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/README.md +16 -1
- package/action.yml +16 -0
- package/dist/action.cjs +216 -22
- package/dist/cli.cjs +216 -22
- package/dist/index.cjs +216 -22
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -113,7 +113,16 @@ with:
|
|
|
113
113
|
monitor-id: 1e2f3a4b-monitor-id
|
|
114
114
|
```
|
|
115
115
|
|
|
116
|
-
Repo-sync
|
|
116
|
+
Repo-sync defaults to public mocks for anonymous validation. Set `mock-visibility: private` for teams that prohibit public mocks. Explicit, discovered, and newly created mocks must match the requested visibility and the expected baseline collection/environment; unknown visibility, stale URLs, and identity mismatches fail before `mock-url` is emitted. For private mocks, repo-sync emits `mock-auth-required: true` and installs a secret-free request hook in the smoke and contract collections. The runner must supply its PMAK as the transient `postmanPrivateMockApiKey` variable. Repo-sync never writes that credential to a collection, environment, output, or repository artifact.
|
|
117
|
+
|
|
118
|
+
For manual collection validation against the resolved mock, opt in to a dedicated Postman environment:
|
|
119
|
+
|
|
120
|
+
```yaml
|
|
121
|
+
with:
|
|
122
|
+
mock-environment-enabled: true
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
On canonical and legacy runs, the action creates or reuses `<project> - Mock`, sets its `baseUrl` to the validated mock URL, and emits `mock-environment-uid`. Preview and channel runs skip it so branch retention cleanup cannot leak an untracked environment. Its exported representation lives at `postman/mocks/manual-validation.postman_environment.json`; it is deliberately excluded from `environment-uids-json`, system-environment associations, monitors, and generated CI environment selection. Select it explicitly when running baseline, Smoke, or Contract collections manually. Repo-sync never replaces the runtime `prod` or `dev` `baseUrl` with a mock URL.
|
|
117
126
|
|
|
118
127
|
### mTLS certificates for Postman CLI runs
|
|
119
128
|
|
|
@@ -146,6 +155,8 @@ with:
|
|
|
146
155
|
| `release-label` | Optional release label used for versioned naming. | no | |
|
|
147
156
|
| `monitor-id` | Existing smoke monitor ID. When set, the action validates and reuses this monitor instead of creating a new one. | no | |
|
|
148
157
|
| `mock-url` | Existing mock server URL. When set, the action validates and reuses this mock instead of creating a new one. | no | |
|
|
158
|
+
| `mock-visibility` | Required mock access policy. Public is anonymous; private requires a runtime x-api-key supplied by the caller and is never persisted by repo-sync. | no | `public` |
|
|
159
|
+
| `mock-environment-enabled` | Create or update a dedicated manual-validation environment whose baseUrl is the validated mock URL. This environment is excluded from runtime CI selection and never contains a mock credential. | no | `false` |
|
|
149
160
|
| `monitor-cron` | Cron expression for monitor scheduling (e.g. '0 */6 * * *'). When empty, the monitor is created disabled and triggered to run once per workflow invocation (and once on every subsequent run). | no | `""` |
|
|
150
161
|
| `environments-json` | JSON array of environment slugs to create or update. | no | `["prod"]` |
|
|
151
162
|
| `git-provider` | Git provider override ('github', 'gitlab', 'bitbucket', 'azure-devops'). Auto-detected from environment when omitted. | no | |
|
|
@@ -193,6 +204,10 @@ with:
|
|
|
193
204
|
| `environment-sync-status` | Whether environment sync succeeded, was skipped, or failed. |
|
|
194
205
|
| `environment-uids-json` | JSON map of environment slug to Postman environment uid. |
|
|
195
206
|
| `mock-url` | Created or reused mock server URL. |
|
|
207
|
+
| `mock-visibility` | Authoritatively observed mock visibility: public or private. |
|
|
208
|
+
| `mock-auth-required` | Whether the collection runner must supply postmanPrivateMockApiKey at runtime. |
|
|
209
|
+
| `mock-environment-uid` | Dedicated manual-validation environment UID when mock-environment-enabled succeeds. |
|
|
210
|
+
| `mock-environment-status` | Whether the optional manual-validation mock environment succeeded, was skipped, or failed. |
|
|
196
211
|
| `monitor-id` | Created or reused smoke monitor ID. |
|
|
197
212
|
| `repo-sync-summary-json` | JSON summary of repo materialization and workspace sync outputs. |
|
|
198
213
|
| `commit-sha` | Commit SHA produced by repo-write-mode, if any. |
|
package/action.yml
CHANGED
|
@@ -57,6 +57,14 @@ inputs:
|
|
|
57
57
|
mock-url:
|
|
58
58
|
description: Existing mock server URL. When set, the action validates and reuses this mock instead of creating a new one.
|
|
59
59
|
required: false
|
|
60
|
+
mock-visibility:
|
|
61
|
+
description: Required mock access policy. Public is anonymous; private requires a runtime x-api-key supplied by the caller and is never persisted by repo-sync.
|
|
62
|
+
required: false
|
|
63
|
+
default: public
|
|
64
|
+
mock-environment-enabled:
|
|
65
|
+
description: Create or update a dedicated manual-validation environment whose baseUrl is the validated mock URL. This environment is excluded from runtime CI selection and never contains a mock credential.
|
|
66
|
+
required: false
|
|
67
|
+
default: "false"
|
|
60
68
|
monitor-cron:
|
|
61
69
|
description: Cron expression for monitor scheduling (e.g. '0 */6 * * *'). When empty, the monitor is created disabled and triggered to run once per workflow invocation (and once on every subsequent run).
|
|
62
70
|
required: false
|
|
@@ -200,6 +208,14 @@ outputs:
|
|
|
200
208
|
description: JSON map of environment slug to Postman environment uid.
|
|
201
209
|
mock-url:
|
|
202
210
|
description: Created or reused mock server URL.
|
|
211
|
+
mock-visibility:
|
|
212
|
+
description: "Authoritatively observed mock visibility: public or private."
|
|
213
|
+
mock-auth-required:
|
|
214
|
+
description: Whether the collection runner must supply postmanPrivateMockApiKey at runtime.
|
|
215
|
+
mock-environment-uid:
|
|
216
|
+
description: Dedicated manual-validation environment UID when mock-environment-enabled succeeds.
|
|
217
|
+
mock-environment-status:
|
|
218
|
+
description: Whether the optional manual-validation mock environment succeeded, was skipped, or failed.
|
|
203
219
|
monitor-id:
|
|
204
220
|
description: Created or reused smoke monitor ID.
|
|
205
221
|
repo-sync-summary-json:
|
package/dist/action.cjs
CHANGED
|
@@ -136660,6 +136660,17 @@ var postmanRepoSyncActionContract = {
|
|
|
136660
136660
|
description: "Existing mock server URL. When set, the action validates and reuses this mock instead of creating a new one.",
|
|
136661
136661
|
required: false
|
|
136662
136662
|
},
|
|
136663
|
+
"mock-visibility": {
|
|
136664
|
+
description: "Required mock access policy. Public is anonymous; private requires a runtime x-api-key supplied by the caller and is never persisted by repo-sync.",
|
|
136665
|
+
required: false,
|
|
136666
|
+
default: "public",
|
|
136667
|
+
allowedValues: ["public", "private"]
|
|
136668
|
+
},
|
|
136669
|
+
"mock-environment-enabled": {
|
|
136670
|
+
description: "Create or update a dedicated manual-validation environment whose baseUrl is the validated mock URL. This environment is excluded from runtime CI selection and never contains a mock credential.",
|
|
136671
|
+
required: false,
|
|
136672
|
+
default: "false"
|
|
136673
|
+
},
|
|
136663
136674
|
"monitor-cron": {
|
|
136664
136675
|
description: "Cron expression for monitor scheduling (e.g. '0 */6 * * *'). When empty, the monitor is created disabled and triggered to run once per workflow invocation (and once on every subsequent run).",
|
|
136665
136676
|
required: false,
|
|
@@ -136853,6 +136864,18 @@ var postmanRepoSyncActionContract = {
|
|
|
136853
136864
|
"mock-url": {
|
|
136854
136865
|
description: "Created or reused mock server URL."
|
|
136855
136866
|
},
|
|
136867
|
+
"mock-visibility": {
|
|
136868
|
+
description: "Authoritatively observed mock visibility: public or private."
|
|
136869
|
+
},
|
|
136870
|
+
"mock-auth-required": {
|
|
136871
|
+
description: "Whether the collection runner must supply postmanPrivateMockApiKey at runtime."
|
|
136872
|
+
},
|
|
136873
|
+
"mock-environment-uid": {
|
|
136874
|
+
description: "Dedicated manual-validation environment UID when mock-environment-enabled succeeds."
|
|
136875
|
+
},
|
|
136876
|
+
"mock-environment-status": {
|
|
136877
|
+
description: "Whether the optional manual-validation mock environment succeeded, was skipped, or failed."
|
|
136878
|
+
},
|
|
136856
136879
|
"monitor-id": {
|
|
136857
136880
|
description: "Created or reused smoke monitor ID."
|
|
136858
136881
|
},
|
|
@@ -136947,19 +136970,30 @@ var MockContractError = class extends Error {
|
|
|
136947
136970
|
this.name = "MockContractError";
|
|
136948
136971
|
}
|
|
136949
136972
|
};
|
|
136950
|
-
function
|
|
136951
|
-
if (mock.visibility === "
|
|
136973
|
+
function requireMockVisibility(mock, requested) {
|
|
136974
|
+
if (mock.visibility === "unknown") {
|
|
136952
136975
|
throw new MockContractError(
|
|
136953
|
-
`
|
|
136976
|
+
`MOCK_VISIBILITY_UNKNOWN: Mock ${mock.uid} did not expose a supported visibility field. Refusing to assume it is callable.`
|
|
136954
136977
|
);
|
|
136955
136978
|
}
|
|
136956
|
-
if (mock.visibility !==
|
|
136979
|
+
if (mock.visibility !== requested) {
|
|
136980
|
+
const code = requested === "public" ? "MOCK_NOT_PUBLIC" : "MOCK_NOT_PRIVATE";
|
|
136957
136981
|
throw new MockContractError(
|
|
136958
|
-
|
|
136982
|
+
`${code}: Mock ${mock.uid} is ${mock.visibility}, but mock-visibility requires ${requested}. Change the mock visibility in Postman or set mock-visibility to ${mock.visibility}.`
|
|
136959
136983
|
);
|
|
136960
136984
|
}
|
|
136961
136985
|
return mock;
|
|
136962
136986
|
}
|
|
136987
|
+
var PRIVATE_MOCK_AUTH_MARKER = "postman-enterprise-automation: private-mock-auth";
|
|
136988
|
+
var PRIVATE_MOCK_AUTH_VARIABLE = "postmanPrivateMockApiKey";
|
|
136989
|
+
var PRIVATE_MOCK_AUTH_SCRIPT = [
|
|
136990
|
+
`// ${PRIVATE_MOCK_AUTH_MARKER}`,
|
|
136991
|
+
`var privateMockApiKey = pm.variables.get('${PRIVATE_MOCK_AUTH_VARIABLE}');`,
|
|
136992
|
+
"var privateMockHost = String(pm.request.url && pm.request.url.getHost ? pm.request.url.getHost() : '');",
|
|
136993
|
+
"if (privateMockApiKey && /(^|\\.)mock\\.pstmn\\.io$/i.test(privateMockHost)) {",
|
|
136994
|
+
" pm.request.headers.upsert({ key: 'x-api-key', value: privateMockApiKey });",
|
|
136995
|
+
"}"
|
|
136996
|
+
].join("\n");
|
|
136963
136997
|
var MAX_CREATE_FLIGHTS = 256;
|
|
136964
136998
|
var createFlights = /* @__PURE__ */ new Map();
|
|
136965
136999
|
var PostmanGatewayAssetsClient = class {
|
|
@@ -137467,22 +137501,22 @@ var PostmanGatewayAssetsClient = class {
|
|
|
137467
137501
|
return data?.collection ?? null;
|
|
137468
137502
|
}
|
|
137469
137503
|
// --- mocks (service: mock) ---
|
|
137470
|
-
async createMock(workspaceId, name, collectionUid, environmentUid) {
|
|
137504
|
+
async createMock(workspaceId, name, collectionUid, environmentUid, requestedVisibility = "public") {
|
|
137471
137505
|
const ws = workspaceId || this.workspaceId;
|
|
137472
137506
|
const mockName = String(name ?? "").trim();
|
|
137473
137507
|
const collection = String(collectionUid ?? "").trim();
|
|
137474
137508
|
const environment = String(environmentUid ?? "").trim();
|
|
137475
|
-
const flightKey = `mock:${ws}:${collection}:${environment}:${mockName}`;
|
|
137509
|
+
const flightKey = `mock:${ws}:${collection}:${environment}:${requestedVisibility}:${mockName}`;
|
|
137476
137510
|
return this.singleFlight(flightKey, flightKey, "mock", async () => {
|
|
137477
137511
|
const existing = await this.findMockByCollection(collection, environment, mockName);
|
|
137478
137512
|
if (existing) {
|
|
137479
|
-
const reusable =
|
|
137480
|
-
return { uid: reusable.uid, url: reusable.mockUrl };
|
|
137513
|
+
const reusable = requireMockVisibility(existing, requestedVisibility);
|
|
137514
|
+
return { uid: reusable.uid, url: reusable.mockUrl, visibility: requestedVisibility };
|
|
137481
137515
|
}
|
|
137482
137516
|
const body = {
|
|
137483
137517
|
name: mockName,
|
|
137484
137518
|
collection,
|
|
137485
|
-
private:
|
|
137519
|
+
private: requestedVisibility === "private",
|
|
137486
137520
|
...environment ? { environment } : {}
|
|
137487
137521
|
};
|
|
137488
137522
|
const send2 = (fallback) => this.gateway.requestJson(
|
|
@@ -137500,12 +137534,14 @@ var PostmanGatewayAssetsClient = class {
|
|
|
137500
137534
|
);
|
|
137501
137535
|
const parseMock = (response) => {
|
|
137502
137536
|
const record = this.dataOf(response);
|
|
137503
|
-
const created =
|
|
137504
|
-
this.decodeMockRecord(record, "Mock create")
|
|
137537
|
+
const created = requireMockVisibility(
|
|
137538
|
+
this.decodeMockRecord(record, "Mock create"),
|
|
137539
|
+
requestedVisibility
|
|
137505
137540
|
);
|
|
137506
137541
|
return {
|
|
137507
137542
|
uid: created.uid,
|
|
137508
|
-
url: created.mockUrl
|
|
137543
|
+
url: created.mockUrl,
|
|
137544
|
+
visibility: requestedVisibility
|
|
137509
137545
|
};
|
|
137510
137546
|
};
|
|
137511
137547
|
try {
|
|
@@ -137516,8 +137552,8 @@ var PostmanGatewayAssetsClient = class {
|
|
|
137516
137552
|
error2
|
|
137517
137553
|
);
|
|
137518
137554
|
if (adopted) {
|
|
137519
|
-
const reusable =
|
|
137520
|
-
return { uid: reusable.uid, url: reusable.mockUrl };
|
|
137555
|
+
const reusable = requireMockVisibility(adopted, requestedVisibility);
|
|
137556
|
+
return { uid: reusable.uid, url: reusable.mockUrl, visibility: requestedVisibility };
|
|
137521
137557
|
}
|
|
137522
137558
|
if (adopted === void 0) {
|
|
137523
137559
|
const retried = await this.resendAbsentCreate(async () => parseMock(await send2("auto")));
|
|
@@ -137527,6 +137563,51 @@ var PostmanGatewayAssetsClient = class {
|
|
|
137527
137563
|
}
|
|
137528
137564
|
});
|
|
137529
137565
|
}
|
|
137566
|
+
/**
|
|
137567
|
+
* Add a secret-free runtime hook to every HTTP request in a collection. The
|
|
137568
|
+
* PMAK value is supplied only by the runner as a transient variable; this
|
|
137569
|
+
* method persists the variable name and header wiring, never the credential.
|
|
137570
|
+
*/
|
|
137571
|
+
async configurePrivateMockRuntimeAuth(collectionUid) {
|
|
137572
|
+
const cid = String(collectionUid ?? "").trim();
|
|
137573
|
+
if (!cid) return 0;
|
|
137574
|
+
const listed = await this.gateway.requestJson({
|
|
137575
|
+
service: "collection",
|
|
137576
|
+
method: "get",
|
|
137577
|
+
path: `/v3/collections/${cid}/items/`
|
|
137578
|
+
});
|
|
137579
|
+
const items = Array.isArray(listed?.data) ? listed.data : [];
|
|
137580
|
+
let patched = 0;
|
|
137581
|
+
for (const listedItem of items) {
|
|
137582
|
+
if (String(listedItem.$kind ?? "") !== "http-request") continue;
|
|
137583
|
+
const itemId = String(listedItem.id ?? "").trim();
|
|
137584
|
+
if (!itemId) continue;
|
|
137585
|
+
const response = await this.gateway.requestJson({
|
|
137586
|
+
service: "collection",
|
|
137587
|
+
method: "get",
|
|
137588
|
+
path: `/v3/collections/${cid}/items/${itemId}`,
|
|
137589
|
+
headers: { "X-Entity-Type": "http-request" }
|
|
137590
|
+
});
|
|
137591
|
+
const item = this.asRecord(response?.data) ?? listedItem;
|
|
137592
|
+
const scripts = Array.isArray(item.scripts) ? item.scripts.filter((entry) => Boolean(this.asRecord(entry))) : [];
|
|
137593
|
+
const before = scripts.find((script) => String(script.type ?? "") === "beforeRequest");
|
|
137594
|
+
if (String(before?.code ?? "").includes(PRIVATE_MOCK_AUTH_MARKER)) continue;
|
|
137595
|
+
const code = [String(before?.code ?? "").trim(), PRIVATE_MOCK_AUTH_SCRIPT].filter(Boolean).join("\n");
|
|
137596
|
+
const nextScripts = [
|
|
137597
|
+
...scripts.filter((script) => String(script.type ?? "") !== "beforeRequest"),
|
|
137598
|
+
{ type: "beforeRequest", code, language: "text/javascript" }
|
|
137599
|
+
];
|
|
137600
|
+
await this.gateway.requestJson({
|
|
137601
|
+
service: "collection",
|
|
137602
|
+
method: "patch",
|
|
137603
|
+
path: `/v3/collections/${cid}/items/${itemId}`,
|
|
137604
|
+
headers: { "X-Entity-Type": "http-request" },
|
|
137605
|
+
body: [{ op: "add", path: "/scripts", value: nextScripts }]
|
|
137606
|
+
});
|
|
137607
|
+
patched += 1;
|
|
137608
|
+
}
|
|
137609
|
+
return patched;
|
|
137610
|
+
}
|
|
137530
137611
|
async listMocks() {
|
|
137531
137612
|
const response = await this.gateway.requestJson({
|
|
137532
137613
|
service: "mock",
|
|
@@ -138541,7 +138622,7 @@ function normalizeMockUrl(value, source) {
|
|
|
138541
138622
|
url.pathname = url.pathname.replace(/\/+$/g, "") || "/";
|
|
138542
138623
|
return url.toString();
|
|
138543
138624
|
}
|
|
138544
|
-
function
|
|
138625
|
+
function resolveExplicitMock(mocks, explicitUrl, collectionUid, environmentUid, requestedVisibility) {
|
|
138545
138626
|
const normalized = normalizeMockUrl(explicitUrl, "mock-url");
|
|
138546
138627
|
const matches = mocks.filter(
|
|
138547
138628
|
(mock) => normalizeMockUrl(mock.mockUrl, `mock ${mock.uid} URL`) === normalized
|
|
@@ -138567,7 +138648,7 @@ function resolveExplicitPublicMock(mocks, explicitUrl, collectionUid, environmen
|
|
|
138567
138648
|
`EXPLICIT_MOCK_IDENTITY_MISMATCH: Mock ${match.uid} references environment ${match.environment || "(none)"}, expected ${environmentUid}`
|
|
138568
138649
|
);
|
|
138569
138650
|
}
|
|
138570
|
-
return
|
|
138651
|
+
return requireMockVisibility(match, requestedVisibility);
|
|
138571
138652
|
}
|
|
138572
138653
|
function shouldRetryMockCreate(error2) {
|
|
138573
138654
|
if (error2 instanceof MockContractError) return false;
|
|
@@ -138679,6 +138760,15 @@ function parseCredentialPreflight(value) {
|
|
|
138679
138760
|
`Unsupported credential-preflight "${normalized}". Supported values: ${allowed.join(", ")}`
|
|
138680
138761
|
);
|
|
138681
138762
|
}
|
|
138763
|
+
function parseMockVisibility(value) {
|
|
138764
|
+
const definition = postmanRepoSyncActionContract.inputs["mock-visibility"];
|
|
138765
|
+
const allowed = definition.allowedValues ?? [];
|
|
138766
|
+
const normalized = String(value || "").trim() || (definition.default ?? "public");
|
|
138767
|
+
if (allowed.includes(normalized)) return normalized;
|
|
138768
|
+
throw new Error(
|
|
138769
|
+
`Unsupported mock-visibility "${normalized}". Supported values: ${allowed.join(", ")}`
|
|
138770
|
+
);
|
|
138771
|
+
}
|
|
138682
138772
|
function parseBranchStrategy(value) {
|
|
138683
138773
|
const definition = postmanRepoSyncActionContract.inputs["branch-strategy"];
|
|
138684
138774
|
const allowed = definition.allowedValues ?? [];
|
|
@@ -138785,6 +138875,8 @@ function resolveInputs(env = process.env) {
|
|
|
138785
138875
|
orgMode: parseBooleanInput(getInput2("org-mode", env), false),
|
|
138786
138876
|
monitorId: getInput2("monitor-id", env),
|
|
138787
138877
|
mockUrl: getInput2("mock-url", env),
|
|
138878
|
+
mockVisibility: parseMockVisibility(getInput2("mock-visibility", env)),
|
|
138879
|
+
mockEnvironmentEnabled: parseBooleanInput(getInput2("mock-environment-enabled", env), false),
|
|
138788
138880
|
monitorCron: getInput2("monitor-cron", env),
|
|
138789
138881
|
sslClientCert: getInput2("ssl-client-cert", env),
|
|
138790
138882
|
sslClientKey: getInput2("ssl-client-key", env),
|
|
@@ -139011,6 +139103,10 @@ function createOutputs(inputs) {
|
|
|
139011
139103
|
"environment-sync-status": "skipped",
|
|
139012
139104
|
"environment-uids-json": JSON.stringify(inputs.environmentUids),
|
|
139013
139105
|
"mock-url": "",
|
|
139106
|
+
"mock-visibility": "",
|
|
139107
|
+
"mock-auth-required": "false",
|
|
139108
|
+
"mock-environment-uid": "",
|
|
139109
|
+
"mock-environment-status": "skipped",
|
|
139014
139110
|
"monitor-id": "",
|
|
139015
139111
|
"repo-sync-summary-json": "{}",
|
|
139016
139112
|
"commit-sha": "",
|
|
@@ -139078,6 +139174,8 @@ function readActionInputs(actionCore) {
|
|
|
139078
139174
|
INPUT_ORG_MODE: readInput(actionCore, "org-mode"),
|
|
139079
139175
|
INPUT_MONITOR_ID: readInput(actionCore, "monitor-id"),
|
|
139080
139176
|
INPUT_MOCK_URL: readInput(actionCore, "mock-url"),
|
|
139177
|
+
INPUT_MOCK_VISIBILITY: readInput(actionCore, "mock-visibility"),
|
|
139178
|
+
INPUT_MOCK_ENVIRONMENT_ENABLED: readInput(actionCore, "mock-environment-enabled"),
|
|
139081
139179
|
INPUT_MONITOR_CRON: readInput(actionCore, "monitor-cron"),
|
|
139082
139180
|
INPUT_SSL_CLIENT_CERT: sslClientCert,
|
|
139083
139181
|
INPUT_SSL_CLIENT_KEY: sslClientKey,
|
|
@@ -139279,6 +139377,52 @@ async function upsertEnvironments(inputs, dependencies, resourcesState, assetMar
|
|
|
139279
139377
|
}
|
|
139280
139378
|
return envUids;
|
|
139281
139379
|
}
|
|
139380
|
+
async function upsertMockEnvironment(inputs, dependencies, assetProjectName, mockUrl) {
|
|
139381
|
+
if (!inputs.mockEnvironmentEnabled || !inputs.workspaceId || !mockUrl) {
|
|
139382
|
+
return "";
|
|
139383
|
+
}
|
|
139384
|
+
const displayName = `${assetProjectName} - Mock`;
|
|
139385
|
+
const values = buildEnvironmentValues("mock", mockUrl);
|
|
139386
|
+
const mask = resolveRepoSyncMasker(dependencies);
|
|
139387
|
+
try {
|
|
139388
|
+
const discovered = await dependencies.postman.findEnvironmentByName(
|
|
139389
|
+
inputs.workspaceId,
|
|
139390
|
+
displayName
|
|
139391
|
+
);
|
|
139392
|
+
if (discovered?.uid) {
|
|
139393
|
+
try {
|
|
139394
|
+
const existing = await dependencies.postman.getEnvironment(discovered.uid);
|
|
139395
|
+
const currentValues = existing.data?.values ?? existing.values ?? [];
|
|
139396
|
+
if (currentValues.some((value) => value.key === "baseUrl" && value.value === mockUrl)) {
|
|
139397
|
+
dependencies.core.info(`Mock environment already points to ${mockUrl}: ${discovered.uid}`);
|
|
139398
|
+
return discovered.uid;
|
|
139399
|
+
}
|
|
139400
|
+
} catch {
|
|
139401
|
+
}
|
|
139402
|
+
await dependencies.postman.updateEnvironment(discovered.uid, displayName, values);
|
|
139403
|
+
dependencies.core.info(`Updated mock environment ${displayName}: ${discovered.uid}`);
|
|
139404
|
+
return discovered.uid;
|
|
139405
|
+
}
|
|
139406
|
+
const uid = await dependencies.postman.createEnvironment(
|
|
139407
|
+
inputs.workspaceId,
|
|
139408
|
+
displayName,
|
|
139409
|
+
values
|
|
139410
|
+
);
|
|
139411
|
+
dependencies.core.info(`Created mock environment ${displayName}: ${uid}`);
|
|
139412
|
+
return uid;
|
|
139413
|
+
} catch (error2) {
|
|
139414
|
+
dependencies.core.warning(
|
|
139415
|
+
formatOrchestrationIssue({
|
|
139416
|
+
operation: "Mock environment upsert",
|
|
139417
|
+
entity: `workspace ${inputs.workspaceId} environment "${displayName}"`,
|
|
139418
|
+
cause: error2,
|
|
139419
|
+
remediation: "verify environment access or disable mock-environment-enabled then rerun",
|
|
139420
|
+
mask
|
|
139421
|
+
})
|
|
139422
|
+
);
|
|
139423
|
+
return "";
|
|
139424
|
+
}
|
|
139425
|
+
}
|
|
139282
139426
|
function ensureDir(path9) {
|
|
139283
139427
|
(0, import_node_fs5.mkdirSync)(path9, { recursive: true });
|
|
139284
139428
|
}
|
|
@@ -139917,6 +140061,13 @@ async function exportArtifacts(inputs, dependencies, envUids, assetProjectName,
|
|
|
139917
140061
|
true
|
|
139918
140062
|
);
|
|
139919
140063
|
}
|
|
140064
|
+
if (options.mockEnvironmentUid) {
|
|
140065
|
+
writeJsonFile(
|
|
140066
|
+
`${mocksDir}/manual-validation.postman_environment.json`,
|
|
140067
|
+
await dependencies.postman.getEnvironment(options.mockEnvironmentUid),
|
|
140068
|
+
true
|
|
140069
|
+
);
|
|
140070
|
+
}
|
|
139920
140071
|
const durableWorkspaceId = resolveDurableWorkspaceId({
|
|
139921
140072
|
candidateId: inputs.workspaceId,
|
|
139922
140073
|
priorId: options.priorWorkspaceId,
|
|
@@ -139975,7 +140126,11 @@ function createRepoSummary(outputs, envUids, pushed) {
|
|
|
139975
140126
|
commitSha: outputs["commit-sha"],
|
|
139976
140127
|
environmentCount: Object.keys(envUids).length,
|
|
139977
140128
|
environmentSyncStatus: outputs["environment-sync-status"],
|
|
140129
|
+
mockEnvironmentStatus: outputs["mock-environment-status"],
|
|
140130
|
+
mockEnvironmentUid: outputs["mock-environment-uid"],
|
|
140131
|
+
mockAuthRequired: outputs["mock-auth-required"] === "true",
|
|
139978
140132
|
mockUrl: outputs["mock-url"],
|
|
140133
|
+
mockVisibility: outputs["mock-visibility"],
|
|
139979
140134
|
monitorId: outputs["monitor-id"],
|
|
139980
140135
|
pushed,
|
|
139981
140136
|
resolvedCurrentRef: outputs["resolved-current-ref"],
|
|
@@ -140203,6 +140358,7 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
140203
140358
|
const mockEnvUid = envUids.dev || envUids.prod || Object.values(envUids)[0];
|
|
140204
140359
|
if (mockEnvUid) {
|
|
140205
140360
|
let resolvedMockUrl = "";
|
|
140361
|
+
let resolvedMockVisibility = "";
|
|
140206
140362
|
const mockName = `${assetProjectName} Mock`;
|
|
140207
140363
|
if (inputs.mockUrl) {
|
|
140208
140364
|
let mocks;
|
|
@@ -140220,12 +140376,15 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
140220
140376
|
{ cause: error2 }
|
|
140221
140377
|
);
|
|
140222
140378
|
}
|
|
140223
|
-
|
|
140379
|
+
const resolved = resolveExplicitMock(
|
|
140224
140380
|
mocks,
|
|
140225
140381
|
inputs.mockUrl,
|
|
140226
140382
|
inputs.baselineCollectionId,
|
|
140227
|
-
mockEnvUid
|
|
140228
|
-
|
|
140383
|
+
mockEnvUid,
|
|
140384
|
+
inputs.mockVisibility
|
|
140385
|
+
);
|
|
140386
|
+
resolvedMockUrl = resolved.mockUrl;
|
|
140387
|
+
resolvedMockVisibility = resolved.visibility;
|
|
140229
140388
|
dependencies.core.info(`Reusing mock from explicit input: ${resolvedMockUrl}`);
|
|
140230
140389
|
}
|
|
140231
140390
|
if (!resolvedMockUrl && inputs.baselineCollectionId) {
|
|
@@ -140249,7 +140408,9 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
140249
140408
|
);
|
|
140250
140409
|
}
|
|
140251
140410
|
if (discovered) {
|
|
140252
|
-
|
|
140411
|
+
const resolved = requireMockVisibility(discovered, inputs.mockVisibility);
|
|
140412
|
+
resolvedMockUrl = resolved.mockUrl;
|
|
140413
|
+
resolvedMockVisibility = resolved.visibility;
|
|
140253
140414
|
dependencies.core.info(`Discovered existing mock for collection ${inputs.baselineCollectionId}: ${resolvedMockUrl}`);
|
|
140254
140415
|
}
|
|
140255
140416
|
}
|
|
@@ -140262,7 +140423,8 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
140262
140423
|
inputs.workspaceId,
|
|
140263
140424
|
mockName,
|
|
140264
140425
|
inputs.baselineCollectionId,
|
|
140265
|
-
mockEnvUid
|
|
140426
|
+
mockEnvUid,
|
|
140427
|
+
inputs.mockVisibility
|
|
140266
140428
|
),
|
|
140267
140429
|
{
|
|
140268
140430
|
maxAttempts: 3,
|
|
@@ -140284,6 +140446,7 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
140284
140446
|
}
|
|
140285
140447
|
);
|
|
140286
140448
|
resolvedMockUrl = mock.url;
|
|
140449
|
+
resolvedMockVisibility = mock.visibility ?? inputs.mockVisibility;
|
|
140287
140450
|
dependencies.core.info(`Created new mock: ${resolvedMockUrl}`);
|
|
140288
140451
|
} catch (error2) {
|
|
140289
140452
|
throw new Error(
|
|
@@ -140299,7 +140462,37 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
140299
140462
|
}
|
|
140300
140463
|
}
|
|
140301
140464
|
outputs["mock-url"] = resolvedMockUrl;
|
|
140465
|
+
outputs["mock-visibility"] = resolvedMockVisibility;
|
|
140466
|
+
outputs["mock-auth-required"] = String(resolvedMockVisibility === "private");
|
|
140302
140467
|
dependencies.core.setOutput("mock-url", resolvedMockUrl);
|
|
140468
|
+
dependencies.core.setOutput("mock-visibility", resolvedMockVisibility);
|
|
140469
|
+
dependencies.core.setOutput("mock-auth-required", outputs["mock-auth-required"]);
|
|
140470
|
+
if (resolvedMockVisibility === "private") {
|
|
140471
|
+
if (!dependencies.postman.configurePrivateMockRuntimeAuth) {
|
|
140472
|
+
throw new Error(
|
|
140473
|
+
"PRIVATE_MOCK_RUNTIME_AUTH_UNAVAILABLE: The Postman client cannot configure runtime x-api-key injection."
|
|
140474
|
+
);
|
|
140475
|
+
}
|
|
140476
|
+
for (const collectionUid of [inputs.smokeCollectionId, inputs.contractCollectionId]) {
|
|
140477
|
+
if (collectionUid) {
|
|
140478
|
+
await dependencies.postman.configurePrivateMockRuntimeAuth(collectionUid);
|
|
140479
|
+
}
|
|
140480
|
+
}
|
|
140481
|
+
}
|
|
140482
|
+
if (inputs.mockEnvironmentEnabled && isCanonicalWriter) {
|
|
140483
|
+
const mockEnvironmentUid = await upsertMockEnvironment(
|
|
140484
|
+
inputs,
|
|
140485
|
+
dependencies,
|
|
140486
|
+
assetProjectName,
|
|
140487
|
+
resolvedMockUrl
|
|
140488
|
+
);
|
|
140489
|
+
outputs["mock-environment-uid"] = mockEnvironmentUid;
|
|
140490
|
+
outputs["mock-environment-status"] = mockEnvironmentUid ? "success" : "failed";
|
|
140491
|
+
} else if (inputs.mockEnvironmentEnabled) {
|
|
140492
|
+
dependencies.core.warning(
|
|
140493
|
+
"mock-environment-enabled is skipped for preview and channel runs so manual-validation environments cannot escape branch retention cleanup."
|
|
140494
|
+
);
|
|
140495
|
+
}
|
|
140303
140496
|
}
|
|
140304
140497
|
}
|
|
140305
140498
|
if (inputs.workspaceId && inputs.smokeCollectionId && Object.keys(envUids).length > 0) {
|
|
@@ -140432,6 +140625,7 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
140432
140625
|
workspaceLinkStatus: outputs["workspace-link-status"],
|
|
140433
140626
|
priorWorkspaceId: resourcesState?.workspace?.id,
|
|
140434
140627
|
existingSpecs: resourcesState?.cloudResources?.specs,
|
|
140628
|
+
mockEnvironmentUid: outputs["mock-environment-uid"] || void 0,
|
|
140435
140629
|
releaseLabel,
|
|
140436
140630
|
priorState: resourcesState,
|
|
140437
140631
|
preparedPrebuiltCollections
|