@postman-cse/onboarding-repo-sync 2.1.13 → 2.1.15
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 +1 -0
- package/action.yml +4 -0
- package/dist/action.cjs +672 -90
- package/dist/cli.cjs +807 -112
- package/dist/index.cjs +674 -90
- package/package.json +2 -2
package/dist/action.cjs
CHANGED
|
@@ -26569,7 +26569,7 @@ var require_util7 = __commonJS({
|
|
|
26569
26569
|
exports2.esc = esc;
|
|
26570
26570
|
exports2.slugify = slugify;
|
|
26571
26571
|
exports2.isObject = isObject;
|
|
26572
|
-
exports2.isPlainObject =
|
|
26572
|
+
exports2.isPlainObject = isPlainObject3;
|
|
26573
26573
|
exports2.shallowClone = shallowClone;
|
|
26574
26574
|
exports2.numKeys = numKeys;
|
|
26575
26575
|
exports2.escapeRegex = escapeRegex;
|
|
@@ -26752,7 +26752,7 @@ var require_util7 = __commonJS({
|
|
|
26752
26752
|
return false;
|
|
26753
26753
|
}
|
|
26754
26754
|
});
|
|
26755
|
-
function
|
|
26755
|
+
function isPlainObject3(o) {
|
|
26756
26756
|
if (isObject(o) === false)
|
|
26757
26757
|
return false;
|
|
26758
26758
|
const ctor = o.constructor;
|
|
@@ -26769,7 +26769,7 @@ var require_util7 = __commonJS({
|
|
|
26769
26769
|
return true;
|
|
26770
26770
|
}
|
|
26771
26771
|
function shallowClone(o) {
|
|
26772
|
-
if (
|
|
26772
|
+
if (isPlainObject3(o))
|
|
26773
26773
|
return { ...o };
|
|
26774
26774
|
if (Array.isArray(o))
|
|
26775
26775
|
return [...o];
|
|
@@ -26974,7 +26974,7 @@ var require_util7 = __commonJS({
|
|
|
26974
26974
|
return clone(schema, def);
|
|
26975
26975
|
}
|
|
26976
26976
|
function extend(schema, shape) {
|
|
26977
|
-
if (!
|
|
26977
|
+
if (!isPlainObject3(shape)) {
|
|
26978
26978
|
throw new Error("Invalid input to extend: expected a plain object");
|
|
26979
26979
|
}
|
|
26980
26980
|
const checks = schema._zod.def.checks;
|
|
@@ -26997,7 +26997,7 @@ var require_util7 = __commonJS({
|
|
|
26997
26997
|
return clone(schema, def);
|
|
26998
26998
|
}
|
|
26999
26999
|
function safeExtend(schema, shape) {
|
|
27000
|
-
if (!
|
|
27000
|
+
if (!isPlainObject3(shape)) {
|
|
27001
27001
|
throw new Error("Invalid input to safeExtend: expected a plain object");
|
|
27002
27002
|
}
|
|
27003
27003
|
const def = mergeDefs(schema._zod.def, {
|
|
@@ -54816,7 +54816,7 @@ var require_lodash = __commonJS({
|
|
|
54816
54816
|
} else {
|
|
54817
54817
|
newValue = [];
|
|
54818
54818
|
}
|
|
54819
|
-
} else if (
|
|
54819
|
+
} else if (isPlainObject3(srcValue) || isArguments(srcValue)) {
|
|
54820
54820
|
newValue = objValue;
|
|
54821
54821
|
if (isArguments(objValue)) {
|
|
54822
54822
|
newValue = toPlainObject(objValue);
|
|
@@ -55780,7 +55780,7 @@ var require_lodash = __commonJS({
|
|
|
55780
55780
|
return objValue;
|
|
55781
55781
|
}
|
|
55782
55782
|
function customOmitClone(value) {
|
|
55783
|
-
return
|
|
55783
|
+
return isPlainObject3(value) ? undefined2 : value;
|
|
55784
55784
|
}
|
|
55785
55785
|
function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
|
|
55786
55786
|
var isPartial = bitmask & COMPARE_PARTIAL_FLAG, arrLength = array.length, othLength = other.length;
|
|
@@ -57281,7 +57281,7 @@ var require_lodash = __commonJS({
|
|
|
57281
57281
|
var isBuffer = nativeIsBuffer || stubFalse;
|
|
57282
57282
|
var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
|
|
57283
57283
|
function isElement(value) {
|
|
57284
|
-
return isObjectLike(value) && value.nodeType === 1 && !
|
|
57284
|
+
return isObjectLike(value) && value.nodeType === 1 && !isPlainObject3(value);
|
|
57285
57285
|
}
|
|
57286
57286
|
function isEmpty(value) {
|
|
57287
57287
|
if (value == null) {
|
|
@@ -57317,7 +57317,7 @@ var require_lodash = __commonJS({
|
|
|
57317
57317
|
return false;
|
|
57318
57318
|
}
|
|
57319
57319
|
var tag = baseGetTag(value);
|
|
57320
|
-
return tag == errorTag || tag == domExcTag || typeof value.message == "string" && typeof value.name == "string" && !
|
|
57320
|
+
return tag == errorTag || tag == domExcTag || typeof value.message == "string" && typeof value.name == "string" && !isPlainObject3(value);
|
|
57321
57321
|
}
|
|
57322
57322
|
function isFinite2(value) {
|
|
57323
57323
|
return typeof value == "number" && nativeIsFinite(value);
|
|
@@ -57368,7 +57368,7 @@ var require_lodash = __commonJS({
|
|
|
57368
57368
|
function isNumber(value) {
|
|
57369
57369
|
return typeof value == "number" || isObjectLike(value) && baseGetTag(value) == numberTag;
|
|
57370
57370
|
}
|
|
57371
|
-
function
|
|
57371
|
+
function isPlainObject3(value) {
|
|
57372
57372
|
if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
|
|
57373
57373
|
return false;
|
|
57374
57374
|
}
|
|
@@ -58439,7 +58439,7 @@ var require_lodash = __commonJS({
|
|
|
58439
58439
|
lodash.isNumber = isNumber;
|
|
58440
58440
|
lodash.isObject = isObject;
|
|
58441
58441
|
lodash.isObjectLike = isObjectLike;
|
|
58442
|
-
lodash.isPlainObject =
|
|
58442
|
+
lodash.isPlainObject = isPlainObject3;
|
|
58443
58443
|
lodash.isRegExp = isRegExp;
|
|
58444
58444
|
lodash.isSafeInteger = isSafeInteger;
|
|
58445
58445
|
lodash.isSet = isSet;
|
|
@@ -131082,7 +131082,8 @@ function getIDToken(aud) {
|
|
|
131082
131082
|
}
|
|
131083
131083
|
|
|
131084
131084
|
// src/index.ts
|
|
131085
|
-
var
|
|
131085
|
+
var import_node_crypto4 = require("node:crypto");
|
|
131086
|
+
var import_node_fs5 = require("node:fs");
|
|
131086
131087
|
var path8 = __toESM(require("node:path"), 1);
|
|
131087
131088
|
|
|
131088
131089
|
// node_modules/js-yaml/dist/js-yaml.mjs
|
|
@@ -133998,6 +133999,7 @@ function dump(input, options = {}) {
|
|
|
133998
133999
|
}
|
|
133999
134000
|
|
|
134000
134001
|
// src/postman-v3/converter.ts
|
|
134002
|
+
var import_node_fs = require("node:fs");
|
|
134001
134003
|
var fs3 = __toESM(require("node:fs/promises"), 1);
|
|
134002
134004
|
var path6 = __toESM(require("node:path"), 1);
|
|
134003
134005
|
var V2 = __toESM(require_v2(), 1);
|
|
@@ -134068,6 +134070,72 @@ function structuredCloneSafe(value) {
|
|
|
134068
134070
|
if (typeof structuredClone === "function") return structuredClone(value);
|
|
134069
134071
|
return JSON.parse(JSON.stringify(value));
|
|
134070
134072
|
}
|
|
134073
|
+
var ArtifactDigestStreamError = class extends Error {
|
|
134074
|
+
code = "ARTIFACT_DIGEST_STREAM";
|
|
134075
|
+
constructor(message, options) {
|
|
134076
|
+
super(message, options);
|
|
134077
|
+
this.name = "ArtifactDigestStreamError";
|
|
134078
|
+
}
|
|
134079
|
+
};
|
|
134080
|
+
function sameFileIdentity(left, right) {
|
|
134081
|
+
return left.dev === right.dev && left.ino === right.ino && left.size === right.size;
|
|
134082
|
+
}
|
|
134083
|
+
async function appendArtifactDigestFileStreaming(hash, relative4, absolute, expected) {
|
|
134084
|
+
const flags = typeof import_node_fs.constants.O_NOFOLLOW === "number" ? import_node_fs.constants.O_RDONLY | import_node_fs.constants.O_NOFOLLOW : import_node_fs.constants.O_RDONLY;
|
|
134085
|
+
let handle;
|
|
134086
|
+
try {
|
|
134087
|
+
handle = await fs3.open(absolute, flags);
|
|
134088
|
+
} catch (error2) {
|
|
134089
|
+
const code = error2?.code;
|
|
134090
|
+
if (code === "ELOOP" || code === "EMLINK" || code === "EINVAL") {
|
|
134091
|
+
throw new ArtifactDigestStreamError(
|
|
134092
|
+
`prebuilt collection tree file became a symlink or unsupported node at ${relative4}`,
|
|
134093
|
+
{ cause: error2 }
|
|
134094
|
+
);
|
|
134095
|
+
}
|
|
134096
|
+
throw new ArtifactDigestStreamError(
|
|
134097
|
+
`prebuilt collection tree file changed or became unsupported at ${relative4}`,
|
|
134098
|
+
{ cause: error2 }
|
|
134099
|
+
);
|
|
134100
|
+
}
|
|
134101
|
+
try {
|
|
134102
|
+
const before = await handle.stat();
|
|
134103
|
+
if (!before.isFile() || !sameFileIdentity(before, expected)) {
|
|
134104
|
+
throw new ArtifactDigestStreamError(
|
|
134105
|
+
`prebuilt collection tree file changed or became unsupported at ${relative4}`
|
|
134106
|
+
);
|
|
134107
|
+
}
|
|
134108
|
+
hash.update(relative4);
|
|
134109
|
+
hash.update("\0");
|
|
134110
|
+
const content = Buffer.allocUnsafe(expected.size);
|
|
134111
|
+
let total = 0;
|
|
134112
|
+
const buffer = Buffer.alloc(64 * 1024);
|
|
134113
|
+
for (; ; ) {
|
|
134114
|
+
const { bytesRead } = await handle.read(buffer, 0, buffer.length, null);
|
|
134115
|
+
if (bytesRead === 0) {
|
|
134116
|
+
break;
|
|
134117
|
+
}
|
|
134118
|
+
if (total + bytesRead > expected.size) {
|
|
134119
|
+
throw new ArtifactDigestStreamError(
|
|
134120
|
+
`prebuilt collection tree file changed while reading at ${relative4}`
|
|
134121
|
+
);
|
|
134122
|
+
}
|
|
134123
|
+
buffer.copy(content, total, 0, bytesRead);
|
|
134124
|
+
hash.update(buffer.subarray(0, bytesRead));
|
|
134125
|
+
total += bytesRead;
|
|
134126
|
+
}
|
|
134127
|
+
hash.update("\0");
|
|
134128
|
+
const after = await handle.stat();
|
|
134129
|
+
if (!after.isFile() || !sameFileIdentity(after, expected) || total !== expected.size) {
|
|
134130
|
+
throw new ArtifactDigestStreamError(
|
|
134131
|
+
`prebuilt collection tree file changed while reading at ${relative4}`
|
|
134132
|
+
);
|
|
134133
|
+
}
|
|
134134
|
+
return total === expected.size ? content : content.subarray(0, total);
|
|
134135
|
+
} finally {
|
|
134136
|
+
await handle.close();
|
|
134137
|
+
}
|
|
134138
|
+
}
|
|
134071
134139
|
async function listFilesRelative(dir, base) {
|
|
134072
134140
|
let entries;
|
|
134073
134141
|
try {
|
|
@@ -134628,7 +134696,7 @@ function getCiWorkflowTemplate(provider, options = {}) {
|
|
|
134628
134696
|
}
|
|
134629
134697
|
|
|
134630
134698
|
// src/lib/github/repo-mutation.ts
|
|
134631
|
-
var
|
|
134699
|
+
var import_node_fs2 = require("node:fs");
|
|
134632
134700
|
var import_node_path = __toESM(require("node:path"), 1);
|
|
134633
134701
|
|
|
134634
134702
|
// src/lib/secrets.ts
|
|
@@ -134918,7 +134986,7 @@ var RepoMutationService = class {
|
|
|
134918
134986
|
throw new Error(this.secretMasker(changed.stderr || changed.stdout || "Failed to inspect generated changes"));
|
|
134919
134987
|
}
|
|
134920
134988
|
const hasPlannedRemoval = removePaths.some(
|
|
134921
|
-
(removePath) => (0,
|
|
134989
|
+
(removePath) => (0, import_node_fs2.existsSync)(import_node_path.default.resolve(this.cwd, removePath))
|
|
134922
134990
|
);
|
|
134923
134991
|
if (!changed.stdout.trim() && !hasPlannedRemoval) {
|
|
134924
134992
|
return {
|
|
@@ -134942,7 +135010,7 @@ var RepoMutationService = class {
|
|
|
134942
135010
|
await this.execute("git", ["config", "user.name", options.committerName]);
|
|
134943
135011
|
await this.execute("git", ["config", "user.email", options.committerEmail]);
|
|
134944
135012
|
for (const removePath of removePaths) {
|
|
134945
|
-
(0,
|
|
135013
|
+
(0, import_node_fs2.rmSync)(import_node_path.default.resolve(this.cwd, removePath), { force: true });
|
|
134946
135014
|
}
|
|
134947
135015
|
await this.execute("git", ["add", "-A", "--", ...stagePaths]);
|
|
134948
135016
|
const staged = await this.execute("git", ["diff", "--cached", "--quiet"]);
|
|
@@ -135485,14 +135553,14 @@ function createTelemetryContext(options) {
|
|
|
135485
135553
|
}
|
|
135486
135554
|
|
|
135487
135555
|
// src/action-version.ts
|
|
135488
|
-
var
|
|
135556
|
+
var import_node_fs3 = require("node:fs");
|
|
135489
135557
|
var import_node_path2 = require("node:path");
|
|
135490
135558
|
function resolveActionVersion2() {
|
|
135491
135559
|
if (false) {
|
|
135492
135560
|
return void 0;
|
|
135493
135561
|
}
|
|
135494
135562
|
try {
|
|
135495
|
-
const raw = (0,
|
|
135563
|
+
const raw = (0, import_node_fs3.readFileSync)((0, import_node_path2.join)(__dirname, "..", "package.json"), "utf8");
|
|
135496
135564
|
return JSON.parse(raw).version ?? "unknown";
|
|
135497
135565
|
} catch {
|
|
135498
135566
|
return "unknown";
|
|
@@ -135731,7 +135799,8 @@ async function resolveSessionIdentity(opts) {
|
|
|
135731
135799
|
opts.fetchImpl ?? fetch,
|
|
135732
135800
|
Math.max(1, opts.maxAttempts ?? SESSION_MAX_ATTEMPTS),
|
|
135733
135801
|
opts.sleepImpl ?? defaultSessionSleep,
|
|
135734
|
-
opts.randomImpl ?? defaultRandom
|
|
135802
|
+
opts.randomImpl ?? defaultRandom,
|
|
135803
|
+
opts.onRetryEvent
|
|
135735
135804
|
);
|
|
135736
135805
|
sessionMemo.set(memoKey, pending);
|
|
135737
135806
|
}
|
|
@@ -135765,7 +135834,7 @@ async function parseSessionResponse(response) {
|
|
|
135765
135834
|
consumerType: coerceText(root.consumerType) ?? coerceText(data?.consumerType) ?? coerceText(user?.consumerType)
|
|
135766
135835
|
};
|
|
135767
135836
|
}
|
|
135768
|
-
async function probeSessionIdentity(baseUrl, accessToken, fetchImpl, maxAttempts, sleepImpl, random) {
|
|
135837
|
+
async function probeSessionIdentity(baseUrl, accessToken, fetchImpl, maxAttempts, sleepImpl, random, onRetryEvent) {
|
|
135769
135838
|
let failure = "unavailable";
|
|
135770
135839
|
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
135771
135840
|
let response;
|
|
@@ -135777,7 +135846,9 @@ async function probeSessionIdentity(baseUrl, accessToken, fetchImpl, maxAttempts
|
|
|
135777
135846
|
} catch {
|
|
135778
135847
|
failure = "unavailable";
|
|
135779
135848
|
if (attempt < maxAttempts) {
|
|
135780
|
-
|
|
135849
|
+
const delay = computeSessionRetryDelayMs(void 0, attempt, random);
|
|
135850
|
+
onRetryEvent?.({ class: "transport", attempt, delay });
|
|
135851
|
+
await sleepImpl(delay);
|
|
135781
135852
|
continue;
|
|
135782
135853
|
}
|
|
135783
135854
|
break;
|
|
@@ -135799,7 +135870,9 @@ async function probeSessionIdentity(baseUrl, accessToken, fetchImpl, maxAttempts
|
|
|
135799
135870
|
if (response.status === 429 || response.status >= 500) {
|
|
135800
135871
|
failure = "unavailable";
|
|
135801
135872
|
if (attempt < maxAttempts) {
|
|
135802
|
-
|
|
135873
|
+
const delay = computeSessionRetryDelayMs(response, attempt, random);
|
|
135874
|
+
onRetryEvent?.({ class: "http", status: response.status, attempt, delay });
|
|
135875
|
+
await sleepImpl(delay);
|
|
135803
135876
|
continue;
|
|
135804
135877
|
}
|
|
135805
135878
|
break;
|
|
@@ -135901,7 +135974,8 @@ async function runCredentialPreflight(args) {
|
|
|
135901
135974
|
accessToken,
|
|
135902
135975
|
fetchImpl: args.fetchImpl,
|
|
135903
135976
|
...args.sleepImpl ? { sleepImpl: args.sleepImpl } : {},
|
|
135904
|
-
...args.randomImpl ? { randomImpl: args.randomImpl } : {}
|
|
135977
|
+
...args.randomImpl ? { randomImpl: args.randomImpl } : {},
|
|
135978
|
+
onRetryEvent: args.retryEvent ?? args.log.retryEvent
|
|
135905
135979
|
});
|
|
135906
135980
|
} catch (error2) {
|
|
135907
135981
|
args.log.warning(
|
|
@@ -136553,6 +136627,11 @@ var postmanRepoSyncActionContract = {
|
|
|
136553
136627
|
description: "Contract collection ID used for exported artifacts.",
|
|
136554
136628
|
required: false
|
|
136555
136629
|
},
|
|
136630
|
+
"prebuilt-collections-json": {
|
|
136631
|
+
description: "Optional digest-bound JSON manifest of unique baseline, smoke, or contract roles with confined repo-relative path, SHA-256 artifact digest of the on-disk v3 collection tree (sorted relative-path + NUL + bytes + NUL), and canonical cloud ID. The optional payloadDigest field is the semantic v2 payload digest carried for provenance (format-validated only, not the reuse gate). Exact role, path, cloudId, and artifactDigest matches reuse the on-disk tree without cloud export.",
|
|
136632
|
+
required: false,
|
|
136633
|
+
default: ""
|
|
136634
|
+
},
|
|
136556
136635
|
"collection-sync-mode": {
|
|
136557
136636
|
description: "Collection sync lifecycle mode (refresh or version).",
|
|
136558
136637
|
required: false,
|
|
@@ -136795,7 +136874,7 @@ var postmanRepoSyncActionContract = {
|
|
|
136795
136874
|
"Create or update Postman environments from runtime URLs.",
|
|
136796
136875
|
"Associate Postman environments to system environments through Postman integration APIs.",
|
|
136797
136876
|
"Create mock servers and smoke monitors from generated collections.",
|
|
136798
|
-
"Export Postman collections in the Collection v3 multi-file YAML directory structure under `postman/collections/` (
|
|
136877
|
+
"Export Postman collections in the Collection v3 multi-file YAML directory structure under `postman/collections/` (canonical `.resources/definition.yaml` plus request/resource YAML files), and export environments plus `.postman/resources.yaml` into the repository.",
|
|
136799
136878
|
"Link the Postman workspace to the repository (GitHub or GitLab) through Postman integration APIs.",
|
|
136800
136879
|
"Commit synced artifacts and push them back to the current checked out ref."
|
|
136801
136880
|
],
|
|
@@ -136906,13 +136985,36 @@ var PostmanGatewayAssetsClient = class {
|
|
|
136906
136985
|
name: String(entry.name ?? entry.message ?? "").trim()
|
|
136907
136986
|
})).filter((entry) => entry.id || entry.name);
|
|
136908
136987
|
}
|
|
136988
|
+
/**
|
|
136989
|
+
* Delete a collection (GC path). DELETE is idempotent: transient 408/429/5xx
|
|
136990
|
+
* (including Bifrost ESOCKETTIMEDOUT envelopes) are retried with the same
|
|
136991
|
+
* bounded budget as other idempotent writes; 404 is success (already gone).
|
|
136992
|
+
* Ordinary 4xx are not retried.
|
|
136993
|
+
*/
|
|
136909
136994
|
async deleteCollection(collectionUid) {
|
|
136910
136995
|
const bareId = String(collectionUid).split("-").slice(-5).join("-") || collectionUid;
|
|
136911
|
-
|
|
136912
|
-
|
|
136913
|
-
|
|
136914
|
-
|
|
136915
|
-
|
|
136996
|
+
try {
|
|
136997
|
+
await retry(
|
|
136998
|
+
() => this.gateway.requestJson({
|
|
136999
|
+
service: "collection",
|
|
137000
|
+
method: "delete",
|
|
137001
|
+
path: `/v3/collections/${bareId}`
|
|
137002
|
+
}),
|
|
137003
|
+
{
|
|
137004
|
+
maxAttempts: 5,
|
|
137005
|
+
delayMs: 2e3,
|
|
137006
|
+
backoffMultiplier: 2,
|
|
137007
|
+
maxDelayMs: 15e3,
|
|
137008
|
+
sleep: this.sleep,
|
|
137009
|
+
shouldRetry: (e) => this.isRetryableIdempotentWriteOutcome(e)
|
|
137010
|
+
}
|
|
137011
|
+
);
|
|
137012
|
+
} catch (error2) {
|
|
137013
|
+
if (error2 instanceof HttpError && error2.status === 404) {
|
|
137014
|
+
return;
|
|
137015
|
+
}
|
|
137016
|
+
throw error2;
|
|
137017
|
+
}
|
|
136916
137018
|
}
|
|
136917
137019
|
async listSpecifications(workspaceId) {
|
|
136918
137020
|
const response = await this.gateway.requestJson({
|
|
@@ -137580,6 +137682,7 @@ var AccessTokenProvider = class {
|
|
|
137580
137682
|
maxAttempts;
|
|
137581
137683
|
onToken;
|
|
137582
137684
|
sleep;
|
|
137685
|
+
onRetryEvent;
|
|
137583
137686
|
inflight;
|
|
137584
137687
|
constructor(options) {
|
|
137585
137688
|
this.token = String(options.accessToken || "").trim();
|
|
@@ -137591,6 +137694,7 @@ var AccessTokenProvider = class {
|
|
|
137591
137694
|
this.maxAttempts = Math.max(1, options.maxAttempts ?? 2);
|
|
137592
137695
|
this.onToken = options.onToken;
|
|
137593
137696
|
this.sleep = options.sleep;
|
|
137697
|
+
this.onRetryEvent = options.onRetryEvent;
|
|
137594
137698
|
}
|
|
137595
137699
|
current() {
|
|
137596
137700
|
return this.token;
|
|
@@ -137616,7 +137720,12 @@ var AccessTokenProvider = class {
|
|
|
137616
137720
|
delayMs: 1e3,
|
|
137617
137721
|
backoffMultiplier: 2,
|
|
137618
137722
|
...this.sleep ? { sleep: this.sleep } : {},
|
|
137619
|
-
shouldRetry: (error2) => !(error2 instanceof MintError && error2.permanent)
|
|
137723
|
+
shouldRetry: (error2) => !(error2 instanceof MintError && error2.permanent),
|
|
137724
|
+
onRetry: ({ attempt, delayMs, error: error2 }) => {
|
|
137725
|
+
const status = error2 instanceof MintError ? error2.status : void 0;
|
|
137726
|
+
const retryClass = status === void 0 ? "transport" : "http";
|
|
137727
|
+
this.onRetryEvent?.({ class: retryClass, ...status === void 0 ? {} : { status }, attempt, delay: Math.max(0, delayMs) });
|
|
137728
|
+
}
|
|
137620
137729
|
});
|
|
137621
137730
|
this.token = token;
|
|
137622
137731
|
this.onToken?.(token);
|
|
@@ -137647,7 +137756,7 @@ var AccessTokenProvider = class {
|
|
|
137647
137756
|
true
|
|
137648
137757
|
);
|
|
137649
137758
|
}
|
|
137650
|
-
throw new MintError(`postman: re-mint failed (service-account-tokens HTTP ${status}).`, false);
|
|
137759
|
+
throw new MintError(`postman: re-mint failed (service-account-tokens HTTP ${status}).`, false, status);
|
|
137651
137760
|
}
|
|
137652
137761
|
let parsed;
|
|
137653
137762
|
try {
|
|
@@ -137678,7 +137787,8 @@ async function mintAccessTokenIfNeeded(inputs, log, setSecret2, fetchImpl = fetc
|
|
|
137678
137787
|
apiKey: inputs.postmanApiKey,
|
|
137679
137788
|
apiBaseUrl,
|
|
137680
137789
|
fetchImpl,
|
|
137681
|
-
onToken: (token) => setSecret2?.(token)
|
|
137790
|
+
onToken: (token) => setSecret2?.(token),
|
|
137791
|
+
onRetryEvent: (event) => log.retryEvent?.(event)
|
|
137682
137792
|
});
|
|
137683
137793
|
try {
|
|
137684
137794
|
inputs.postmanAccessToken = await provider.refresh();
|
|
@@ -137718,6 +137828,7 @@ var AccessTokenGatewayClient = class {
|
|
|
137718
137828
|
requestTimeoutMs;
|
|
137719
137829
|
retryMaxDelayMs;
|
|
137720
137830
|
randomImpl;
|
|
137831
|
+
onRetryEvent;
|
|
137721
137832
|
constructor(options) {
|
|
137722
137833
|
this.tokenProvider = options.tokenProvider;
|
|
137723
137834
|
this.bifrostBaseUrl = String(
|
|
@@ -137736,6 +137847,7 @@ var AccessTokenGatewayClient = class {
|
|
|
137736
137847
|
this.requestTimeoutMs = options.requestTimeoutMs ?? 3e4;
|
|
137737
137848
|
this.retryMaxDelayMs = options.retryMaxDelayMs ?? 5e3;
|
|
137738
137849
|
this.randomImpl = options.randomImpl ?? Math.random;
|
|
137850
|
+
this.onRetryEvent = options.onRetryEvent;
|
|
137739
137851
|
}
|
|
137740
137852
|
configureTeamContext(teamId, orgMode) {
|
|
137741
137853
|
this.teamId = String(teamId || "").trim();
|
|
@@ -137804,8 +137916,9 @@ var AccessTokenGatewayClient = class {
|
|
|
137804
137916
|
if (!this.fallbackBaseUrl) return false;
|
|
137805
137917
|
return retryTransient || request.fallback === "auto";
|
|
137806
137918
|
}
|
|
137807
|
-
async attemptFallback(request, retryTransient) {
|
|
137919
|
+
async attemptFallback(request, retryTransient, status) {
|
|
137808
137920
|
if (!this.fallbackEligible(request, retryTransient)) return null;
|
|
137921
|
+
this.emitRetryEvent("fallback", status, 1, 0);
|
|
137809
137922
|
const response = await this.tryFallback(request);
|
|
137810
137923
|
if (!response) return null;
|
|
137811
137924
|
if (response.ok) return response;
|
|
@@ -137831,6 +137944,7 @@ var AccessTokenGatewayClient = class {
|
|
|
137831
137944
|
} catch (error2) {
|
|
137832
137945
|
if (retryTransient && attempt < this.maxRetries) {
|
|
137833
137946
|
const delay = this.retryDelayMs(attempt);
|
|
137947
|
+
this.emitRetryEvent("transport", void 0, attempt + 1, delay);
|
|
137834
137948
|
attempt += 1;
|
|
137835
137949
|
await this.sleepImpl(delay);
|
|
137836
137950
|
continue;
|
|
@@ -137844,7 +137958,9 @@ var AccessTokenGatewayClient = class {
|
|
|
137844
137958
|
const inner = this.innerStatus(okBody);
|
|
137845
137959
|
if (inner !== void 0) {
|
|
137846
137960
|
if (retryTransient && this.isTransient(inner, okBody) && attempt < this.maxRetries) {
|
|
137847
|
-
|
|
137961
|
+
const delay = this.retryDelayMs(attempt);
|
|
137962
|
+
this.emitRetryEvent("inner", inner, attempt + 1, delay);
|
|
137963
|
+
await this.sleepImpl(delay);
|
|
137848
137964
|
attempt += 1;
|
|
137849
137965
|
continue;
|
|
137850
137966
|
}
|
|
@@ -137854,6 +137970,7 @@ var AccessTokenGatewayClient = class {
|
|
|
137854
137970
|
}
|
|
137855
137971
|
const body = await response.text().catch(() => "");
|
|
137856
137972
|
if (isExpiredAuthError(response.status, body) && this.tokenProvider.canRefresh()) {
|
|
137973
|
+
this.emitRetryEvent("auth", response.status, 1, 0);
|
|
137857
137974
|
await this.tokenProvider.refresh();
|
|
137858
137975
|
response = await this.send(request);
|
|
137859
137976
|
if (response.ok) {
|
|
@@ -137864,11 +137981,12 @@ var AccessTokenGatewayClient = class {
|
|
|
137864
137981
|
}
|
|
137865
137982
|
if (retryTransient && this.isTransient(response.status, body) && attempt < this.maxRetries) {
|
|
137866
137983
|
const delay = this.retryDelayMs(attempt, parseRetryAfterMs2(response.headers.get("retry-after")));
|
|
137984
|
+
this.emitRetryEvent("http", response.status, attempt + 1, delay);
|
|
137867
137985
|
attempt += 1;
|
|
137868
137986
|
await this.sleepImpl(delay);
|
|
137869
137987
|
continue;
|
|
137870
137988
|
}
|
|
137871
|
-
const fallbackResponse = await this.attemptFallback(request, retryTransient);
|
|
137989
|
+
const fallbackResponse = await this.attemptFallback(request, retryTransient, response.status);
|
|
137872
137990
|
if (fallbackResponse) return fallbackResponse;
|
|
137873
137991
|
throw this.toHttpError(request, response, body);
|
|
137874
137992
|
}
|
|
@@ -137876,6 +137994,14 @@ var AccessTokenGatewayClient = class {
|
|
|
137876
137994
|
retryDelayMs(attempt, retryAfter) {
|
|
137877
137995
|
return retryAfter === void 0 ? fullJitterDelayMs(attempt, this.retryBaseDelayMs, this.retryMaxDelayMs, this.randomImpl) : Math.min(this.retryMaxDelayMs, retryAfter);
|
|
137878
137996
|
}
|
|
137997
|
+
emitRetryEvent(retryClass, status, attempt, delay) {
|
|
137998
|
+
this.onRetryEvent?.({
|
|
137999
|
+
class: retryClass,
|
|
138000
|
+
...status === void 0 ? {} : { status },
|
|
138001
|
+
attempt: Math.max(1, attempt),
|
|
138002
|
+
delay: Math.max(0, delay)
|
|
138003
|
+
});
|
|
138004
|
+
}
|
|
137879
138005
|
isTransient(status, body) {
|
|
137880
138006
|
return status === 408 || status === 429 || status >= 500 || /ESOCKETTIMEDOUT|ETIMEDOUT|ECONNRESET|serverError|downstream/.test(body);
|
|
137881
138007
|
}
|
|
@@ -138005,7 +138131,7 @@ function validateCertMaterial(certBase64, keyBase64, passphrase) {
|
|
|
138005
138131
|
}
|
|
138006
138132
|
|
|
138007
138133
|
// src/lib/repo/branch-decision.ts
|
|
138008
|
-
var
|
|
138134
|
+
var import_node_fs4 = require("node:fs");
|
|
138009
138135
|
var import_node_crypto3 = require("node:crypto");
|
|
138010
138136
|
var ContractError = class extends Error {
|
|
138011
138137
|
code;
|
|
@@ -138046,7 +138172,7 @@ function readGithubEvent(env) {
|
|
|
138046
138172
|
const path9 = clean(env.GITHUB_EVENT_PATH);
|
|
138047
138173
|
if (!path9) return void 0;
|
|
138048
138174
|
try {
|
|
138049
|
-
return JSON.parse((0,
|
|
138175
|
+
return JSON.parse((0, import_node_fs4.readFileSync)(path9, "utf8"));
|
|
138050
138176
|
} catch {
|
|
138051
138177
|
return void 0;
|
|
138052
138178
|
}
|
|
@@ -138502,6 +138628,7 @@ function resolveInputs(env = process.env) {
|
|
|
138502
138628
|
baselineCollectionId: getInput2("baseline-collection-id", env),
|
|
138503
138629
|
smokeCollectionId: getInput2("smoke-collection-id", env),
|
|
138504
138630
|
contractCollectionId: getInput2("contract-collection-id", env),
|
|
138631
|
+
prebuiltCollectionsJson: getInput2("prebuilt-collections-json", env),
|
|
138505
138632
|
specId: getInput2("spec-id", env),
|
|
138506
138633
|
specContentChanged: parseBooleanInput(getInput2("spec-content-changed", env), true),
|
|
138507
138634
|
specPath: getInput2("spec-path", env),
|
|
@@ -138617,7 +138744,7 @@ var StateUnreadableError = class extends Error {
|
|
|
138617
138744
|
function readResourcesState() {
|
|
138618
138745
|
let raw;
|
|
138619
138746
|
try {
|
|
138620
|
-
raw = (0,
|
|
138747
|
+
raw = (0, import_node_fs5.readFileSync)(".postman/resources.yaml", "utf8");
|
|
138621
138748
|
} catch {
|
|
138622
138749
|
return null;
|
|
138623
138750
|
}
|
|
@@ -138676,12 +138803,15 @@ function getEnvironmentUidsFromResources(resourcesState) {
|
|
|
138676
138803
|
function normalizeToPosix(filePath) {
|
|
138677
138804
|
return filePath.split(path8.sep).join("/").replace(/\\/g, "/");
|
|
138678
138805
|
}
|
|
138806
|
+
function canonicalizeRelativePath(value) {
|
|
138807
|
+
return normalizeToPosix(String(value ?? "").trim()).replace(/^\.\/+/, "").replace(/\/{2,}/g, "/").replace(/\/+$/g, "");
|
|
138808
|
+
}
|
|
138679
138809
|
function isOpenApiSpecFile(filePath) {
|
|
138680
138810
|
if (!(filePath.endsWith(".json") || filePath.endsWith(".yaml") || filePath.endsWith(".yml"))) {
|
|
138681
138811
|
return false;
|
|
138682
138812
|
}
|
|
138683
138813
|
try {
|
|
138684
|
-
const raw = (0,
|
|
138814
|
+
const raw = (0, import_node_fs5.readFileSync)(filePath, "utf8");
|
|
138685
138815
|
const parsed = filePath.endsWith(".json") ? JSON.parse(raw) : load(raw);
|
|
138686
138816
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
138687
138817
|
return false;
|
|
@@ -138710,7 +138840,7 @@ function scanLocalSpecReferences(baseDir = ".") {
|
|
|
138710
138840
|
const found = /* @__PURE__ */ new Set();
|
|
138711
138841
|
const refs = [];
|
|
138712
138842
|
const visit2 = (currentDir) => {
|
|
138713
|
-
for (const entry of (0,
|
|
138843
|
+
for (const entry of (0, import_node_fs5.readdirSync)(currentDir, { withFileTypes: true })) {
|
|
138714
138844
|
if (ignoredDirs.has(entry.name)) {
|
|
138715
138845
|
continue;
|
|
138716
138846
|
}
|
|
@@ -138740,7 +138870,7 @@ function resolveMappedSpecReference(explicitSpecPath, discoveredSpecs) {
|
|
|
138740
138870
|
const normalizedExplicitPath = normalizeToPosix(explicitSpecPath.trim());
|
|
138741
138871
|
if (normalizedExplicitPath) {
|
|
138742
138872
|
const explicitFullPath = path8.resolve(normalizedExplicitPath);
|
|
138743
|
-
if ((0,
|
|
138873
|
+
if ((0, import_node_fs5.existsSync)(explicitFullPath) && (0, import_node_fs5.statSync)(explicitFullPath).isFile()) {
|
|
138744
138874
|
return {
|
|
138745
138875
|
repoRelativePath: normalizedExplicitPath,
|
|
138746
138876
|
configRelativePath: normalizeToPosix(path8.join("..", normalizedExplicitPath))
|
|
@@ -138792,6 +138922,7 @@ function readActionInputs(actionCore) {
|
|
|
138792
138922
|
INPUT_BASELINE_COLLECTION_ID: readInput(actionCore, "baseline-collection-id"),
|
|
138793
138923
|
INPUT_SMOKE_COLLECTION_ID: readInput(actionCore, "smoke-collection-id"),
|
|
138794
138924
|
INPUT_CONTRACT_COLLECTION_ID: readInput(actionCore, "contract-collection-id"),
|
|
138925
|
+
INPUT_PREBUILT_COLLECTIONS_JSON: readInput(actionCore, "prebuilt-collections-json"),
|
|
138795
138926
|
INPUT_SPEC_ID: readInput(actionCore, "spec-id"),
|
|
138796
138927
|
INPUT_SPEC_PATH: readInput(actionCore, "spec-path"),
|
|
138797
138928
|
INPUT_COLLECTION_SYNC_MODE: readInput(actionCore, "collection-sync-mode") || "refresh",
|
|
@@ -139005,6 +139136,7 @@ async function upsertEnvironments(inputs, dependencies, resourcesState, assetMar
|
|
|
139005
139136
|
);
|
|
139006
139137
|
}
|
|
139007
139138
|
envUids[envName] = existingUid;
|
|
139139
|
+
dependencies.core.setOutput("environment-uids-json", JSON.stringify(envUids));
|
|
139008
139140
|
continue;
|
|
139009
139141
|
}
|
|
139010
139142
|
const values = buildEnvironmentValues(envName, runtimeUrl);
|
|
@@ -139015,6 +139147,7 @@ async function upsertEnvironments(inputs, dependencies, resourcesState, assetMar
|
|
|
139015
139147
|
displayName,
|
|
139016
139148
|
values
|
|
139017
139149
|
);
|
|
139150
|
+
dependencies.core.setOutput("environment-uids-json", JSON.stringify(envUids));
|
|
139018
139151
|
} catch (error2) {
|
|
139019
139152
|
throw new Error(
|
|
139020
139153
|
formatOrchestrationIssue({
|
|
@@ -139031,7 +139164,7 @@ async function upsertEnvironments(inputs, dependencies, resourcesState, assetMar
|
|
|
139031
139164
|
return envUids;
|
|
139032
139165
|
}
|
|
139033
139166
|
function ensureDir(path9) {
|
|
139034
|
-
(0,
|
|
139167
|
+
(0, import_node_fs5.mkdirSync)(path9, { recursive: true });
|
|
139035
139168
|
}
|
|
139036
139169
|
function getCollectionDirectoryName(kind, projectName) {
|
|
139037
139170
|
if (kind === "Baseline") {
|
|
@@ -139068,7 +139201,7 @@ function stripVolatileFields(obj) {
|
|
|
139068
139201
|
}
|
|
139069
139202
|
function writeJsonFile(path9, content, normalize4 = false) {
|
|
139070
139203
|
const data = normalize4 ? stripVolatileFields(content) : content;
|
|
139071
|
-
(0,
|
|
139204
|
+
(0, import_node_fs5.writeFileSync)(path9, JSON.stringify(data, null, 2));
|
|
139072
139205
|
}
|
|
139073
139206
|
function buildMappedSpecCloudKey(mappedSource, specSyncMode, releaseLabel) {
|
|
139074
139207
|
if (specSyncMode !== "version") {
|
|
@@ -139132,22 +139265,422 @@ function buildResourcesManifest(workspaceId, collectionMap, envMap, artifactDir,
|
|
|
139132
139265
|
sortKeys: false
|
|
139133
139266
|
});
|
|
139134
139267
|
}
|
|
139135
|
-
function
|
|
139136
|
-
return
|
|
139137
|
-
|
|
139138
|
-
|
|
139139
|
-
|
|
139140
|
-
|
|
139141
|
-
|
|
139142
|
-
|
|
139268
|
+
function isPlainObject2(value) {
|
|
139269
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
139270
|
+
}
|
|
139271
|
+
function buildSpecCollectionWorkflowManifest(specRef, collectionRefs, existingRaw) {
|
|
139272
|
+
const pairs = collectionRefs.map((collectionRef) => ({
|
|
139273
|
+
spec: specRef,
|
|
139274
|
+
collection: collectionRef
|
|
139275
|
+
}));
|
|
139276
|
+
let root = {};
|
|
139277
|
+
if (typeof existingRaw === "string" && existingRaw.trim()) {
|
|
139278
|
+
let parsed;
|
|
139279
|
+
try {
|
|
139280
|
+
parsed = load(existingRaw);
|
|
139281
|
+
} catch (error2) {
|
|
139282
|
+
throw new Error(
|
|
139283
|
+
`CONTRACT_WORKFLOWS_UNREADABLE: .postman/workflows.yaml exists but is not parseable YAML (${error2 instanceof Error ? error2.message : String(error2)}). Fix or delete the file; refusing to overwrite unrelated workflow data.`,
|
|
139284
|
+
{ cause: error2 }
|
|
139285
|
+
);
|
|
139286
|
+
}
|
|
139287
|
+
if (parsed === null || parsed === void 0) {
|
|
139288
|
+
root = {};
|
|
139289
|
+
} else if (!isPlainObject2(parsed)) {
|
|
139290
|
+
throw new Error(
|
|
139291
|
+
"CONTRACT_WORKFLOWS_UNREADABLE: .postman/workflows.yaml exists but does not contain a YAML mapping. Fix or delete the file; refusing to overwrite unrelated workflow data."
|
|
139292
|
+
);
|
|
139293
|
+
} else {
|
|
139294
|
+
root = { ...parsed };
|
|
139295
|
+
}
|
|
139296
|
+
}
|
|
139297
|
+
const workflows = isPlainObject2(root.workflows) ? { ...root.workflows } : {};
|
|
139298
|
+
const desiredCollections = new Set(collectionRefs);
|
|
139299
|
+
const currentPairs = (Array.isArray(workflows.syncSpecToCollection) ? workflows.syncSpecToCollection : []).map((entry) => isPlainObject2(entry) ? { ...entry } : null).filter((entry) => Boolean(entry)).filter(
|
|
139300
|
+
(entry) => String(entry.spec ?? "") !== specRef || desiredCollections.has(String(entry.collection ?? ""))
|
|
139301
|
+
);
|
|
139302
|
+
for (const pair of pairs) {
|
|
139303
|
+
const index = currentPairs.findIndex(
|
|
139304
|
+
(entry) => String(entry.spec ?? "") === pair.spec && String(entry.collection ?? "") === pair.collection
|
|
139305
|
+
);
|
|
139306
|
+
if (index >= 0) {
|
|
139307
|
+
const previous = currentPairs[index];
|
|
139308
|
+
currentPairs[index] = { ...previous, spec: pair.spec, collection: pair.collection };
|
|
139309
|
+
} else {
|
|
139310
|
+
currentPairs.push({ spec: pair.spec, collection: pair.collection });
|
|
139311
|
+
}
|
|
139312
|
+
}
|
|
139313
|
+
workflows.syncSpecToCollection = currentPairs;
|
|
139314
|
+
root.workflows = workflows;
|
|
139315
|
+
return dump(root, {
|
|
139316
|
+
lineWidth: -1,
|
|
139317
|
+
noRefs: true,
|
|
139318
|
+
sortKeys: false
|
|
139319
|
+
});
|
|
139320
|
+
}
|
|
139321
|
+
var PREBUILT_COLLECTION_ROLES = /* @__PURE__ */ new Set([
|
|
139322
|
+
"baseline",
|
|
139323
|
+
"smoke",
|
|
139324
|
+
"contract"
|
|
139325
|
+
]);
|
|
139326
|
+
var SHA256_HEX = /^[a-f0-9]{64}$/;
|
|
139327
|
+
var PREBUILT_CLOUD_ID = /^[A-Za-z0-9][A-Za-z0-9._:-]*$/;
|
|
139328
|
+
function failPrebuiltCollections(detail) {
|
|
139329
|
+
throw new Error(`CONTRACT_PREBUILT_COLLECTIONS_INVALID: ${detail}`);
|
|
139330
|
+
}
|
|
139331
|
+
function parsePrebuiltCollectionsJson(raw) {
|
|
139332
|
+
const trimmed = String(raw ?? "").trim();
|
|
139333
|
+
if (!trimmed) {
|
|
139334
|
+
return [];
|
|
139335
|
+
}
|
|
139336
|
+
let parsed;
|
|
139337
|
+
try {
|
|
139338
|
+
parsed = JSON.parse(trimmed);
|
|
139339
|
+
} catch (error2) {
|
|
139340
|
+
throw new Error(
|
|
139341
|
+
`CONTRACT_PREBUILT_COLLECTIONS_INVALID: malformed JSON (${error2 instanceof Error ? error2.message : String(error2)})`,
|
|
139342
|
+
{ cause: error2 }
|
|
139343
|
+
);
|
|
139344
|
+
}
|
|
139345
|
+
let entriesRaw;
|
|
139346
|
+
if (Array.isArray(parsed)) {
|
|
139347
|
+
entriesRaw = parsed;
|
|
139348
|
+
} else if (isPlainObject2(parsed)) {
|
|
139349
|
+
if (parsed.schemaVersion !== 1) {
|
|
139350
|
+
failPrebuiltCollections("schemaVersion must be 1");
|
|
139351
|
+
}
|
|
139352
|
+
if (!Array.isArray(parsed.collections)) {
|
|
139353
|
+
failPrebuiltCollections("collections must be an array when schemaVersion is set");
|
|
139354
|
+
}
|
|
139355
|
+
entriesRaw = parsed.collections;
|
|
139356
|
+
} else {
|
|
139357
|
+
failPrebuiltCollections("expected a JSON array or {schemaVersion:1,collections:[]}");
|
|
139358
|
+
}
|
|
139359
|
+
const seenRoles = /* @__PURE__ */ new Set();
|
|
139360
|
+
const entries = [];
|
|
139361
|
+
for (const [index, value] of entriesRaw.entries()) {
|
|
139362
|
+
if (!isPlainObject2(value)) {
|
|
139363
|
+
failPrebuiltCollections(`collections[${index}] must be an object`);
|
|
139364
|
+
}
|
|
139365
|
+
const roleRaw = String(value.role ?? "").trim();
|
|
139366
|
+
if (!PREBUILT_COLLECTION_ROLES.has(roleRaw)) {
|
|
139367
|
+
failPrebuiltCollections(
|
|
139368
|
+
`collections[${index}].role must be one of baseline|smoke|contract`
|
|
139369
|
+
);
|
|
139370
|
+
}
|
|
139371
|
+
const role = roleRaw;
|
|
139372
|
+
if (seenRoles.has(role)) {
|
|
139373
|
+
failPrebuiltCollections(`duplicate role ${role}`);
|
|
139374
|
+
}
|
|
139375
|
+
seenRoles.add(role);
|
|
139376
|
+
const collectionPath = String(
|
|
139377
|
+
value.collectionPath ?? value.path ?? ""
|
|
139378
|
+
).trim();
|
|
139379
|
+
if (!collectionPath || hasControlCharacter2(collectionPath)) {
|
|
139380
|
+
failPrebuiltCollections(
|
|
139381
|
+
`collections[${index}].collectionPath must be a non-empty confined relative path`
|
|
139382
|
+
);
|
|
139383
|
+
}
|
|
139384
|
+
const cloudId = String(value.cloudId ?? "").trim();
|
|
139385
|
+
if (!cloudId || !PREBUILT_CLOUD_ID.test(cloudId)) {
|
|
139386
|
+
failPrebuiltCollections(
|
|
139387
|
+
`collections[${index}].cloudId must be a non-empty Postman collection id`
|
|
139388
|
+
);
|
|
139389
|
+
}
|
|
139390
|
+
let payloadDigest;
|
|
139391
|
+
if (Object.prototype.hasOwnProperty.call(value, "payloadDigest")) {
|
|
139392
|
+
const payloadDigestRaw = value.payloadDigest;
|
|
139393
|
+
if (payloadDigestRaw !== void 0 && payloadDigestRaw !== null) {
|
|
139394
|
+
payloadDigest = String(payloadDigestRaw).trim();
|
|
139395
|
+
if (!SHA256_HEX.test(payloadDigest)) {
|
|
139396
|
+
failPrebuiltCollections(
|
|
139397
|
+
`collections[${index}].payloadDigest must be lowercase 64-hex`
|
|
139398
|
+
);
|
|
139399
|
+
}
|
|
139143
139400
|
}
|
|
139144
|
-
},
|
|
139145
|
-
{
|
|
139146
|
-
lineWidth: -1,
|
|
139147
|
-
noRefs: true,
|
|
139148
|
-
sortKeys: false
|
|
139149
139401
|
}
|
|
139402
|
+
const artifactDigest = String(value.artifactDigest ?? "").trim();
|
|
139403
|
+
if (!SHA256_HEX.test(artifactDigest)) {
|
|
139404
|
+
failPrebuiltCollections(
|
|
139405
|
+
`collections[${index}].artifactDigest must be lowercase 64-hex`
|
|
139406
|
+
);
|
|
139407
|
+
}
|
|
139408
|
+
entries.push({
|
|
139409
|
+
role,
|
|
139410
|
+
collectionPath,
|
|
139411
|
+
cloudId,
|
|
139412
|
+
...payloadDigest !== void 0 ? { payloadDigest } : {},
|
|
139413
|
+
artifactDigest
|
|
139414
|
+
});
|
|
139415
|
+
}
|
|
139416
|
+
return entries;
|
|
139417
|
+
}
|
|
139418
|
+
function assertPathWithinArtifactRoot(targetPath, artifactDir, fieldName) {
|
|
139419
|
+
assertPathWithinCwd(targetPath, fieldName);
|
|
139420
|
+
assertPathWithinCwd(artifactDir, "artifact-dir");
|
|
139421
|
+
const cwd = (0, import_node_fs5.realpathSync)(process.cwd());
|
|
139422
|
+
const artifactRoot = path8.resolve(cwd, artifactDir.trim());
|
|
139423
|
+
const resolved = path8.resolve(cwd, targetPath.trim());
|
|
139424
|
+
const relativeToArtifact = path8.relative(artifactRoot, resolved);
|
|
139425
|
+
if (!relativeToArtifact || relativeToArtifact.startsWith("..") || path8.isAbsolute(relativeToArtifact)) {
|
|
139426
|
+
failPrebuiltCollections(
|
|
139427
|
+
`${fieldName} must stay under artifact-dir (${artifactDir}); received ${targetPath}`
|
|
139428
|
+
);
|
|
139429
|
+
}
|
|
139430
|
+
let existingPath = resolved;
|
|
139431
|
+
while (!(0, import_node_fs5.existsSync)(existingPath)) {
|
|
139432
|
+
const parent = path8.dirname(existingPath);
|
|
139433
|
+
if (parent === existingPath) {
|
|
139434
|
+
break;
|
|
139435
|
+
}
|
|
139436
|
+
existingPath = parent;
|
|
139437
|
+
}
|
|
139438
|
+
const realExisting = (0, import_node_fs5.realpathSync)(existingPath);
|
|
139439
|
+
const realRelative = path8.relative(artifactRoot, realExisting);
|
|
139440
|
+
if (realRelative.startsWith("..") || path8.isAbsolute(realRelative)) {
|
|
139441
|
+
failPrebuiltCollections(
|
|
139442
|
+
`${fieldName} resolves outside artifact-dir via symlink; received ${targetPath}`
|
|
139443
|
+
);
|
|
139444
|
+
}
|
|
139445
|
+
return normalizeToPosix(path8.relative(cwd, resolved));
|
|
139446
|
+
}
|
|
139447
|
+
function prebuiltDirectoryTraversalIdentity(absolutePath, stats, options = {}) {
|
|
139448
|
+
const platform2 = options.platform ?? process.platform;
|
|
139449
|
+
const inodeIsZero = stats.ino === 0 || stats.ino === 0n;
|
|
139450
|
+
if (platform2 !== "win32" && !inodeIsZero) {
|
|
139451
|
+
return `${stats.dev}:${stats.ino}`;
|
|
139452
|
+
}
|
|
139453
|
+
const resolveCanonicalPath = options.resolveCanonicalPath ?? ((candidate) => import_node_fs5.realpathSync.native(candidate));
|
|
139454
|
+
const canonical = resolveCanonicalPath(absolutePath);
|
|
139455
|
+
return platform2 === "win32" ? canonical.toLowerCase() : canonical;
|
|
139456
|
+
}
|
|
139457
|
+
function listPrebuiltCollectionTreeFiles(collectionPath, artifactDir) {
|
|
139458
|
+
const confined = assertPathWithinArtifactRoot(
|
|
139459
|
+
collectionPath,
|
|
139460
|
+
artifactDir,
|
|
139461
|
+
"prebuilt collection path"
|
|
139462
|
+
);
|
|
139463
|
+
const absRoot = path8.resolve(process.cwd(), confined);
|
|
139464
|
+
if (!(0, import_node_fs5.existsSync)(absRoot)) {
|
|
139465
|
+
return [];
|
|
139466
|
+
}
|
|
139467
|
+
let rootStat;
|
|
139468
|
+
try {
|
|
139469
|
+
rootStat = (0, import_node_fs5.lstatSync)(absRoot);
|
|
139470
|
+
} catch {
|
|
139471
|
+
return [];
|
|
139472
|
+
}
|
|
139473
|
+
if (rootStat.isSymbolicLink()) {
|
|
139474
|
+
failPrebuiltCollections(
|
|
139475
|
+
`prebuilt collection path must not be a symlink; received ${collectionPath}`
|
|
139476
|
+
);
|
|
139477
|
+
}
|
|
139478
|
+
if (!rootStat.isDirectory()) {
|
|
139479
|
+
return [];
|
|
139480
|
+
}
|
|
139481
|
+
const files = [];
|
|
139482
|
+
const pendingDirectories = [absRoot];
|
|
139483
|
+
const seenDirectories = /* @__PURE__ */ new Set();
|
|
139484
|
+
while (pendingDirectories.length > 0) {
|
|
139485
|
+
const currentAbsolute = pendingDirectories.pop();
|
|
139486
|
+
if (!currentAbsolute) {
|
|
139487
|
+
break;
|
|
139488
|
+
}
|
|
139489
|
+
const currentStat = (0, import_node_fs5.lstatSync)(currentAbsolute);
|
|
139490
|
+
if (currentStat.isSymbolicLink() || !currentStat.isDirectory()) {
|
|
139491
|
+
failPrebuiltCollections(
|
|
139492
|
+
`prebuilt collection tree directory changed or became unsupported at ${normalizeToPosix(path8.relative(absRoot, currentAbsolute)) || "."}`
|
|
139493
|
+
);
|
|
139494
|
+
}
|
|
139495
|
+
const currentKey = prebuiltDirectoryTraversalIdentity(currentAbsolute, currentStat);
|
|
139496
|
+
if (seenDirectories.has(currentKey)) {
|
|
139497
|
+
failPrebuiltCollections(
|
|
139498
|
+
`prebuilt collection tree directory cycle detected at ${normalizeToPosix(path8.relative(absRoot, currentAbsolute)) || "."}`
|
|
139499
|
+
);
|
|
139500
|
+
}
|
|
139501
|
+
seenDirectories.add(currentKey);
|
|
139502
|
+
const entries = (0, import_node_fs5.readdirSync)(currentAbsolute, { withFileTypes: true });
|
|
139503
|
+
for (const entry of entries) {
|
|
139504
|
+
const abs = path8.join(currentAbsolute, entry.name);
|
|
139505
|
+
if (entry.isSymbolicLink()) {
|
|
139506
|
+
failPrebuiltCollections(
|
|
139507
|
+
`prebuilt collection tree must not contain symlinks; received ${normalizeToPosix(path8.relative(absRoot, abs))}`
|
|
139508
|
+
);
|
|
139509
|
+
}
|
|
139510
|
+
if (entry.isDirectory()) {
|
|
139511
|
+
pendingDirectories.push(abs);
|
|
139512
|
+
continue;
|
|
139513
|
+
}
|
|
139514
|
+
if (!entry.isFile()) {
|
|
139515
|
+
failPrebuiltCollections(
|
|
139516
|
+
`prebuilt collection tree contains unsupported entry type at ${normalizeToPosix(path8.relative(absRoot, abs))}`
|
|
139517
|
+
);
|
|
139518
|
+
}
|
|
139519
|
+
const fileLstat = (0, import_node_fs5.lstatSync)(abs);
|
|
139520
|
+
if (fileLstat.isSymbolicLink() || !fileLstat.isFile()) {
|
|
139521
|
+
failPrebuiltCollections(
|
|
139522
|
+
`prebuilt collection tree file changed or became unsupported at ${normalizeToPosix(path8.relative(absRoot, abs))}`
|
|
139523
|
+
);
|
|
139524
|
+
}
|
|
139525
|
+
files.push({
|
|
139526
|
+
absolute: abs,
|
|
139527
|
+
relative: normalizeToPosix(path8.relative(absRoot, abs)),
|
|
139528
|
+
dev: fileLstat.dev,
|
|
139529
|
+
ino: fileLstat.ino,
|
|
139530
|
+
size: fileLstat.size
|
|
139531
|
+
});
|
|
139532
|
+
}
|
|
139533
|
+
}
|
|
139534
|
+
files.sort((a, b) => a.relative.localeCompare(b.relative));
|
|
139535
|
+
return files;
|
|
139536
|
+
}
|
|
139537
|
+
function validateCanonicalV3CollectionFile(relative4, bytes) {
|
|
139538
|
+
let expectedKind;
|
|
139539
|
+
if (/(^|\/)\.resources\/definition\.yaml$/.test(relative4)) {
|
|
139540
|
+
expectedKind = "collection";
|
|
139541
|
+
} else if (relative4.endsWith(".request.yaml")) {
|
|
139542
|
+
expectedKind = "request";
|
|
139543
|
+
} else if (relative4.endsWith(".example.yaml")) {
|
|
139544
|
+
expectedKind = "example";
|
|
139545
|
+
} else if (relative4.endsWith(".message.yaml")) {
|
|
139546
|
+
expectedKind = "message";
|
|
139547
|
+
} else {
|
|
139548
|
+
failPrebuiltCollections(`prebuilt collection tree contains unexpected file ${relative4}`);
|
|
139549
|
+
}
|
|
139550
|
+
let parsed;
|
|
139551
|
+
try {
|
|
139552
|
+
parsed = load(bytes.toString("utf8"));
|
|
139553
|
+
} catch (error2) {
|
|
139554
|
+
failPrebuiltCollections(
|
|
139555
|
+
`prebuilt collection tree contains malformed YAML at ${relative4} (${error2 instanceof Error ? error2.message : String(error2)})`
|
|
139556
|
+
);
|
|
139557
|
+
}
|
|
139558
|
+
if (!isPlainObject2(parsed)) {
|
|
139559
|
+
failPrebuiltCollections(`prebuilt collection tree file ${relative4} must contain a YAML mapping`);
|
|
139560
|
+
}
|
|
139561
|
+
const kind = typeof parsed.$kind === "string" ? parsed.$kind.trim() : "";
|
|
139562
|
+
if (!kind) {
|
|
139563
|
+
failPrebuiltCollections(`prebuilt collection tree file ${relative4} must contain a nonempty $kind`);
|
|
139564
|
+
}
|
|
139565
|
+
const agrees = expectedKind === "collection" ? kind === "collection" : kind.endsWith(`-${expectedKind}`);
|
|
139566
|
+
if (!agrees) {
|
|
139567
|
+
failPrebuiltCollections(
|
|
139568
|
+
`prebuilt collection tree file ${relative4} has $kind ${kind} inconsistent with its filename`
|
|
139569
|
+
);
|
|
139570
|
+
}
|
|
139571
|
+
}
|
|
139572
|
+
async function digestAndValidatePrebuiltCollectionTree(files) {
|
|
139573
|
+
if (!files.some((file) => file.relative === ".resources/definition.yaml")) {
|
|
139574
|
+
failPrebuiltCollections("prebuilt collection tree is missing .resources/definition.yaml");
|
|
139575
|
+
}
|
|
139576
|
+
const hash = (0, import_node_crypto4.createHash)("sha256");
|
|
139577
|
+
for (const file of files) {
|
|
139578
|
+
let bytes;
|
|
139579
|
+
try {
|
|
139580
|
+
bytes = await appendArtifactDigestFileStreaming(hash, file.relative, file.absolute, {
|
|
139581
|
+
dev: file.dev,
|
|
139582
|
+
ino: file.ino,
|
|
139583
|
+
size: file.size
|
|
139584
|
+
});
|
|
139585
|
+
} catch (error2) {
|
|
139586
|
+
if (error2 instanceof ArtifactDigestStreamError) {
|
|
139587
|
+
failPrebuiltCollections(error2.message);
|
|
139588
|
+
}
|
|
139589
|
+
const code = error2?.code;
|
|
139590
|
+
if (code === "ELOOP" || code === "EPERM") {
|
|
139591
|
+
failPrebuiltCollections(
|
|
139592
|
+
`prebuilt collection tree file became a symlink or unsupported node at ${file.relative}`
|
|
139593
|
+
);
|
|
139594
|
+
}
|
|
139595
|
+
failPrebuiltCollections(
|
|
139596
|
+
`prebuilt collection tree file changed or became unsupported at ${file.relative}`
|
|
139597
|
+
);
|
|
139598
|
+
}
|
|
139599
|
+
validateCanonicalV3CollectionFile(file.relative, bytes);
|
|
139600
|
+
}
|
|
139601
|
+
return hash.digest("hex");
|
|
139602
|
+
}
|
|
139603
|
+
async function preparePrebuiltCollections(inputs) {
|
|
139604
|
+
const prepared = /* @__PURE__ */ new Map();
|
|
139605
|
+
for (const entry of parsePrebuiltCollectionsJson(inputs.prebuiltCollectionsJson ?? "")) {
|
|
139606
|
+
const confinedPath = assertPathWithinArtifactRoot(
|
|
139607
|
+
entry.collectionPath,
|
|
139608
|
+
inputs.artifactDir,
|
|
139609
|
+
`prebuilt ${entry.role} collection path`
|
|
139610
|
+
);
|
|
139611
|
+
const absolute = path8.resolve(process.cwd(), confinedPath);
|
|
139612
|
+
if (!(0, import_node_fs5.existsSync)(absolute)) {
|
|
139613
|
+
prepared.set(entry.role, { entry, confinedPath });
|
|
139614
|
+
continue;
|
|
139615
|
+
}
|
|
139616
|
+
const files = listPrebuiltCollectionTreeFiles(confinedPath, inputs.artifactDir);
|
|
139617
|
+
const artifactDigest = await digestAndValidatePrebuiltCollectionTree(files);
|
|
139618
|
+
prepared.set(entry.role, {
|
|
139619
|
+
entry,
|
|
139620
|
+
confinedPath,
|
|
139621
|
+
artifactDigest
|
|
139622
|
+
});
|
|
139623
|
+
}
|
|
139624
|
+
return prepared;
|
|
139625
|
+
}
|
|
139626
|
+
function tryReusePrebuiltCollection(options) {
|
|
139627
|
+
const { prepared, expectedPath, expectedCloudId } = options;
|
|
139628
|
+
const { entry } = prepared;
|
|
139629
|
+
if (!expectedCloudId || entry.cloudId !== expectedCloudId) {
|
|
139630
|
+
return false;
|
|
139631
|
+
}
|
|
139632
|
+
const expectedNormalized = canonicalizeRelativePath(expectedPath);
|
|
139633
|
+
const entryNormalized = canonicalizeRelativePath(entry.collectionPath);
|
|
139634
|
+
if (entryNormalized !== expectedNormalized) {
|
|
139635
|
+
return false;
|
|
139636
|
+
}
|
|
139637
|
+
const confined = canonicalizeRelativePath(prepared.confinedPath);
|
|
139638
|
+
if (confined !== expectedNormalized) {
|
|
139639
|
+
return false;
|
|
139640
|
+
}
|
|
139641
|
+
const expectedName = path8.posix.basename(expectedNormalized);
|
|
139642
|
+
if (path8.posix.basename(confined) !== expectedName) {
|
|
139643
|
+
return false;
|
|
139644
|
+
}
|
|
139645
|
+
return prepared.artifactDigest === entry.artifactDigest;
|
|
139646
|
+
}
|
|
139647
|
+
async function exportCollectionArtifact(options) {
|
|
139648
|
+
const {
|
|
139649
|
+
role,
|
|
139650
|
+
collectionId,
|
|
139651
|
+
dirName,
|
|
139652
|
+
collectionsDir,
|
|
139653
|
+
prebuiltByRole,
|
|
139654
|
+
postman,
|
|
139655
|
+
core
|
|
139656
|
+
} = options;
|
|
139657
|
+
if (!collectionId) {
|
|
139658
|
+
return void 0;
|
|
139659
|
+
}
|
|
139660
|
+
const expectedPath = `${collectionsDir}/${dirName}`;
|
|
139661
|
+
const entry = prebuiltByRole.get(role);
|
|
139662
|
+
if (entry) {
|
|
139663
|
+
const reused = tryReusePrebuiltCollection({
|
|
139664
|
+
prepared: entry,
|
|
139665
|
+
expectedPath,
|
|
139666
|
+
expectedCloudId: collectionId
|
|
139667
|
+
});
|
|
139668
|
+
if (reused) {
|
|
139669
|
+
core.info(
|
|
139670
|
+
`Reusing prebuilt ${role} collection tree at ${expectedPath} (artifactDigest match)`
|
|
139671
|
+
);
|
|
139672
|
+
return `../${expectedPath}`;
|
|
139673
|
+
}
|
|
139674
|
+
core.info(
|
|
139675
|
+
`Prebuilt ${role} collection entry present but did not exactly match; exporting from cloud`
|
|
139676
|
+
);
|
|
139677
|
+
}
|
|
139678
|
+
const col = await postman.getCollection(collectionId);
|
|
139679
|
+
await convertAndSplitAnyCollection(
|
|
139680
|
+
col,
|
|
139681
|
+
expectedPath
|
|
139150
139682
|
);
|
|
139683
|
+
return `../${expectedPath}`;
|
|
139151
139684
|
}
|
|
139152
139685
|
function hasControlCharacter2(value) {
|
|
139153
139686
|
for (let index = 0; index < value.length; index += 1) {
|
|
@@ -139165,21 +139698,21 @@ function assertPathWithinCwd(targetPath, fieldName) {
|
|
|
139165
139698
|
if (!rawPath || hasControlCharacter2(originalPath) || path8.isAbsolute(rawPath) || path8.win32.isAbsolute(rawPath) || segments.includes("..") || rawPath.startsWith(":") || hasControlCharacter2(rawPath)) {
|
|
139166
139699
|
throw new Error(`${fieldName} must stay within the repository root; received ${targetPath}`);
|
|
139167
139700
|
}
|
|
139168
|
-
const base = (0,
|
|
139701
|
+
const base = (0, import_node_fs5.realpathSync)(process.cwd());
|
|
139169
139702
|
const resolved = path8.resolve(base, rawPath);
|
|
139170
139703
|
const relative4 = path8.relative(base, resolved);
|
|
139171
139704
|
if (relative4.startsWith("..") || path8.isAbsolute(relative4)) {
|
|
139172
139705
|
throw new Error(`${fieldName} must stay within the repository root; received ${targetPath}`);
|
|
139173
139706
|
}
|
|
139174
139707
|
let existingPath = resolved;
|
|
139175
|
-
while (!(0,
|
|
139708
|
+
while (!(0, import_node_fs5.existsSync)(existingPath)) {
|
|
139176
139709
|
const parent = path8.dirname(existingPath);
|
|
139177
139710
|
if (parent === existingPath) {
|
|
139178
139711
|
break;
|
|
139179
139712
|
}
|
|
139180
139713
|
existingPath = parent;
|
|
139181
139714
|
}
|
|
139182
|
-
const realExistingPath = (0,
|
|
139715
|
+
const realExistingPath = (0, import_node_fs5.realpathSync)(existingPath);
|
|
139183
139716
|
const realRelative = path8.relative(base, realExistingPath);
|
|
139184
139717
|
if (realRelative.startsWith("..") || path8.isAbsolute(realRelative)) {
|
|
139185
139718
|
throw new Error(`${fieldName} must stay within the repository root; received ${targetPath}`);
|
|
@@ -139207,8 +139740,8 @@ async function exportArtifacts(inputs, dependencies, envUids, assetProjectName,
|
|
|
139207
139740
|
ensureDir(specsDir);
|
|
139208
139741
|
ensureDir(".postman");
|
|
139209
139742
|
const globalsFilePath = `${globalsDir}/workspace.globals.yaml`;
|
|
139210
|
-
if (!(0,
|
|
139211
|
-
(0,
|
|
139743
|
+
if (!(0, import_node_fs5.existsSync)(globalsFilePath)) {
|
|
139744
|
+
(0, import_node_fs5.writeFileSync)(globalsFilePath, "name: Globals\nvalues: []\n");
|
|
139212
139745
|
}
|
|
139213
139746
|
if (inputs.generateCiWorkflow) {
|
|
139214
139747
|
const ciDir = inputs.ciWorkflowPath.split("/").slice(0, -1).join("/");
|
|
@@ -139224,23 +139757,42 @@ async function exportArtifacts(inputs, dependencies, envUids, assetProjectName,
|
|
|
139224
139757
|
inputs.specSyncMode,
|
|
139225
139758
|
options.releaseLabel
|
|
139226
139759
|
) : void 0;
|
|
139227
|
-
|
|
139228
|
-
|
|
139229
|
-
|
|
139230
|
-
|
|
139231
|
-
|
|
139232
|
-
|
|
139233
|
-
|
|
139234
|
-
|
|
139235
|
-
|
|
139236
|
-
|
|
139237
|
-
|
|
139238
|
-
|
|
139239
|
-
|
|
139240
|
-
|
|
139241
|
-
|
|
139242
|
-
|
|
139243
|
-
|
|
139760
|
+
const prebuiltByRole = options.preparedPrebuiltCollections;
|
|
139761
|
+
const baselineRef = await exportCollectionArtifact({
|
|
139762
|
+
role: "baseline",
|
|
139763
|
+
collectionId: inputs.baselineCollectionId,
|
|
139764
|
+
dirName: getCollectionDirectoryName("Baseline", assetProjectName),
|
|
139765
|
+
collectionsDir,
|
|
139766
|
+
prebuiltByRole,
|
|
139767
|
+
postman: dependencies.postman,
|
|
139768
|
+
core: dependencies.core
|
|
139769
|
+
});
|
|
139770
|
+
if (baselineRef) {
|
|
139771
|
+
manifestCollections[baselineRef] = inputs.baselineCollectionId;
|
|
139772
|
+
}
|
|
139773
|
+
const smokeRef = await exportCollectionArtifact({
|
|
139774
|
+
role: "smoke",
|
|
139775
|
+
collectionId: inputs.smokeCollectionId,
|
|
139776
|
+
dirName: getCollectionDirectoryName("Smoke", assetProjectName),
|
|
139777
|
+
collectionsDir,
|
|
139778
|
+
prebuiltByRole,
|
|
139779
|
+
postman: dependencies.postman,
|
|
139780
|
+
core: dependencies.core
|
|
139781
|
+
});
|
|
139782
|
+
if (smokeRef) {
|
|
139783
|
+
manifestCollections[smokeRef] = inputs.smokeCollectionId;
|
|
139784
|
+
}
|
|
139785
|
+
const contractRef = await exportCollectionArtifact({
|
|
139786
|
+
role: "contract",
|
|
139787
|
+
collectionId: inputs.contractCollectionId,
|
|
139788
|
+
dirName: getCollectionDirectoryName("Contract", assetProjectName),
|
|
139789
|
+
collectionsDir,
|
|
139790
|
+
prebuiltByRole,
|
|
139791
|
+
postman: dependencies.postman,
|
|
139792
|
+
core: dependencies.core
|
|
139793
|
+
});
|
|
139794
|
+
if (contractRef) {
|
|
139795
|
+
manifestCollections[contractRef] = inputs.contractCollectionId;
|
|
139244
139796
|
}
|
|
139245
139797
|
for (const [envName, envUid] of Object.entries(envUids)) {
|
|
139246
139798
|
writeJsonFile(
|
|
@@ -139255,7 +139807,7 @@ async function exportArtifacts(inputs, dependencies, envUids, assetProjectName,
|
|
|
139255
139807
|
workspaceLinkEnabled: inputs.workspaceLinkEnabled,
|
|
139256
139808
|
workspaceLinkStatus: options.workspaceLinkStatus
|
|
139257
139809
|
});
|
|
139258
|
-
(0,
|
|
139810
|
+
(0, import_node_fs5.writeFileSync)(".postman/resources.yaml", buildResourcesManifest(
|
|
139259
139811
|
durableWorkspaceId,
|
|
139260
139812
|
manifestCollections,
|
|
139261
139813
|
envUids,
|
|
@@ -139267,11 +139819,18 @@ async function exportArtifacts(inputs, dependencies, envUids, assetProjectName,
|
|
|
139267
139819
|
options.priorState
|
|
139268
139820
|
));
|
|
139269
139821
|
if (mappedSpec && Object.keys(manifestCollections).length > 0) {
|
|
139270
|
-
|
|
139822
|
+
let existingWorkflows;
|
|
139823
|
+
try {
|
|
139824
|
+
existingWorkflows = (0, import_node_fs5.readFileSync)(".postman/workflows.yaml", "utf8");
|
|
139825
|
+
} catch {
|
|
139826
|
+
existingWorkflows = void 0;
|
|
139827
|
+
}
|
|
139828
|
+
(0, import_node_fs5.writeFileSync)(
|
|
139271
139829
|
".postman/workflows.yaml",
|
|
139272
139830
|
buildSpecCollectionWorkflowManifest(
|
|
139273
139831
|
mappedSpec.configRelativePath,
|
|
139274
|
-
Object.keys(manifestCollections)
|
|
139832
|
+
Object.keys(manifestCollections),
|
|
139833
|
+
existingWorkflows
|
|
139275
139834
|
)
|
|
139276
139835
|
);
|
|
139277
139836
|
}
|
|
@@ -139316,12 +139875,12 @@ async function commitAndPushGeneratedFiles(inputs, dependencies) {
|
|
|
139316
139875
|
const dir = parts.slice(0, -1).join("/");
|
|
139317
139876
|
ensureDir(dir);
|
|
139318
139877
|
}
|
|
139319
|
-
(0,
|
|
139878
|
+
(0, import_node_fs5.writeFileSync)(inputs.ciWorkflowPath, ciWorkflow);
|
|
139320
139879
|
if (inputs.provider === "github" || inputs.provider === "unknown") {
|
|
139321
139880
|
const gcPath = ".github/workflows/postman-preview-gc.yml";
|
|
139322
139881
|
if (inputs.ciWorkflowPath.endsWith(".github/workflows/ci.yml") || inputs.ciWorkflowPath === ".github/workflows/ci.yml") {
|
|
139323
139882
|
ensureDir(".github/workflows");
|
|
139324
|
-
(0,
|
|
139883
|
+
(0, import_node_fs5.writeFileSync)(gcPath, renderGcWorkflowTemplate());
|
|
139325
139884
|
}
|
|
139326
139885
|
}
|
|
139327
139886
|
}
|
|
@@ -139329,16 +139888,16 @@ async function commitAndPushGeneratedFiles(inputs, dependencies) {
|
|
|
139329
139888
|
return { commitSha: "", resolvedCurrentRef: "", pushed: false };
|
|
139330
139889
|
}
|
|
139331
139890
|
const provisionPath = ".github/workflows/provision.yml";
|
|
139332
|
-
const provisionExists = inputs.provider === "github" && (0,
|
|
139891
|
+
const provisionExists = inputs.provider === "github" && (0, import_node_fs5.existsSync)(provisionPath);
|
|
139333
139892
|
const gcWorkflowPath = ".github/workflows/postman-preview-gc.yml";
|
|
139334
|
-
const gcExists = inputs.generateCiWorkflow && (0,
|
|
139893
|
+
const gcExists = inputs.generateCiWorkflow && (0, import_node_fs5.existsSync)(gcWorkflowPath);
|
|
139335
139894
|
const stagePaths = [
|
|
139336
139895
|
inputs.artifactDir,
|
|
139337
139896
|
".postman",
|
|
139338
139897
|
inputs.generateCiWorkflow ? inputs.ciWorkflowPath : null,
|
|
139339
139898
|
gcExists ? gcWorkflowPath : null,
|
|
139340
139899
|
provisionExists ? provisionPath : null
|
|
139341
|
-
].filter((entry) => typeof entry === "string" && ((0,
|
|
139900
|
+
].filter((entry) => typeof entry === "string" && ((0, import_node_fs5.existsSync)(entry) || entry === provisionPath));
|
|
139342
139901
|
if (stagePaths.length === 0) {
|
|
139343
139902
|
dependencies.core.info("No generated repository paths were found; skipping repo mutation.");
|
|
139344
139903
|
return {
|
|
@@ -139446,6 +140005,7 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
139446
140005
|
}
|
|
139447
140006
|
}
|
|
139448
140007
|
}
|
|
140008
|
+
const preparedPrebuiltCollections = await preparePrebuiltCollections(inputs);
|
|
139449
140009
|
let skipRepositoryLinkPost = false;
|
|
139450
140010
|
let repositoryLinkPreflightWasFree = false;
|
|
139451
140011
|
if (inputs.workspaceLinkEnabled && inputs.workspaceId && inputs.repoUrl && dependencies.internalIntegration?.findWorkspaceForRepo) {
|
|
@@ -139482,6 +140042,7 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
139482
140042
|
const branchAssetMarker = buildBranchAssetMarker(branchDecision, inputs);
|
|
139483
140043
|
const envUids = await upsertEnvironments(inputs, dependencies, resourcesState, branchAssetMarker);
|
|
139484
140044
|
outputs["environment-uids-json"] = JSON.stringify(envUids);
|
|
140045
|
+
dependencies.core.setOutput("environment-uids-json", outputs["environment-uids-json"]);
|
|
139485
140046
|
if (inputs.environmentSyncEnabled && inputs.workspaceId && dependencies.internalIntegration) {
|
|
139486
140047
|
const associations = Object.entries(envUids).map(([envName, envUid]) => ({
|
|
139487
140048
|
envUid,
|
|
@@ -139600,6 +140161,7 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
139600
140161
|
}
|
|
139601
140162
|
}
|
|
139602
140163
|
outputs["mock-url"] = resolvedMockUrl;
|
|
140164
|
+
dependencies.core.setOutput("mock-url", resolvedMockUrl);
|
|
139603
140165
|
}
|
|
139604
140166
|
}
|
|
139605
140167
|
if (inputs.workspaceId && inputs.smokeCollectionId && Object.keys(envUids).length > 0) {
|
|
@@ -139675,6 +140237,7 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
139675
140237
|
}
|
|
139676
140238
|
}
|
|
139677
140239
|
outputs["monitor-id"] = resolvedMonitorId;
|
|
140240
|
+
dependencies.core.setOutput("monitor-id", resolvedMonitorId);
|
|
139678
140241
|
if (!effectiveCron && resolvedMonitorId) {
|
|
139679
140242
|
try {
|
|
139680
140243
|
await dependencies.postman.runMonitor(resolvedMonitorId);
|
|
@@ -139732,7 +140295,8 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
139732
140295
|
priorWorkspaceId: resourcesState?.workspace?.id,
|
|
139733
140296
|
existingSpecs: resourcesState?.cloudResources?.specs,
|
|
139734
140297
|
releaseLabel,
|
|
139735
|
-
priorState: resourcesState
|
|
140298
|
+
priorState: resourcesState,
|
|
140299
|
+
preparedPrebuiltCollections
|
|
139736
140300
|
});
|
|
139737
140301
|
const commit = await commitAndPushGeneratedFiles(inputs, dependencies);
|
|
139738
140302
|
outputs["commit-sha"] = commit.commitSha;
|
|
@@ -139958,7 +140522,12 @@ async function resolvePostmanApiKeyAndTeamId(inputs, actionCore, actionExec, mas
|
|
|
139958
140522
|
bifrostBaseUrl: inputs.postmanBifrostBase,
|
|
139959
140523
|
// No fallback on the org-mode probe: the expected non-org 400 must
|
|
139960
140524
|
// surface verbatim, not be re-fired against the /_api alias.
|
|
139961
|
-
secretMasker: masker
|
|
140525
|
+
secretMasker: masker,
|
|
140526
|
+
onRetryEvent: (event) => {
|
|
140527
|
+
actionCore.info(
|
|
140528
|
+
`[postman retry] action=repo-sync class=${event.class} status=${event.status ?? "none"} attempt=${event.attempt} delayMs=${event.delay}`
|
|
140529
|
+
);
|
|
140530
|
+
}
|
|
139962
140531
|
});
|
|
139963
140532
|
const squads = await gateway.getSquads(teamId);
|
|
139964
140533
|
if (squads.length > 0) {
|
|
@@ -140022,7 +140591,12 @@ function createRepoSyncDependencies(inputs, resolved, factories, options = {}) {
|
|
|
140022
140591
|
fallbackBaseUrl: inputs.postmanFallbackBase,
|
|
140023
140592
|
teamId: resolved.teamId,
|
|
140024
140593
|
orgMode: inputs.orgMode,
|
|
140025
|
-
secretMasker: masker
|
|
140594
|
+
secretMasker: masker,
|
|
140595
|
+
onRetryEvent: (event) => {
|
|
140596
|
+
factories.core.info(
|
|
140597
|
+
`[postman retry] action=repo-sync class=${event.class} status=${event.status ?? "none"} attempt=${event.attempt} delayMs=${event.delay}`
|
|
140598
|
+
);
|
|
140599
|
+
}
|
|
140026
140600
|
});
|
|
140027
140601
|
const gatewayAssets = new PostmanGatewayAssetsClient({
|
|
140028
140602
|
gateway,
|
|
@@ -140141,7 +140715,10 @@ async function runAction(actionCore = core_exports, actionExec = exec_exports) {
|
|
|
140141
140715
|
}
|
|
140142
140716
|
await mintAccessTokenIfNeeded(inputs, {
|
|
140143
140717
|
info: (message) => actionCore.info(message),
|
|
140144
|
-
warning: (message) => actionCore.warning(message)
|
|
140718
|
+
warning: (message) => actionCore.warning(message),
|
|
140719
|
+
retryEvent: (event) => actionCore.info(
|
|
140720
|
+
`[postman retry] action=repo-sync class=${event.class} status=${event.status ?? "none"} attempt=${event.attempt} delayMs=${event.delay}`
|
|
140721
|
+
)
|
|
140145
140722
|
}, (secret) => actionCore.setSecret(secret));
|
|
140146
140723
|
const masker = createSecretMasker([
|
|
140147
140724
|
inputs.postmanApiKey,
|
|
@@ -140162,7 +140739,12 @@ async function runAction(actionCore = core_exports, actionExec = exec_exports) {
|
|
|
140162
140739
|
explicitTeamId: inputs.teamId || void 0,
|
|
140163
140740
|
mode: inputs.credentialPreflight,
|
|
140164
140741
|
mask: masker,
|
|
140165
|
-
log:
|
|
140742
|
+
log: {
|
|
140743
|
+
...actionCore,
|
|
140744
|
+
retryEvent: (event) => actionCore.info(
|
|
140745
|
+
`[postman retry] action=repo-sync class=${event.class} status=${event.status ?? "none"} attempt=${event.attempt} delayMs=${event.delay}`
|
|
140746
|
+
)
|
|
140747
|
+
}
|
|
140166
140748
|
});
|
|
140167
140749
|
const resolved = await resolvePostmanApiKeyAndTeamId(inputs, actionCore, actionExec, masker, {
|
|
140168
140750
|
env: process.env
|