@postman-cse/onboarding-repo-sync 2.1.13 → 2.1.14
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 +644 -85
- package/dist/cli.cjs +779 -107
- package/dist/index.cjs +646 -85
- 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
|
],
|
|
@@ -137580,6 +137659,7 @@ var AccessTokenProvider = class {
|
|
|
137580
137659
|
maxAttempts;
|
|
137581
137660
|
onToken;
|
|
137582
137661
|
sleep;
|
|
137662
|
+
onRetryEvent;
|
|
137583
137663
|
inflight;
|
|
137584
137664
|
constructor(options) {
|
|
137585
137665
|
this.token = String(options.accessToken || "").trim();
|
|
@@ -137591,6 +137671,7 @@ var AccessTokenProvider = class {
|
|
|
137591
137671
|
this.maxAttempts = Math.max(1, options.maxAttempts ?? 2);
|
|
137592
137672
|
this.onToken = options.onToken;
|
|
137593
137673
|
this.sleep = options.sleep;
|
|
137674
|
+
this.onRetryEvent = options.onRetryEvent;
|
|
137594
137675
|
}
|
|
137595
137676
|
current() {
|
|
137596
137677
|
return this.token;
|
|
@@ -137616,7 +137697,12 @@ var AccessTokenProvider = class {
|
|
|
137616
137697
|
delayMs: 1e3,
|
|
137617
137698
|
backoffMultiplier: 2,
|
|
137618
137699
|
...this.sleep ? { sleep: this.sleep } : {},
|
|
137619
|
-
shouldRetry: (error2) => !(error2 instanceof MintError && error2.permanent)
|
|
137700
|
+
shouldRetry: (error2) => !(error2 instanceof MintError && error2.permanent),
|
|
137701
|
+
onRetry: ({ attempt, delayMs, error: error2 }) => {
|
|
137702
|
+
const status = error2 instanceof MintError ? error2.status : void 0;
|
|
137703
|
+
const retryClass = status === void 0 ? "transport" : "http";
|
|
137704
|
+
this.onRetryEvent?.({ class: retryClass, ...status === void 0 ? {} : { status }, attempt, delay: Math.max(0, delayMs) });
|
|
137705
|
+
}
|
|
137620
137706
|
});
|
|
137621
137707
|
this.token = token;
|
|
137622
137708
|
this.onToken?.(token);
|
|
@@ -137647,7 +137733,7 @@ var AccessTokenProvider = class {
|
|
|
137647
137733
|
true
|
|
137648
137734
|
);
|
|
137649
137735
|
}
|
|
137650
|
-
throw new MintError(`postman: re-mint failed (service-account-tokens HTTP ${status}).`, false);
|
|
137736
|
+
throw new MintError(`postman: re-mint failed (service-account-tokens HTTP ${status}).`, false, status);
|
|
137651
137737
|
}
|
|
137652
137738
|
let parsed;
|
|
137653
137739
|
try {
|
|
@@ -137678,7 +137764,8 @@ async function mintAccessTokenIfNeeded(inputs, log, setSecret2, fetchImpl = fetc
|
|
|
137678
137764
|
apiKey: inputs.postmanApiKey,
|
|
137679
137765
|
apiBaseUrl,
|
|
137680
137766
|
fetchImpl,
|
|
137681
|
-
onToken: (token) => setSecret2?.(token)
|
|
137767
|
+
onToken: (token) => setSecret2?.(token),
|
|
137768
|
+
onRetryEvent: (event) => log.retryEvent?.(event)
|
|
137682
137769
|
});
|
|
137683
137770
|
try {
|
|
137684
137771
|
inputs.postmanAccessToken = await provider.refresh();
|
|
@@ -137718,6 +137805,7 @@ var AccessTokenGatewayClient = class {
|
|
|
137718
137805
|
requestTimeoutMs;
|
|
137719
137806
|
retryMaxDelayMs;
|
|
137720
137807
|
randomImpl;
|
|
137808
|
+
onRetryEvent;
|
|
137721
137809
|
constructor(options) {
|
|
137722
137810
|
this.tokenProvider = options.tokenProvider;
|
|
137723
137811
|
this.bifrostBaseUrl = String(
|
|
@@ -137736,6 +137824,7 @@ var AccessTokenGatewayClient = class {
|
|
|
137736
137824
|
this.requestTimeoutMs = options.requestTimeoutMs ?? 3e4;
|
|
137737
137825
|
this.retryMaxDelayMs = options.retryMaxDelayMs ?? 5e3;
|
|
137738
137826
|
this.randomImpl = options.randomImpl ?? Math.random;
|
|
137827
|
+
this.onRetryEvent = options.onRetryEvent;
|
|
137739
137828
|
}
|
|
137740
137829
|
configureTeamContext(teamId, orgMode) {
|
|
137741
137830
|
this.teamId = String(teamId || "").trim();
|
|
@@ -137804,8 +137893,9 @@ var AccessTokenGatewayClient = class {
|
|
|
137804
137893
|
if (!this.fallbackBaseUrl) return false;
|
|
137805
137894
|
return retryTransient || request.fallback === "auto";
|
|
137806
137895
|
}
|
|
137807
|
-
async attemptFallback(request, retryTransient) {
|
|
137896
|
+
async attemptFallback(request, retryTransient, status) {
|
|
137808
137897
|
if (!this.fallbackEligible(request, retryTransient)) return null;
|
|
137898
|
+
this.emitRetryEvent("fallback", status, 1, 0);
|
|
137809
137899
|
const response = await this.tryFallback(request);
|
|
137810
137900
|
if (!response) return null;
|
|
137811
137901
|
if (response.ok) return response;
|
|
@@ -137831,6 +137921,7 @@ var AccessTokenGatewayClient = class {
|
|
|
137831
137921
|
} catch (error2) {
|
|
137832
137922
|
if (retryTransient && attempt < this.maxRetries) {
|
|
137833
137923
|
const delay = this.retryDelayMs(attempt);
|
|
137924
|
+
this.emitRetryEvent("transport", void 0, attempt + 1, delay);
|
|
137834
137925
|
attempt += 1;
|
|
137835
137926
|
await this.sleepImpl(delay);
|
|
137836
137927
|
continue;
|
|
@@ -137844,7 +137935,9 @@ var AccessTokenGatewayClient = class {
|
|
|
137844
137935
|
const inner = this.innerStatus(okBody);
|
|
137845
137936
|
if (inner !== void 0) {
|
|
137846
137937
|
if (retryTransient && this.isTransient(inner, okBody) && attempt < this.maxRetries) {
|
|
137847
|
-
|
|
137938
|
+
const delay = this.retryDelayMs(attempt);
|
|
137939
|
+
this.emitRetryEvent("inner", inner, attempt + 1, delay);
|
|
137940
|
+
await this.sleepImpl(delay);
|
|
137848
137941
|
attempt += 1;
|
|
137849
137942
|
continue;
|
|
137850
137943
|
}
|
|
@@ -137854,6 +137947,7 @@ var AccessTokenGatewayClient = class {
|
|
|
137854
137947
|
}
|
|
137855
137948
|
const body = await response.text().catch(() => "");
|
|
137856
137949
|
if (isExpiredAuthError(response.status, body) && this.tokenProvider.canRefresh()) {
|
|
137950
|
+
this.emitRetryEvent("auth", response.status, 1, 0);
|
|
137857
137951
|
await this.tokenProvider.refresh();
|
|
137858
137952
|
response = await this.send(request);
|
|
137859
137953
|
if (response.ok) {
|
|
@@ -137864,11 +137958,12 @@ var AccessTokenGatewayClient = class {
|
|
|
137864
137958
|
}
|
|
137865
137959
|
if (retryTransient && this.isTransient(response.status, body) && attempt < this.maxRetries) {
|
|
137866
137960
|
const delay = this.retryDelayMs(attempt, parseRetryAfterMs2(response.headers.get("retry-after")));
|
|
137961
|
+
this.emitRetryEvent("http", response.status, attempt + 1, delay);
|
|
137867
137962
|
attempt += 1;
|
|
137868
137963
|
await this.sleepImpl(delay);
|
|
137869
137964
|
continue;
|
|
137870
137965
|
}
|
|
137871
|
-
const fallbackResponse = await this.attemptFallback(request, retryTransient);
|
|
137966
|
+
const fallbackResponse = await this.attemptFallback(request, retryTransient, response.status);
|
|
137872
137967
|
if (fallbackResponse) return fallbackResponse;
|
|
137873
137968
|
throw this.toHttpError(request, response, body);
|
|
137874
137969
|
}
|
|
@@ -137876,6 +137971,14 @@ var AccessTokenGatewayClient = class {
|
|
|
137876
137971
|
retryDelayMs(attempt, retryAfter) {
|
|
137877
137972
|
return retryAfter === void 0 ? fullJitterDelayMs(attempt, this.retryBaseDelayMs, this.retryMaxDelayMs, this.randomImpl) : Math.min(this.retryMaxDelayMs, retryAfter);
|
|
137878
137973
|
}
|
|
137974
|
+
emitRetryEvent(retryClass, status, attempt, delay) {
|
|
137975
|
+
this.onRetryEvent?.({
|
|
137976
|
+
class: retryClass,
|
|
137977
|
+
...status === void 0 ? {} : { status },
|
|
137978
|
+
attempt: Math.max(1, attempt),
|
|
137979
|
+
delay: Math.max(0, delay)
|
|
137980
|
+
});
|
|
137981
|
+
}
|
|
137879
137982
|
isTransient(status, body) {
|
|
137880
137983
|
return status === 408 || status === 429 || status >= 500 || /ESOCKETTIMEDOUT|ETIMEDOUT|ECONNRESET|serverError|downstream/.test(body);
|
|
137881
137984
|
}
|
|
@@ -138005,7 +138108,7 @@ function validateCertMaterial(certBase64, keyBase64, passphrase) {
|
|
|
138005
138108
|
}
|
|
138006
138109
|
|
|
138007
138110
|
// src/lib/repo/branch-decision.ts
|
|
138008
|
-
var
|
|
138111
|
+
var import_node_fs4 = require("node:fs");
|
|
138009
138112
|
var import_node_crypto3 = require("node:crypto");
|
|
138010
138113
|
var ContractError = class extends Error {
|
|
138011
138114
|
code;
|
|
@@ -138046,7 +138149,7 @@ function readGithubEvent(env) {
|
|
|
138046
138149
|
const path9 = clean(env.GITHUB_EVENT_PATH);
|
|
138047
138150
|
if (!path9) return void 0;
|
|
138048
138151
|
try {
|
|
138049
|
-
return JSON.parse((0,
|
|
138152
|
+
return JSON.parse((0, import_node_fs4.readFileSync)(path9, "utf8"));
|
|
138050
138153
|
} catch {
|
|
138051
138154
|
return void 0;
|
|
138052
138155
|
}
|
|
@@ -138502,6 +138605,7 @@ function resolveInputs(env = process.env) {
|
|
|
138502
138605
|
baselineCollectionId: getInput2("baseline-collection-id", env),
|
|
138503
138606
|
smokeCollectionId: getInput2("smoke-collection-id", env),
|
|
138504
138607
|
contractCollectionId: getInput2("contract-collection-id", env),
|
|
138608
|
+
prebuiltCollectionsJson: getInput2("prebuilt-collections-json", env),
|
|
138505
138609
|
specId: getInput2("spec-id", env),
|
|
138506
138610
|
specContentChanged: parseBooleanInput(getInput2("spec-content-changed", env), true),
|
|
138507
138611
|
specPath: getInput2("spec-path", env),
|
|
@@ -138617,7 +138721,7 @@ var StateUnreadableError = class extends Error {
|
|
|
138617
138721
|
function readResourcesState() {
|
|
138618
138722
|
let raw;
|
|
138619
138723
|
try {
|
|
138620
|
-
raw = (0,
|
|
138724
|
+
raw = (0, import_node_fs5.readFileSync)(".postman/resources.yaml", "utf8");
|
|
138621
138725
|
} catch {
|
|
138622
138726
|
return null;
|
|
138623
138727
|
}
|
|
@@ -138676,12 +138780,15 @@ function getEnvironmentUidsFromResources(resourcesState) {
|
|
|
138676
138780
|
function normalizeToPosix(filePath) {
|
|
138677
138781
|
return filePath.split(path8.sep).join("/").replace(/\\/g, "/");
|
|
138678
138782
|
}
|
|
138783
|
+
function canonicalizeRelativePath(value) {
|
|
138784
|
+
return normalizeToPosix(String(value ?? "").trim()).replace(/^\.\/+/, "").replace(/\/{2,}/g, "/").replace(/\/+$/g, "");
|
|
138785
|
+
}
|
|
138679
138786
|
function isOpenApiSpecFile(filePath) {
|
|
138680
138787
|
if (!(filePath.endsWith(".json") || filePath.endsWith(".yaml") || filePath.endsWith(".yml"))) {
|
|
138681
138788
|
return false;
|
|
138682
138789
|
}
|
|
138683
138790
|
try {
|
|
138684
|
-
const raw = (0,
|
|
138791
|
+
const raw = (0, import_node_fs5.readFileSync)(filePath, "utf8");
|
|
138685
138792
|
const parsed = filePath.endsWith(".json") ? JSON.parse(raw) : load(raw);
|
|
138686
138793
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
138687
138794
|
return false;
|
|
@@ -138710,7 +138817,7 @@ function scanLocalSpecReferences(baseDir = ".") {
|
|
|
138710
138817
|
const found = /* @__PURE__ */ new Set();
|
|
138711
138818
|
const refs = [];
|
|
138712
138819
|
const visit2 = (currentDir) => {
|
|
138713
|
-
for (const entry of (0,
|
|
138820
|
+
for (const entry of (0, import_node_fs5.readdirSync)(currentDir, { withFileTypes: true })) {
|
|
138714
138821
|
if (ignoredDirs.has(entry.name)) {
|
|
138715
138822
|
continue;
|
|
138716
138823
|
}
|
|
@@ -138740,7 +138847,7 @@ function resolveMappedSpecReference(explicitSpecPath, discoveredSpecs) {
|
|
|
138740
138847
|
const normalizedExplicitPath = normalizeToPosix(explicitSpecPath.trim());
|
|
138741
138848
|
if (normalizedExplicitPath) {
|
|
138742
138849
|
const explicitFullPath = path8.resolve(normalizedExplicitPath);
|
|
138743
|
-
if ((0,
|
|
138850
|
+
if ((0, import_node_fs5.existsSync)(explicitFullPath) && (0, import_node_fs5.statSync)(explicitFullPath).isFile()) {
|
|
138744
138851
|
return {
|
|
138745
138852
|
repoRelativePath: normalizedExplicitPath,
|
|
138746
138853
|
configRelativePath: normalizeToPosix(path8.join("..", normalizedExplicitPath))
|
|
@@ -138792,6 +138899,7 @@ function readActionInputs(actionCore) {
|
|
|
138792
138899
|
INPUT_BASELINE_COLLECTION_ID: readInput(actionCore, "baseline-collection-id"),
|
|
138793
138900
|
INPUT_SMOKE_COLLECTION_ID: readInput(actionCore, "smoke-collection-id"),
|
|
138794
138901
|
INPUT_CONTRACT_COLLECTION_ID: readInput(actionCore, "contract-collection-id"),
|
|
138902
|
+
INPUT_PREBUILT_COLLECTIONS_JSON: readInput(actionCore, "prebuilt-collections-json"),
|
|
138795
138903
|
INPUT_SPEC_ID: readInput(actionCore, "spec-id"),
|
|
138796
138904
|
INPUT_SPEC_PATH: readInput(actionCore, "spec-path"),
|
|
138797
138905
|
INPUT_COLLECTION_SYNC_MODE: readInput(actionCore, "collection-sync-mode") || "refresh",
|
|
@@ -139005,6 +139113,7 @@ async function upsertEnvironments(inputs, dependencies, resourcesState, assetMar
|
|
|
139005
139113
|
);
|
|
139006
139114
|
}
|
|
139007
139115
|
envUids[envName] = existingUid;
|
|
139116
|
+
dependencies.core.setOutput("environment-uids-json", JSON.stringify(envUids));
|
|
139008
139117
|
continue;
|
|
139009
139118
|
}
|
|
139010
139119
|
const values = buildEnvironmentValues(envName, runtimeUrl);
|
|
@@ -139015,6 +139124,7 @@ async function upsertEnvironments(inputs, dependencies, resourcesState, assetMar
|
|
|
139015
139124
|
displayName,
|
|
139016
139125
|
values
|
|
139017
139126
|
);
|
|
139127
|
+
dependencies.core.setOutput("environment-uids-json", JSON.stringify(envUids));
|
|
139018
139128
|
} catch (error2) {
|
|
139019
139129
|
throw new Error(
|
|
139020
139130
|
formatOrchestrationIssue({
|
|
@@ -139031,7 +139141,7 @@ async function upsertEnvironments(inputs, dependencies, resourcesState, assetMar
|
|
|
139031
139141
|
return envUids;
|
|
139032
139142
|
}
|
|
139033
139143
|
function ensureDir(path9) {
|
|
139034
|
-
(0,
|
|
139144
|
+
(0, import_node_fs5.mkdirSync)(path9, { recursive: true });
|
|
139035
139145
|
}
|
|
139036
139146
|
function getCollectionDirectoryName(kind, projectName) {
|
|
139037
139147
|
if (kind === "Baseline") {
|
|
@@ -139068,7 +139178,7 @@ function stripVolatileFields(obj) {
|
|
|
139068
139178
|
}
|
|
139069
139179
|
function writeJsonFile(path9, content, normalize4 = false) {
|
|
139070
139180
|
const data = normalize4 ? stripVolatileFields(content) : content;
|
|
139071
|
-
(0,
|
|
139181
|
+
(0, import_node_fs5.writeFileSync)(path9, JSON.stringify(data, null, 2));
|
|
139072
139182
|
}
|
|
139073
139183
|
function buildMappedSpecCloudKey(mappedSource, specSyncMode, releaseLabel) {
|
|
139074
139184
|
if (specSyncMode !== "version") {
|
|
@@ -139132,22 +139242,422 @@ function buildResourcesManifest(workspaceId, collectionMap, envMap, artifactDir,
|
|
|
139132
139242
|
sortKeys: false
|
|
139133
139243
|
});
|
|
139134
139244
|
}
|
|
139135
|
-
function
|
|
139136
|
-
return
|
|
139137
|
-
|
|
139138
|
-
|
|
139139
|
-
|
|
139140
|
-
|
|
139141
|
-
|
|
139142
|
-
|
|
139245
|
+
function isPlainObject2(value) {
|
|
139246
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
139247
|
+
}
|
|
139248
|
+
function buildSpecCollectionWorkflowManifest(specRef, collectionRefs, existingRaw) {
|
|
139249
|
+
const pairs = collectionRefs.map((collectionRef) => ({
|
|
139250
|
+
spec: specRef,
|
|
139251
|
+
collection: collectionRef
|
|
139252
|
+
}));
|
|
139253
|
+
let root = {};
|
|
139254
|
+
if (typeof existingRaw === "string" && existingRaw.trim()) {
|
|
139255
|
+
let parsed;
|
|
139256
|
+
try {
|
|
139257
|
+
parsed = load(existingRaw);
|
|
139258
|
+
} catch (error2) {
|
|
139259
|
+
throw new Error(
|
|
139260
|
+
`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.`,
|
|
139261
|
+
{ cause: error2 }
|
|
139262
|
+
);
|
|
139263
|
+
}
|
|
139264
|
+
if (parsed === null || parsed === void 0) {
|
|
139265
|
+
root = {};
|
|
139266
|
+
} else if (!isPlainObject2(parsed)) {
|
|
139267
|
+
throw new Error(
|
|
139268
|
+
"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."
|
|
139269
|
+
);
|
|
139270
|
+
} else {
|
|
139271
|
+
root = { ...parsed };
|
|
139272
|
+
}
|
|
139273
|
+
}
|
|
139274
|
+
const workflows = isPlainObject2(root.workflows) ? { ...root.workflows } : {};
|
|
139275
|
+
const desiredCollections = new Set(collectionRefs);
|
|
139276
|
+
const currentPairs = (Array.isArray(workflows.syncSpecToCollection) ? workflows.syncSpecToCollection : []).map((entry) => isPlainObject2(entry) ? { ...entry } : null).filter((entry) => Boolean(entry)).filter(
|
|
139277
|
+
(entry) => String(entry.spec ?? "") !== specRef || desiredCollections.has(String(entry.collection ?? ""))
|
|
139278
|
+
);
|
|
139279
|
+
for (const pair of pairs) {
|
|
139280
|
+
const index = currentPairs.findIndex(
|
|
139281
|
+
(entry) => String(entry.spec ?? "") === pair.spec && String(entry.collection ?? "") === pair.collection
|
|
139282
|
+
);
|
|
139283
|
+
if (index >= 0) {
|
|
139284
|
+
const previous = currentPairs[index];
|
|
139285
|
+
currentPairs[index] = { ...previous, spec: pair.spec, collection: pair.collection };
|
|
139286
|
+
} else {
|
|
139287
|
+
currentPairs.push({ spec: pair.spec, collection: pair.collection });
|
|
139288
|
+
}
|
|
139289
|
+
}
|
|
139290
|
+
workflows.syncSpecToCollection = currentPairs;
|
|
139291
|
+
root.workflows = workflows;
|
|
139292
|
+
return dump(root, {
|
|
139293
|
+
lineWidth: -1,
|
|
139294
|
+
noRefs: true,
|
|
139295
|
+
sortKeys: false
|
|
139296
|
+
});
|
|
139297
|
+
}
|
|
139298
|
+
var PREBUILT_COLLECTION_ROLES = /* @__PURE__ */ new Set([
|
|
139299
|
+
"baseline",
|
|
139300
|
+
"smoke",
|
|
139301
|
+
"contract"
|
|
139302
|
+
]);
|
|
139303
|
+
var SHA256_HEX = /^[a-f0-9]{64}$/;
|
|
139304
|
+
var PREBUILT_CLOUD_ID = /^[A-Za-z0-9][A-Za-z0-9._:-]*$/;
|
|
139305
|
+
function failPrebuiltCollections(detail) {
|
|
139306
|
+
throw new Error(`CONTRACT_PREBUILT_COLLECTIONS_INVALID: ${detail}`);
|
|
139307
|
+
}
|
|
139308
|
+
function parsePrebuiltCollectionsJson(raw) {
|
|
139309
|
+
const trimmed = String(raw ?? "").trim();
|
|
139310
|
+
if (!trimmed) {
|
|
139311
|
+
return [];
|
|
139312
|
+
}
|
|
139313
|
+
let parsed;
|
|
139314
|
+
try {
|
|
139315
|
+
parsed = JSON.parse(trimmed);
|
|
139316
|
+
} catch (error2) {
|
|
139317
|
+
throw new Error(
|
|
139318
|
+
`CONTRACT_PREBUILT_COLLECTIONS_INVALID: malformed JSON (${error2 instanceof Error ? error2.message : String(error2)})`,
|
|
139319
|
+
{ cause: error2 }
|
|
139320
|
+
);
|
|
139321
|
+
}
|
|
139322
|
+
let entriesRaw;
|
|
139323
|
+
if (Array.isArray(parsed)) {
|
|
139324
|
+
entriesRaw = parsed;
|
|
139325
|
+
} else if (isPlainObject2(parsed)) {
|
|
139326
|
+
if (parsed.schemaVersion !== 1) {
|
|
139327
|
+
failPrebuiltCollections("schemaVersion must be 1");
|
|
139328
|
+
}
|
|
139329
|
+
if (!Array.isArray(parsed.collections)) {
|
|
139330
|
+
failPrebuiltCollections("collections must be an array when schemaVersion is set");
|
|
139331
|
+
}
|
|
139332
|
+
entriesRaw = parsed.collections;
|
|
139333
|
+
} else {
|
|
139334
|
+
failPrebuiltCollections("expected a JSON array or {schemaVersion:1,collections:[]}");
|
|
139335
|
+
}
|
|
139336
|
+
const seenRoles = /* @__PURE__ */ new Set();
|
|
139337
|
+
const entries = [];
|
|
139338
|
+
for (const [index, value] of entriesRaw.entries()) {
|
|
139339
|
+
if (!isPlainObject2(value)) {
|
|
139340
|
+
failPrebuiltCollections(`collections[${index}] must be an object`);
|
|
139341
|
+
}
|
|
139342
|
+
const roleRaw = String(value.role ?? "").trim();
|
|
139343
|
+
if (!PREBUILT_COLLECTION_ROLES.has(roleRaw)) {
|
|
139344
|
+
failPrebuiltCollections(
|
|
139345
|
+
`collections[${index}].role must be one of baseline|smoke|contract`
|
|
139346
|
+
);
|
|
139347
|
+
}
|
|
139348
|
+
const role = roleRaw;
|
|
139349
|
+
if (seenRoles.has(role)) {
|
|
139350
|
+
failPrebuiltCollections(`duplicate role ${role}`);
|
|
139351
|
+
}
|
|
139352
|
+
seenRoles.add(role);
|
|
139353
|
+
const collectionPath = String(
|
|
139354
|
+
value.collectionPath ?? value.path ?? ""
|
|
139355
|
+
).trim();
|
|
139356
|
+
if (!collectionPath || hasControlCharacter2(collectionPath)) {
|
|
139357
|
+
failPrebuiltCollections(
|
|
139358
|
+
`collections[${index}].collectionPath must be a non-empty confined relative path`
|
|
139359
|
+
);
|
|
139360
|
+
}
|
|
139361
|
+
const cloudId = String(value.cloudId ?? "").trim();
|
|
139362
|
+
if (!cloudId || !PREBUILT_CLOUD_ID.test(cloudId)) {
|
|
139363
|
+
failPrebuiltCollections(
|
|
139364
|
+
`collections[${index}].cloudId must be a non-empty Postman collection id`
|
|
139365
|
+
);
|
|
139366
|
+
}
|
|
139367
|
+
let payloadDigest;
|
|
139368
|
+
if (Object.prototype.hasOwnProperty.call(value, "payloadDigest")) {
|
|
139369
|
+
const payloadDigestRaw = value.payloadDigest;
|
|
139370
|
+
if (payloadDigestRaw !== void 0 && payloadDigestRaw !== null) {
|
|
139371
|
+
payloadDigest = String(payloadDigestRaw).trim();
|
|
139372
|
+
if (!SHA256_HEX.test(payloadDigest)) {
|
|
139373
|
+
failPrebuiltCollections(
|
|
139374
|
+
`collections[${index}].payloadDigest must be lowercase 64-hex`
|
|
139375
|
+
);
|
|
139376
|
+
}
|
|
139143
139377
|
}
|
|
139144
|
-
},
|
|
139145
|
-
{
|
|
139146
|
-
lineWidth: -1,
|
|
139147
|
-
noRefs: true,
|
|
139148
|
-
sortKeys: false
|
|
139149
139378
|
}
|
|
139379
|
+
const artifactDigest = String(value.artifactDigest ?? "").trim();
|
|
139380
|
+
if (!SHA256_HEX.test(artifactDigest)) {
|
|
139381
|
+
failPrebuiltCollections(
|
|
139382
|
+
`collections[${index}].artifactDigest must be lowercase 64-hex`
|
|
139383
|
+
);
|
|
139384
|
+
}
|
|
139385
|
+
entries.push({
|
|
139386
|
+
role,
|
|
139387
|
+
collectionPath,
|
|
139388
|
+
cloudId,
|
|
139389
|
+
...payloadDigest !== void 0 ? { payloadDigest } : {},
|
|
139390
|
+
artifactDigest
|
|
139391
|
+
});
|
|
139392
|
+
}
|
|
139393
|
+
return entries;
|
|
139394
|
+
}
|
|
139395
|
+
function assertPathWithinArtifactRoot(targetPath, artifactDir, fieldName) {
|
|
139396
|
+
assertPathWithinCwd(targetPath, fieldName);
|
|
139397
|
+
assertPathWithinCwd(artifactDir, "artifact-dir");
|
|
139398
|
+
const cwd = (0, import_node_fs5.realpathSync)(process.cwd());
|
|
139399
|
+
const artifactRoot = path8.resolve(cwd, artifactDir.trim());
|
|
139400
|
+
const resolved = path8.resolve(cwd, targetPath.trim());
|
|
139401
|
+
const relativeToArtifact = path8.relative(artifactRoot, resolved);
|
|
139402
|
+
if (!relativeToArtifact || relativeToArtifact.startsWith("..") || path8.isAbsolute(relativeToArtifact)) {
|
|
139403
|
+
failPrebuiltCollections(
|
|
139404
|
+
`${fieldName} must stay under artifact-dir (${artifactDir}); received ${targetPath}`
|
|
139405
|
+
);
|
|
139406
|
+
}
|
|
139407
|
+
let existingPath = resolved;
|
|
139408
|
+
while (!(0, import_node_fs5.existsSync)(existingPath)) {
|
|
139409
|
+
const parent = path8.dirname(existingPath);
|
|
139410
|
+
if (parent === existingPath) {
|
|
139411
|
+
break;
|
|
139412
|
+
}
|
|
139413
|
+
existingPath = parent;
|
|
139414
|
+
}
|
|
139415
|
+
const realExisting = (0, import_node_fs5.realpathSync)(existingPath);
|
|
139416
|
+
const realRelative = path8.relative(artifactRoot, realExisting);
|
|
139417
|
+
if (realRelative.startsWith("..") || path8.isAbsolute(realRelative)) {
|
|
139418
|
+
failPrebuiltCollections(
|
|
139419
|
+
`${fieldName} resolves outside artifact-dir via symlink; received ${targetPath}`
|
|
139420
|
+
);
|
|
139421
|
+
}
|
|
139422
|
+
return normalizeToPosix(path8.relative(cwd, resolved));
|
|
139423
|
+
}
|
|
139424
|
+
function prebuiltDirectoryTraversalIdentity(absolutePath, stats, options = {}) {
|
|
139425
|
+
const platform2 = options.platform ?? process.platform;
|
|
139426
|
+
const inodeIsZero = stats.ino === 0 || stats.ino === 0n;
|
|
139427
|
+
if (platform2 !== "win32" && !inodeIsZero) {
|
|
139428
|
+
return `${stats.dev}:${stats.ino}`;
|
|
139429
|
+
}
|
|
139430
|
+
const resolveCanonicalPath = options.resolveCanonicalPath ?? ((candidate) => import_node_fs5.realpathSync.native(candidate));
|
|
139431
|
+
const canonical = resolveCanonicalPath(absolutePath);
|
|
139432
|
+
return platform2 === "win32" ? canonical.toLowerCase() : canonical;
|
|
139433
|
+
}
|
|
139434
|
+
function listPrebuiltCollectionTreeFiles(collectionPath, artifactDir) {
|
|
139435
|
+
const confined = assertPathWithinArtifactRoot(
|
|
139436
|
+
collectionPath,
|
|
139437
|
+
artifactDir,
|
|
139438
|
+
"prebuilt collection path"
|
|
139439
|
+
);
|
|
139440
|
+
const absRoot = path8.resolve(process.cwd(), confined);
|
|
139441
|
+
if (!(0, import_node_fs5.existsSync)(absRoot)) {
|
|
139442
|
+
return [];
|
|
139443
|
+
}
|
|
139444
|
+
let rootStat;
|
|
139445
|
+
try {
|
|
139446
|
+
rootStat = (0, import_node_fs5.lstatSync)(absRoot);
|
|
139447
|
+
} catch {
|
|
139448
|
+
return [];
|
|
139449
|
+
}
|
|
139450
|
+
if (rootStat.isSymbolicLink()) {
|
|
139451
|
+
failPrebuiltCollections(
|
|
139452
|
+
`prebuilt collection path must not be a symlink; received ${collectionPath}`
|
|
139453
|
+
);
|
|
139454
|
+
}
|
|
139455
|
+
if (!rootStat.isDirectory()) {
|
|
139456
|
+
return [];
|
|
139457
|
+
}
|
|
139458
|
+
const files = [];
|
|
139459
|
+
const pendingDirectories = [absRoot];
|
|
139460
|
+
const seenDirectories = /* @__PURE__ */ new Set();
|
|
139461
|
+
while (pendingDirectories.length > 0) {
|
|
139462
|
+
const currentAbsolute = pendingDirectories.pop();
|
|
139463
|
+
if (!currentAbsolute) {
|
|
139464
|
+
break;
|
|
139465
|
+
}
|
|
139466
|
+
const currentStat = (0, import_node_fs5.lstatSync)(currentAbsolute);
|
|
139467
|
+
if (currentStat.isSymbolicLink() || !currentStat.isDirectory()) {
|
|
139468
|
+
failPrebuiltCollections(
|
|
139469
|
+
`prebuilt collection tree directory changed or became unsupported at ${normalizeToPosix(path8.relative(absRoot, currentAbsolute)) || "."}`
|
|
139470
|
+
);
|
|
139471
|
+
}
|
|
139472
|
+
const currentKey = prebuiltDirectoryTraversalIdentity(currentAbsolute, currentStat);
|
|
139473
|
+
if (seenDirectories.has(currentKey)) {
|
|
139474
|
+
failPrebuiltCollections(
|
|
139475
|
+
`prebuilt collection tree directory cycle detected at ${normalizeToPosix(path8.relative(absRoot, currentAbsolute)) || "."}`
|
|
139476
|
+
);
|
|
139477
|
+
}
|
|
139478
|
+
seenDirectories.add(currentKey);
|
|
139479
|
+
const entries = (0, import_node_fs5.readdirSync)(currentAbsolute, { withFileTypes: true });
|
|
139480
|
+
for (const entry of entries) {
|
|
139481
|
+
const abs = path8.join(currentAbsolute, entry.name);
|
|
139482
|
+
if (entry.isSymbolicLink()) {
|
|
139483
|
+
failPrebuiltCollections(
|
|
139484
|
+
`prebuilt collection tree must not contain symlinks; received ${normalizeToPosix(path8.relative(absRoot, abs))}`
|
|
139485
|
+
);
|
|
139486
|
+
}
|
|
139487
|
+
if (entry.isDirectory()) {
|
|
139488
|
+
pendingDirectories.push(abs);
|
|
139489
|
+
continue;
|
|
139490
|
+
}
|
|
139491
|
+
if (!entry.isFile()) {
|
|
139492
|
+
failPrebuiltCollections(
|
|
139493
|
+
`prebuilt collection tree contains unsupported entry type at ${normalizeToPosix(path8.relative(absRoot, abs))}`
|
|
139494
|
+
);
|
|
139495
|
+
}
|
|
139496
|
+
const fileLstat = (0, import_node_fs5.lstatSync)(abs);
|
|
139497
|
+
if (fileLstat.isSymbolicLink() || !fileLstat.isFile()) {
|
|
139498
|
+
failPrebuiltCollections(
|
|
139499
|
+
`prebuilt collection tree file changed or became unsupported at ${normalizeToPosix(path8.relative(absRoot, abs))}`
|
|
139500
|
+
);
|
|
139501
|
+
}
|
|
139502
|
+
files.push({
|
|
139503
|
+
absolute: abs,
|
|
139504
|
+
relative: normalizeToPosix(path8.relative(absRoot, abs)),
|
|
139505
|
+
dev: fileLstat.dev,
|
|
139506
|
+
ino: fileLstat.ino,
|
|
139507
|
+
size: fileLstat.size
|
|
139508
|
+
});
|
|
139509
|
+
}
|
|
139510
|
+
}
|
|
139511
|
+
files.sort((a, b) => a.relative.localeCompare(b.relative));
|
|
139512
|
+
return files;
|
|
139513
|
+
}
|
|
139514
|
+
function validateCanonicalV3CollectionFile(relative4, bytes) {
|
|
139515
|
+
let expectedKind;
|
|
139516
|
+
if (/(^|\/)\.resources\/definition\.yaml$/.test(relative4)) {
|
|
139517
|
+
expectedKind = "collection";
|
|
139518
|
+
} else if (relative4.endsWith(".request.yaml")) {
|
|
139519
|
+
expectedKind = "request";
|
|
139520
|
+
} else if (relative4.endsWith(".example.yaml")) {
|
|
139521
|
+
expectedKind = "example";
|
|
139522
|
+
} else if (relative4.endsWith(".message.yaml")) {
|
|
139523
|
+
expectedKind = "message";
|
|
139524
|
+
} else {
|
|
139525
|
+
failPrebuiltCollections(`prebuilt collection tree contains unexpected file ${relative4}`);
|
|
139526
|
+
}
|
|
139527
|
+
let parsed;
|
|
139528
|
+
try {
|
|
139529
|
+
parsed = load(bytes.toString("utf8"));
|
|
139530
|
+
} catch (error2) {
|
|
139531
|
+
failPrebuiltCollections(
|
|
139532
|
+
`prebuilt collection tree contains malformed YAML at ${relative4} (${error2 instanceof Error ? error2.message : String(error2)})`
|
|
139533
|
+
);
|
|
139534
|
+
}
|
|
139535
|
+
if (!isPlainObject2(parsed)) {
|
|
139536
|
+
failPrebuiltCollections(`prebuilt collection tree file ${relative4} must contain a YAML mapping`);
|
|
139537
|
+
}
|
|
139538
|
+
const kind = typeof parsed.$kind === "string" ? parsed.$kind.trim() : "";
|
|
139539
|
+
if (!kind) {
|
|
139540
|
+
failPrebuiltCollections(`prebuilt collection tree file ${relative4} must contain a nonempty $kind`);
|
|
139541
|
+
}
|
|
139542
|
+
const agrees = expectedKind === "collection" ? kind === "collection" : kind.endsWith(`-${expectedKind}`);
|
|
139543
|
+
if (!agrees) {
|
|
139544
|
+
failPrebuiltCollections(
|
|
139545
|
+
`prebuilt collection tree file ${relative4} has $kind ${kind} inconsistent with its filename`
|
|
139546
|
+
);
|
|
139547
|
+
}
|
|
139548
|
+
}
|
|
139549
|
+
async function digestAndValidatePrebuiltCollectionTree(files) {
|
|
139550
|
+
if (!files.some((file) => file.relative === ".resources/definition.yaml")) {
|
|
139551
|
+
failPrebuiltCollections("prebuilt collection tree is missing .resources/definition.yaml");
|
|
139552
|
+
}
|
|
139553
|
+
const hash = (0, import_node_crypto4.createHash)("sha256");
|
|
139554
|
+
for (const file of files) {
|
|
139555
|
+
let bytes;
|
|
139556
|
+
try {
|
|
139557
|
+
bytes = await appendArtifactDigestFileStreaming(hash, file.relative, file.absolute, {
|
|
139558
|
+
dev: file.dev,
|
|
139559
|
+
ino: file.ino,
|
|
139560
|
+
size: file.size
|
|
139561
|
+
});
|
|
139562
|
+
} catch (error2) {
|
|
139563
|
+
if (error2 instanceof ArtifactDigestStreamError) {
|
|
139564
|
+
failPrebuiltCollections(error2.message);
|
|
139565
|
+
}
|
|
139566
|
+
const code = error2?.code;
|
|
139567
|
+
if (code === "ELOOP" || code === "EPERM") {
|
|
139568
|
+
failPrebuiltCollections(
|
|
139569
|
+
`prebuilt collection tree file became a symlink or unsupported node at ${file.relative}`
|
|
139570
|
+
);
|
|
139571
|
+
}
|
|
139572
|
+
failPrebuiltCollections(
|
|
139573
|
+
`prebuilt collection tree file changed or became unsupported at ${file.relative}`
|
|
139574
|
+
);
|
|
139575
|
+
}
|
|
139576
|
+
validateCanonicalV3CollectionFile(file.relative, bytes);
|
|
139577
|
+
}
|
|
139578
|
+
return hash.digest("hex");
|
|
139579
|
+
}
|
|
139580
|
+
async function preparePrebuiltCollections(inputs) {
|
|
139581
|
+
const prepared = /* @__PURE__ */ new Map();
|
|
139582
|
+
for (const entry of parsePrebuiltCollectionsJson(inputs.prebuiltCollectionsJson ?? "")) {
|
|
139583
|
+
const confinedPath = assertPathWithinArtifactRoot(
|
|
139584
|
+
entry.collectionPath,
|
|
139585
|
+
inputs.artifactDir,
|
|
139586
|
+
`prebuilt ${entry.role} collection path`
|
|
139587
|
+
);
|
|
139588
|
+
const absolute = path8.resolve(process.cwd(), confinedPath);
|
|
139589
|
+
if (!(0, import_node_fs5.existsSync)(absolute)) {
|
|
139590
|
+
prepared.set(entry.role, { entry, confinedPath });
|
|
139591
|
+
continue;
|
|
139592
|
+
}
|
|
139593
|
+
const files = listPrebuiltCollectionTreeFiles(confinedPath, inputs.artifactDir);
|
|
139594
|
+
const artifactDigest = await digestAndValidatePrebuiltCollectionTree(files);
|
|
139595
|
+
prepared.set(entry.role, {
|
|
139596
|
+
entry,
|
|
139597
|
+
confinedPath,
|
|
139598
|
+
artifactDigest
|
|
139599
|
+
});
|
|
139600
|
+
}
|
|
139601
|
+
return prepared;
|
|
139602
|
+
}
|
|
139603
|
+
function tryReusePrebuiltCollection(options) {
|
|
139604
|
+
const { prepared, expectedPath, expectedCloudId } = options;
|
|
139605
|
+
const { entry } = prepared;
|
|
139606
|
+
if (!expectedCloudId || entry.cloudId !== expectedCloudId) {
|
|
139607
|
+
return false;
|
|
139608
|
+
}
|
|
139609
|
+
const expectedNormalized = canonicalizeRelativePath(expectedPath);
|
|
139610
|
+
const entryNormalized = canonicalizeRelativePath(entry.collectionPath);
|
|
139611
|
+
if (entryNormalized !== expectedNormalized) {
|
|
139612
|
+
return false;
|
|
139613
|
+
}
|
|
139614
|
+
const confined = canonicalizeRelativePath(prepared.confinedPath);
|
|
139615
|
+
if (confined !== expectedNormalized) {
|
|
139616
|
+
return false;
|
|
139617
|
+
}
|
|
139618
|
+
const expectedName = path8.posix.basename(expectedNormalized);
|
|
139619
|
+
if (path8.posix.basename(confined) !== expectedName) {
|
|
139620
|
+
return false;
|
|
139621
|
+
}
|
|
139622
|
+
return prepared.artifactDigest === entry.artifactDigest;
|
|
139623
|
+
}
|
|
139624
|
+
async function exportCollectionArtifact(options) {
|
|
139625
|
+
const {
|
|
139626
|
+
role,
|
|
139627
|
+
collectionId,
|
|
139628
|
+
dirName,
|
|
139629
|
+
collectionsDir,
|
|
139630
|
+
prebuiltByRole,
|
|
139631
|
+
postman,
|
|
139632
|
+
core
|
|
139633
|
+
} = options;
|
|
139634
|
+
if (!collectionId) {
|
|
139635
|
+
return void 0;
|
|
139636
|
+
}
|
|
139637
|
+
const expectedPath = `${collectionsDir}/${dirName}`;
|
|
139638
|
+
const entry = prebuiltByRole.get(role);
|
|
139639
|
+
if (entry) {
|
|
139640
|
+
const reused = tryReusePrebuiltCollection({
|
|
139641
|
+
prepared: entry,
|
|
139642
|
+
expectedPath,
|
|
139643
|
+
expectedCloudId: collectionId
|
|
139644
|
+
});
|
|
139645
|
+
if (reused) {
|
|
139646
|
+
core.info(
|
|
139647
|
+
`Reusing prebuilt ${role} collection tree at ${expectedPath} (artifactDigest match)`
|
|
139648
|
+
);
|
|
139649
|
+
return `../${expectedPath}`;
|
|
139650
|
+
}
|
|
139651
|
+
core.info(
|
|
139652
|
+
`Prebuilt ${role} collection entry present but did not exactly match; exporting from cloud`
|
|
139653
|
+
);
|
|
139654
|
+
}
|
|
139655
|
+
const col = await postman.getCollection(collectionId);
|
|
139656
|
+
await convertAndSplitAnyCollection(
|
|
139657
|
+
col,
|
|
139658
|
+
expectedPath
|
|
139150
139659
|
);
|
|
139660
|
+
return `../${expectedPath}`;
|
|
139151
139661
|
}
|
|
139152
139662
|
function hasControlCharacter2(value) {
|
|
139153
139663
|
for (let index = 0; index < value.length; index += 1) {
|
|
@@ -139165,21 +139675,21 @@ function assertPathWithinCwd(targetPath, fieldName) {
|
|
|
139165
139675
|
if (!rawPath || hasControlCharacter2(originalPath) || path8.isAbsolute(rawPath) || path8.win32.isAbsolute(rawPath) || segments.includes("..") || rawPath.startsWith(":") || hasControlCharacter2(rawPath)) {
|
|
139166
139676
|
throw new Error(`${fieldName} must stay within the repository root; received ${targetPath}`);
|
|
139167
139677
|
}
|
|
139168
|
-
const base = (0,
|
|
139678
|
+
const base = (0, import_node_fs5.realpathSync)(process.cwd());
|
|
139169
139679
|
const resolved = path8.resolve(base, rawPath);
|
|
139170
139680
|
const relative4 = path8.relative(base, resolved);
|
|
139171
139681
|
if (relative4.startsWith("..") || path8.isAbsolute(relative4)) {
|
|
139172
139682
|
throw new Error(`${fieldName} must stay within the repository root; received ${targetPath}`);
|
|
139173
139683
|
}
|
|
139174
139684
|
let existingPath = resolved;
|
|
139175
|
-
while (!(0,
|
|
139685
|
+
while (!(0, import_node_fs5.existsSync)(existingPath)) {
|
|
139176
139686
|
const parent = path8.dirname(existingPath);
|
|
139177
139687
|
if (parent === existingPath) {
|
|
139178
139688
|
break;
|
|
139179
139689
|
}
|
|
139180
139690
|
existingPath = parent;
|
|
139181
139691
|
}
|
|
139182
|
-
const realExistingPath = (0,
|
|
139692
|
+
const realExistingPath = (0, import_node_fs5.realpathSync)(existingPath);
|
|
139183
139693
|
const realRelative = path8.relative(base, realExistingPath);
|
|
139184
139694
|
if (realRelative.startsWith("..") || path8.isAbsolute(realRelative)) {
|
|
139185
139695
|
throw new Error(`${fieldName} must stay within the repository root; received ${targetPath}`);
|
|
@@ -139207,8 +139717,8 @@ async function exportArtifacts(inputs, dependencies, envUids, assetProjectName,
|
|
|
139207
139717
|
ensureDir(specsDir);
|
|
139208
139718
|
ensureDir(".postman");
|
|
139209
139719
|
const globalsFilePath = `${globalsDir}/workspace.globals.yaml`;
|
|
139210
|
-
if (!(0,
|
|
139211
|
-
(0,
|
|
139720
|
+
if (!(0, import_node_fs5.existsSync)(globalsFilePath)) {
|
|
139721
|
+
(0, import_node_fs5.writeFileSync)(globalsFilePath, "name: Globals\nvalues: []\n");
|
|
139212
139722
|
}
|
|
139213
139723
|
if (inputs.generateCiWorkflow) {
|
|
139214
139724
|
const ciDir = inputs.ciWorkflowPath.split("/").slice(0, -1).join("/");
|
|
@@ -139224,23 +139734,42 @@ async function exportArtifacts(inputs, dependencies, envUids, assetProjectName,
|
|
|
139224
139734
|
inputs.specSyncMode,
|
|
139225
139735
|
options.releaseLabel
|
|
139226
139736
|
) : void 0;
|
|
139227
|
-
|
|
139228
|
-
|
|
139229
|
-
|
|
139230
|
-
|
|
139231
|
-
|
|
139232
|
-
|
|
139233
|
-
|
|
139234
|
-
|
|
139235
|
-
|
|
139236
|
-
|
|
139237
|
-
|
|
139238
|
-
|
|
139239
|
-
|
|
139240
|
-
|
|
139241
|
-
|
|
139242
|
-
|
|
139243
|
-
|
|
139737
|
+
const prebuiltByRole = options.preparedPrebuiltCollections;
|
|
139738
|
+
const baselineRef = await exportCollectionArtifact({
|
|
139739
|
+
role: "baseline",
|
|
139740
|
+
collectionId: inputs.baselineCollectionId,
|
|
139741
|
+
dirName: getCollectionDirectoryName("Baseline", assetProjectName),
|
|
139742
|
+
collectionsDir,
|
|
139743
|
+
prebuiltByRole,
|
|
139744
|
+
postman: dependencies.postman,
|
|
139745
|
+
core: dependencies.core
|
|
139746
|
+
});
|
|
139747
|
+
if (baselineRef) {
|
|
139748
|
+
manifestCollections[baselineRef] = inputs.baselineCollectionId;
|
|
139749
|
+
}
|
|
139750
|
+
const smokeRef = await exportCollectionArtifact({
|
|
139751
|
+
role: "smoke",
|
|
139752
|
+
collectionId: inputs.smokeCollectionId,
|
|
139753
|
+
dirName: getCollectionDirectoryName("Smoke", assetProjectName),
|
|
139754
|
+
collectionsDir,
|
|
139755
|
+
prebuiltByRole,
|
|
139756
|
+
postman: dependencies.postman,
|
|
139757
|
+
core: dependencies.core
|
|
139758
|
+
});
|
|
139759
|
+
if (smokeRef) {
|
|
139760
|
+
manifestCollections[smokeRef] = inputs.smokeCollectionId;
|
|
139761
|
+
}
|
|
139762
|
+
const contractRef = await exportCollectionArtifact({
|
|
139763
|
+
role: "contract",
|
|
139764
|
+
collectionId: inputs.contractCollectionId,
|
|
139765
|
+
dirName: getCollectionDirectoryName("Contract", assetProjectName),
|
|
139766
|
+
collectionsDir,
|
|
139767
|
+
prebuiltByRole,
|
|
139768
|
+
postman: dependencies.postman,
|
|
139769
|
+
core: dependencies.core
|
|
139770
|
+
});
|
|
139771
|
+
if (contractRef) {
|
|
139772
|
+
manifestCollections[contractRef] = inputs.contractCollectionId;
|
|
139244
139773
|
}
|
|
139245
139774
|
for (const [envName, envUid] of Object.entries(envUids)) {
|
|
139246
139775
|
writeJsonFile(
|
|
@@ -139255,7 +139784,7 @@ async function exportArtifacts(inputs, dependencies, envUids, assetProjectName,
|
|
|
139255
139784
|
workspaceLinkEnabled: inputs.workspaceLinkEnabled,
|
|
139256
139785
|
workspaceLinkStatus: options.workspaceLinkStatus
|
|
139257
139786
|
});
|
|
139258
|
-
(0,
|
|
139787
|
+
(0, import_node_fs5.writeFileSync)(".postman/resources.yaml", buildResourcesManifest(
|
|
139259
139788
|
durableWorkspaceId,
|
|
139260
139789
|
manifestCollections,
|
|
139261
139790
|
envUids,
|
|
@@ -139267,11 +139796,18 @@ async function exportArtifacts(inputs, dependencies, envUids, assetProjectName,
|
|
|
139267
139796
|
options.priorState
|
|
139268
139797
|
));
|
|
139269
139798
|
if (mappedSpec && Object.keys(manifestCollections).length > 0) {
|
|
139270
|
-
|
|
139799
|
+
let existingWorkflows;
|
|
139800
|
+
try {
|
|
139801
|
+
existingWorkflows = (0, import_node_fs5.readFileSync)(".postman/workflows.yaml", "utf8");
|
|
139802
|
+
} catch {
|
|
139803
|
+
existingWorkflows = void 0;
|
|
139804
|
+
}
|
|
139805
|
+
(0, import_node_fs5.writeFileSync)(
|
|
139271
139806
|
".postman/workflows.yaml",
|
|
139272
139807
|
buildSpecCollectionWorkflowManifest(
|
|
139273
139808
|
mappedSpec.configRelativePath,
|
|
139274
|
-
Object.keys(manifestCollections)
|
|
139809
|
+
Object.keys(manifestCollections),
|
|
139810
|
+
existingWorkflows
|
|
139275
139811
|
)
|
|
139276
139812
|
);
|
|
139277
139813
|
}
|
|
@@ -139316,12 +139852,12 @@ async function commitAndPushGeneratedFiles(inputs, dependencies) {
|
|
|
139316
139852
|
const dir = parts.slice(0, -1).join("/");
|
|
139317
139853
|
ensureDir(dir);
|
|
139318
139854
|
}
|
|
139319
|
-
(0,
|
|
139855
|
+
(0, import_node_fs5.writeFileSync)(inputs.ciWorkflowPath, ciWorkflow);
|
|
139320
139856
|
if (inputs.provider === "github" || inputs.provider === "unknown") {
|
|
139321
139857
|
const gcPath = ".github/workflows/postman-preview-gc.yml";
|
|
139322
139858
|
if (inputs.ciWorkflowPath.endsWith(".github/workflows/ci.yml") || inputs.ciWorkflowPath === ".github/workflows/ci.yml") {
|
|
139323
139859
|
ensureDir(".github/workflows");
|
|
139324
|
-
(0,
|
|
139860
|
+
(0, import_node_fs5.writeFileSync)(gcPath, renderGcWorkflowTemplate());
|
|
139325
139861
|
}
|
|
139326
139862
|
}
|
|
139327
139863
|
}
|
|
@@ -139329,16 +139865,16 @@ async function commitAndPushGeneratedFiles(inputs, dependencies) {
|
|
|
139329
139865
|
return { commitSha: "", resolvedCurrentRef: "", pushed: false };
|
|
139330
139866
|
}
|
|
139331
139867
|
const provisionPath = ".github/workflows/provision.yml";
|
|
139332
|
-
const provisionExists = inputs.provider === "github" && (0,
|
|
139868
|
+
const provisionExists = inputs.provider === "github" && (0, import_node_fs5.existsSync)(provisionPath);
|
|
139333
139869
|
const gcWorkflowPath = ".github/workflows/postman-preview-gc.yml";
|
|
139334
|
-
const gcExists = inputs.generateCiWorkflow && (0,
|
|
139870
|
+
const gcExists = inputs.generateCiWorkflow && (0, import_node_fs5.existsSync)(gcWorkflowPath);
|
|
139335
139871
|
const stagePaths = [
|
|
139336
139872
|
inputs.artifactDir,
|
|
139337
139873
|
".postman",
|
|
139338
139874
|
inputs.generateCiWorkflow ? inputs.ciWorkflowPath : null,
|
|
139339
139875
|
gcExists ? gcWorkflowPath : null,
|
|
139340
139876
|
provisionExists ? provisionPath : null
|
|
139341
|
-
].filter((entry) => typeof entry === "string" && ((0,
|
|
139877
|
+
].filter((entry) => typeof entry === "string" && ((0, import_node_fs5.existsSync)(entry) || entry === provisionPath));
|
|
139342
139878
|
if (stagePaths.length === 0) {
|
|
139343
139879
|
dependencies.core.info("No generated repository paths were found; skipping repo mutation.");
|
|
139344
139880
|
return {
|
|
@@ -139446,6 +139982,7 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
139446
139982
|
}
|
|
139447
139983
|
}
|
|
139448
139984
|
}
|
|
139985
|
+
const preparedPrebuiltCollections = await preparePrebuiltCollections(inputs);
|
|
139449
139986
|
let skipRepositoryLinkPost = false;
|
|
139450
139987
|
let repositoryLinkPreflightWasFree = false;
|
|
139451
139988
|
if (inputs.workspaceLinkEnabled && inputs.workspaceId && inputs.repoUrl && dependencies.internalIntegration?.findWorkspaceForRepo) {
|
|
@@ -139482,6 +140019,7 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
139482
140019
|
const branchAssetMarker = buildBranchAssetMarker(branchDecision, inputs);
|
|
139483
140020
|
const envUids = await upsertEnvironments(inputs, dependencies, resourcesState, branchAssetMarker);
|
|
139484
140021
|
outputs["environment-uids-json"] = JSON.stringify(envUids);
|
|
140022
|
+
dependencies.core.setOutput("environment-uids-json", outputs["environment-uids-json"]);
|
|
139485
140023
|
if (inputs.environmentSyncEnabled && inputs.workspaceId && dependencies.internalIntegration) {
|
|
139486
140024
|
const associations = Object.entries(envUids).map(([envName, envUid]) => ({
|
|
139487
140025
|
envUid,
|
|
@@ -139600,6 +140138,7 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
139600
140138
|
}
|
|
139601
140139
|
}
|
|
139602
140140
|
outputs["mock-url"] = resolvedMockUrl;
|
|
140141
|
+
dependencies.core.setOutput("mock-url", resolvedMockUrl);
|
|
139603
140142
|
}
|
|
139604
140143
|
}
|
|
139605
140144
|
if (inputs.workspaceId && inputs.smokeCollectionId && Object.keys(envUids).length > 0) {
|
|
@@ -139675,6 +140214,7 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
139675
140214
|
}
|
|
139676
140215
|
}
|
|
139677
140216
|
outputs["monitor-id"] = resolvedMonitorId;
|
|
140217
|
+
dependencies.core.setOutput("monitor-id", resolvedMonitorId);
|
|
139678
140218
|
if (!effectiveCron && resolvedMonitorId) {
|
|
139679
140219
|
try {
|
|
139680
140220
|
await dependencies.postman.runMonitor(resolvedMonitorId);
|
|
@@ -139732,7 +140272,8 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
139732
140272
|
priorWorkspaceId: resourcesState?.workspace?.id,
|
|
139733
140273
|
existingSpecs: resourcesState?.cloudResources?.specs,
|
|
139734
140274
|
releaseLabel,
|
|
139735
|
-
priorState: resourcesState
|
|
140275
|
+
priorState: resourcesState,
|
|
140276
|
+
preparedPrebuiltCollections
|
|
139736
140277
|
});
|
|
139737
140278
|
const commit = await commitAndPushGeneratedFiles(inputs, dependencies);
|
|
139738
140279
|
outputs["commit-sha"] = commit.commitSha;
|
|
@@ -139958,7 +140499,12 @@ async function resolvePostmanApiKeyAndTeamId(inputs, actionCore, actionExec, mas
|
|
|
139958
140499
|
bifrostBaseUrl: inputs.postmanBifrostBase,
|
|
139959
140500
|
// No fallback on the org-mode probe: the expected non-org 400 must
|
|
139960
140501
|
// surface verbatim, not be re-fired against the /_api alias.
|
|
139961
|
-
secretMasker: masker
|
|
140502
|
+
secretMasker: masker,
|
|
140503
|
+
onRetryEvent: (event) => {
|
|
140504
|
+
actionCore.info(
|
|
140505
|
+
`[postman retry] action=repo-sync class=${event.class} status=${event.status ?? "none"} attempt=${event.attempt} delayMs=${event.delay}`
|
|
140506
|
+
);
|
|
140507
|
+
}
|
|
139962
140508
|
});
|
|
139963
140509
|
const squads = await gateway.getSquads(teamId);
|
|
139964
140510
|
if (squads.length > 0) {
|
|
@@ -140022,7 +140568,12 @@ function createRepoSyncDependencies(inputs, resolved, factories, options = {}) {
|
|
|
140022
140568
|
fallbackBaseUrl: inputs.postmanFallbackBase,
|
|
140023
140569
|
teamId: resolved.teamId,
|
|
140024
140570
|
orgMode: inputs.orgMode,
|
|
140025
|
-
secretMasker: masker
|
|
140571
|
+
secretMasker: masker,
|
|
140572
|
+
onRetryEvent: (event) => {
|
|
140573
|
+
factories.core.info(
|
|
140574
|
+
`[postman retry] action=repo-sync class=${event.class} status=${event.status ?? "none"} attempt=${event.attempt} delayMs=${event.delay}`
|
|
140575
|
+
);
|
|
140576
|
+
}
|
|
140026
140577
|
});
|
|
140027
140578
|
const gatewayAssets = new PostmanGatewayAssetsClient({
|
|
140028
140579
|
gateway,
|
|
@@ -140141,7 +140692,10 @@ async function runAction(actionCore = core_exports, actionExec = exec_exports) {
|
|
|
140141
140692
|
}
|
|
140142
140693
|
await mintAccessTokenIfNeeded(inputs, {
|
|
140143
140694
|
info: (message) => actionCore.info(message),
|
|
140144
|
-
warning: (message) => actionCore.warning(message)
|
|
140695
|
+
warning: (message) => actionCore.warning(message),
|
|
140696
|
+
retryEvent: (event) => actionCore.info(
|
|
140697
|
+
`[postman retry] action=repo-sync class=${event.class} status=${event.status ?? "none"} attempt=${event.attempt} delayMs=${event.delay}`
|
|
140698
|
+
)
|
|
140145
140699
|
}, (secret) => actionCore.setSecret(secret));
|
|
140146
140700
|
const masker = createSecretMasker([
|
|
140147
140701
|
inputs.postmanApiKey,
|
|
@@ -140162,7 +140716,12 @@ async function runAction(actionCore = core_exports, actionExec = exec_exports) {
|
|
|
140162
140716
|
explicitTeamId: inputs.teamId || void 0,
|
|
140163
140717
|
mode: inputs.credentialPreflight,
|
|
140164
140718
|
mask: masker,
|
|
140165
|
-
log:
|
|
140719
|
+
log: {
|
|
140720
|
+
...actionCore,
|
|
140721
|
+
retryEvent: (event) => actionCore.info(
|
|
140722
|
+
`[postman retry] action=repo-sync class=${event.class} status=${event.status ?? "none"} attempt=${event.attempt} delayMs=${event.delay}`
|
|
140723
|
+
)
|
|
140724
|
+
}
|
|
140166
140725
|
});
|
|
140167
140726
|
const resolved = await resolvePostmanApiKeyAndTeamId(inputs, actionCore, actionExec, masker, {
|
|
140168
140727
|
env: process.env
|