@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/index.cjs
CHANGED
|
@@ -26570,7 +26570,7 @@ var require_util7 = __commonJS({
|
|
|
26570
26570
|
exports2.esc = esc;
|
|
26571
26571
|
exports2.slugify = slugify;
|
|
26572
26572
|
exports2.isObject = isObject;
|
|
26573
|
-
exports2.isPlainObject =
|
|
26573
|
+
exports2.isPlainObject = isPlainObject3;
|
|
26574
26574
|
exports2.shallowClone = shallowClone;
|
|
26575
26575
|
exports2.numKeys = numKeys;
|
|
26576
26576
|
exports2.escapeRegex = escapeRegex;
|
|
@@ -26753,7 +26753,7 @@ var require_util7 = __commonJS({
|
|
|
26753
26753
|
return false;
|
|
26754
26754
|
}
|
|
26755
26755
|
});
|
|
26756
|
-
function
|
|
26756
|
+
function isPlainObject3(o) {
|
|
26757
26757
|
if (isObject(o) === false)
|
|
26758
26758
|
return false;
|
|
26759
26759
|
const ctor = o.constructor;
|
|
@@ -26770,7 +26770,7 @@ var require_util7 = __commonJS({
|
|
|
26770
26770
|
return true;
|
|
26771
26771
|
}
|
|
26772
26772
|
function shallowClone(o) {
|
|
26773
|
-
if (
|
|
26773
|
+
if (isPlainObject3(o))
|
|
26774
26774
|
return { ...o };
|
|
26775
26775
|
if (Array.isArray(o))
|
|
26776
26776
|
return [...o];
|
|
@@ -26975,7 +26975,7 @@ var require_util7 = __commonJS({
|
|
|
26975
26975
|
return clone(schema, def);
|
|
26976
26976
|
}
|
|
26977
26977
|
function extend(schema, shape) {
|
|
26978
|
-
if (!
|
|
26978
|
+
if (!isPlainObject3(shape)) {
|
|
26979
26979
|
throw new Error("Invalid input to extend: expected a plain object");
|
|
26980
26980
|
}
|
|
26981
26981
|
const checks = schema._zod.def.checks;
|
|
@@ -26998,7 +26998,7 @@ var require_util7 = __commonJS({
|
|
|
26998
26998
|
return clone(schema, def);
|
|
26999
26999
|
}
|
|
27000
27000
|
function safeExtend(schema, shape) {
|
|
27001
|
-
if (!
|
|
27001
|
+
if (!isPlainObject3(shape)) {
|
|
27002
27002
|
throw new Error("Invalid input to safeExtend: expected a plain object");
|
|
27003
27003
|
}
|
|
27004
27004
|
const def = mergeDefs(schema._zod.def, {
|
|
@@ -54817,7 +54817,7 @@ var require_lodash = __commonJS({
|
|
|
54817
54817
|
} else {
|
|
54818
54818
|
newValue = [];
|
|
54819
54819
|
}
|
|
54820
|
-
} else if (
|
|
54820
|
+
} else if (isPlainObject3(srcValue) || isArguments(srcValue)) {
|
|
54821
54821
|
newValue = objValue;
|
|
54822
54822
|
if (isArguments(objValue)) {
|
|
54823
54823
|
newValue = toPlainObject(objValue);
|
|
@@ -55781,7 +55781,7 @@ var require_lodash = __commonJS({
|
|
|
55781
55781
|
return objValue;
|
|
55782
55782
|
}
|
|
55783
55783
|
function customOmitClone(value) {
|
|
55784
|
-
return
|
|
55784
|
+
return isPlainObject3(value) ? undefined2 : value;
|
|
55785
55785
|
}
|
|
55786
55786
|
function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
|
|
55787
55787
|
var isPartial = bitmask & COMPARE_PARTIAL_FLAG, arrLength = array.length, othLength = other.length;
|
|
@@ -57282,7 +57282,7 @@ var require_lodash = __commonJS({
|
|
|
57282
57282
|
var isBuffer = nativeIsBuffer || stubFalse;
|
|
57283
57283
|
var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
|
|
57284
57284
|
function isElement(value) {
|
|
57285
|
-
return isObjectLike(value) && value.nodeType === 1 && !
|
|
57285
|
+
return isObjectLike(value) && value.nodeType === 1 && !isPlainObject3(value);
|
|
57286
57286
|
}
|
|
57287
57287
|
function isEmpty(value) {
|
|
57288
57288
|
if (value == null) {
|
|
@@ -57318,7 +57318,7 @@ var require_lodash = __commonJS({
|
|
|
57318
57318
|
return false;
|
|
57319
57319
|
}
|
|
57320
57320
|
var tag = baseGetTag(value);
|
|
57321
|
-
return tag == errorTag || tag == domExcTag || typeof value.message == "string" && typeof value.name == "string" && !
|
|
57321
|
+
return tag == errorTag || tag == domExcTag || typeof value.message == "string" && typeof value.name == "string" && !isPlainObject3(value);
|
|
57322
57322
|
}
|
|
57323
57323
|
function isFinite2(value) {
|
|
57324
57324
|
return typeof value == "number" && nativeIsFinite(value);
|
|
@@ -57369,7 +57369,7 @@ var require_lodash = __commonJS({
|
|
|
57369
57369
|
function isNumber(value) {
|
|
57370
57370
|
return typeof value == "number" || isObjectLike(value) && baseGetTag(value) == numberTag;
|
|
57371
57371
|
}
|
|
57372
|
-
function
|
|
57372
|
+
function isPlainObject3(value) {
|
|
57373
57373
|
if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
|
|
57374
57374
|
return false;
|
|
57375
57375
|
}
|
|
@@ -58440,7 +58440,7 @@ var require_lodash = __commonJS({
|
|
|
58440
58440
|
lodash.isNumber = isNumber;
|
|
58441
58441
|
lodash.isObject = isObject;
|
|
58442
58442
|
lodash.isObjectLike = isObjectLike;
|
|
58443
|
-
lodash.isPlainObject =
|
|
58443
|
+
lodash.isPlainObject = isPlainObject3;
|
|
58444
58444
|
lodash.isRegExp = isRegExp;
|
|
58445
58445
|
lodash.isSafeInteger = isSafeInteger;
|
|
58446
58446
|
lodash.isSet = isSet;
|
|
@@ -128815,6 +128815,7 @@ __export(index_exports, {
|
|
|
128815
128815
|
decideBranchTier: () => decideBranchTier,
|
|
128816
128816
|
getInput: () => getInput2,
|
|
128817
128817
|
hasInput: () => hasInput,
|
|
128818
|
+
prebuiltDirectoryTraversalIdentity: () => prebuiltDirectoryTraversalIdentity,
|
|
128818
128819
|
readActionInputs: () => readActionInputs,
|
|
128819
128820
|
resolveInputs: () => resolveInputs,
|
|
128820
128821
|
resolvePostmanApiKeyAndTeamId: () => resolvePostmanApiKeyAndTeamId,
|
|
@@ -131103,7 +131104,8 @@ function getIDToken(aud) {
|
|
|
131103
131104
|
}
|
|
131104
131105
|
|
|
131105
131106
|
// src/index.ts
|
|
131106
|
-
var
|
|
131107
|
+
var import_node_crypto4 = require("node:crypto");
|
|
131108
|
+
var import_node_fs5 = require("node:fs");
|
|
131107
131109
|
var path8 = __toESM(require("node:path"), 1);
|
|
131108
131110
|
|
|
131109
131111
|
// node_modules/js-yaml/dist/js-yaml.mjs
|
|
@@ -134019,6 +134021,7 @@ function dump(input, options = {}) {
|
|
|
134019
134021
|
}
|
|
134020
134022
|
|
|
134021
134023
|
// src/postman-v3/converter.ts
|
|
134024
|
+
var import_node_fs = require("node:fs");
|
|
134022
134025
|
var fs3 = __toESM(require("node:fs/promises"), 1);
|
|
134023
134026
|
var path6 = __toESM(require("node:path"), 1);
|
|
134024
134027
|
var V2 = __toESM(require_v2(), 1);
|
|
@@ -134089,6 +134092,72 @@ function structuredCloneSafe(value) {
|
|
|
134089
134092
|
if (typeof structuredClone === "function") return structuredClone(value);
|
|
134090
134093
|
return JSON.parse(JSON.stringify(value));
|
|
134091
134094
|
}
|
|
134095
|
+
var ArtifactDigestStreamError = class extends Error {
|
|
134096
|
+
code = "ARTIFACT_DIGEST_STREAM";
|
|
134097
|
+
constructor(message, options) {
|
|
134098
|
+
super(message, options);
|
|
134099
|
+
this.name = "ArtifactDigestStreamError";
|
|
134100
|
+
}
|
|
134101
|
+
};
|
|
134102
|
+
function sameFileIdentity(left, right) {
|
|
134103
|
+
return left.dev === right.dev && left.ino === right.ino && left.size === right.size;
|
|
134104
|
+
}
|
|
134105
|
+
async function appendArtifactDigestFileStreaming(hash, relative4, absolute, expected) {
|
|
134106
|
+
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;
|
|
134107
|
+
let handle;
|
|
134108
|
+
try {
|
|
134109
|
+
handle = await fs3.open(absolute, flags);
|
|
134110
|
+
} catch (error2) {
|
|
134111
|
+
const code = error2?.code;
|
|
134112
|
+
if (code === "ELOOP" || code === "EMLINK" || code === "EINVAL") {
|
|
134113
|
+
throw new ArtifactDigestStreamError(
|
|
134114
|
+
`prebuilt collection tree file became a symlink or unsupported node at ${relative4}`,
|
|
134115
|
+
{ cause: error2 }
|
|
134116
|
+
);
|
|
134117
|
+
}
|
|
134118
|
+
throw new ArtifactDigestStreamError(
|
|
134119
|
+
`prebuilt collection tree file changed or became unsupported at ${relative4}`,
|
|
134120
|
+
{ cause: error2 }
|
|
134121
|
+
);
|
|
134122
|
+
}
|
|
134123
|
+
try {
|
|
134124
|
+
const before = await handle.stat();
|
|
134125
|
+
if (!before.isFile() || !sameFileIdentity(before, expected)) {
|
|
134126
|
+
throw new ArtifactDigestStreamError(
|
|
134127
|
+
`prebuilt collection tree file changed or became unsupported at ${relative4}`
|
|
134128
|
+
);
|
|
134129
|
+
}
|
|
134130
|
+
hash.update(relative4);
|
|
134131
|
+
hash.update("\0");
|
|
134132
|
+
const content = Buffer.allocUnsafe(expected.size);
|
|
134133
|
+
let total = 0;
|
|
134134
|
+
const buffer = Buffer.alloc(64 * 1024);
|
|
134135
|
+
for (; ; ) {
|
|
134136
|
+
const { bytesRead } = await handle.read(buffer, 0, buffer.length, null);
|
|
134137
|
+
if (bytesRead === 0) {
|
|
134138
|
+
break;
|
|
134139
|
+
}
|
|
134140
|
+
if (total + bytesRead > expected.size) {
|
|
134141
|
+
throw new ArtifactDigestStreamError(
|
|
134142
|
+
`prebuilt collection tree file changed while reading at ${relative4}`
|
|
134143
|
+
);
|
|
134144
|
+
}
|
|
134145
|
+
buffer.copy(content, total, 0, bytesRead);
|
|
134146
|
+
hash.update(buffer.subarray(0, bytesRead));
|
|
134147
|
+
total += bytesRead;
|
|
134148
|
+
}
|
|
134149
|
+
hash.update("\0");
|
|
134150
|
+
const after = await handle.stat();
|
|
134151
|
+
if (!after.isFile() || !sameFileIdentity(after, expected) || total !== expected.size) {
|
|
134152
|
+
throw new ArtifactDigestStreamError(
|
|
134153
|
+
`prebuilt collection tree file changed while reading at ${relative4}`
|
|
134154
|
+
);
|
|
134155
|
+
}
|
|
134156
|
+
return total === expected.size ? content : content.subarray(0, total);
|
|
134157
|
+
} finally {
|
|
134158
|
+
await handle.close();
|
|
134159
|
+
}
|
|
134160
|
+
}
|
|
134092
134161
|
async function listFilesRelative(dir, base) {
|
|
134093
134162
|
let entries;
|
|
134094
134163
|
try {
|
|
@@ -134649,7 +134718,7 @@ function getCiWorkflowTemplate(provider, options = {}) {
|
|
|
134649
134718
|
}
|
|
134650
134719
|
|
|
134651
134720
|
// src/lib/github/repo-mutation.ts
|
|
134652
|
-
var
|
|
134721
|
+
var import_node_fs2 = require("node:fs");
|
|
134653
134722
|
var import_node_path = __toESM(require("node:path"), 1);
|
|
134654
134723
|
|
|
134655
134724
|
// src/lib/secrets.ts
|
|
@@ -134939,7 +135008,7 @@ var RepoMutationService = class {
|
|
|
134939
135008
|
throw new Error(this.secretMasker(changed.stderr || changed.stdout || "Failed to inspect generated changes"));
|
|
134940
135009
|
}
|
|
134941
135010
|
const hasPlannedRemoval = removePaths.some(
|
|
134942
|
-
(removePath) => (0,
|
|
135011
|
+
(removePath) => (0, import_node_fs2.existsSync)(import_node_path.default.resolve(this.cwd, removePath))
|
|
134943
135012
|
);
|
|
134944
135013
|
if (!changed.stdout.trim() && !hasPlannedRemoval) {
|
|
134945
135014
|
return {
|
|
@@ -134963,7 +135032,7 @@ var RepoMutationService = class {
|
|
|
134963
135032
|
await this.execute("git", ["config", "user.name", options.committerName]);
|
|
134964
135033
|
await this.execute("git", ["config", "user.email", options.committerEmail]);
|
|
134965
135034
|
for (const removePath of removePaths) {
|
|
134966
|
-
(0,
|
|
135035
|
+
(0, import_node_fs2.rmSync)(import_node_path.default.resolve(this.cwd, removePath), { force: true });
|
|
134967
135036
|
}
|
|
134968
135037
|
await this.execute("git", ["add", "-A", "--", ...stagePaths]);
|
|
134969
135038
|
const staged = await this.execute("git", ["diff", "--cached", "--quiet"]);
|
|
@@ -135506,14 +135575,14 @@ function createTelemetryContext(options) {
|
|
|
135506
135575
|
}
|
|
135507
135576
|
|
|
135508
135577
|
// src/action-version.ts
|
|
135509
|
-
var
|
|
135578
|
+
var import_node_fs3 = require("node:fs");
|
|
135510
135579
|
var import_node_path2 = require("node:path");
|
|
135511
135580
|
function resolveActionVersion2() {
|
|
135512
135581
|
if (false) {
|
|
135513
135582
|
return void 0;
|
|
135514
135583
|
}
|
|
135515
135584
|
try {
|
|
135516
|
-
const raw = (0,
|
|
135585
|
+
const raw = (0, import_node_fs3.readFileSync)((0, import_node_path2.join)(__dirname, "..", "package.json"), "utf8");
|
|
135517
135586
|
return JSON.parse(raw).version ?? "unknown";
|
|
135518
135587
|
} catch {
|
|
135519
135588
|
return "unknown";
|
|
@@ -135752,7 +135821,8 @@ async function resolveSessionIdentity(opts) {
|
|
|
135752
135821
|
opts.fetchImpl ?? fetch,
|
|
135753
135822
|
Math.max(1, opts.maxAttempts ?? SESSION_MAX_ATTEMPTS),
|
|
135754
135823
|
opts.sleepImpl ?? defaultSessionSleep,
|
|
135755
|
-
opts.randomImpl ?? defaultRandom
|
|
135824
|
+
opts.randomImpl ?? defaultRandom,
|
|
135825
|
+
opts.onRetryEvent
|
|
135756
135826
|
);
|
|
135757
135827
|
sessionMemo.set(memoKey, pending);
|
|
135758
135828
|
}
|
|
@@ -135786,7 +135856,7 @@ async function parseSessionResponse(response) {
|
|
|
135786
135856
|
consumerType: coerceText(root.consumerType) ?? coerceText(data?.consumerType) ?? coerceText(user?.consumerType)
|
|
135787
135857
|
};
|
|
135788
135858
|
}
|
|
135789
|
-
async function probeSessionIdentity(baseUrl, accessToken, fetchImpl, maxAttempts, sleepImpl, random) {
|
|
135859
|
+
async function probeSessionIdentity(baseUrl, accessToken, fetchImpl, maxAttempts, sleepImpl, random, onRetryEvent) {
|
|
135790
135860
|
let failure = "unavailable";
|
|
135791
135861
|
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
135792
135862
|
let response;
|
|
@@ -135798,7 +135868,9 @@ async function probeSessionIdentity(baseUrl, accessToken, fetchImpl, maxAttempts
|
|
|
135798
135868
|
} catch {
|
|
135799
135869
|
failure = "unavailable";
|
|
135800
135870
|
if (attempt < maxAttempts) {
|
|
135801
|
-
|
|
135871
|
+
const delay = computeSessionRetryDelayMs(void 0, attempt, random);
|
|
135872
|
+
onRetryEvent?.({ class: "transport", attempt, delay });
|
|
135873
|
+
await sleepImpl(delay);
|
|
135802
135874
|
continue;
|
|
135803
135875
|
}
|
|
135804
135876
|
break;
|
|
@@ -135820,7 +135892,9 @@ async function probeSessionIdentity(baseUrl, accessToken, fetchImpl, maxAttempts
|
|
|
135820
135892
|
if (response.status === 429 || response.status >= 500) {
|
|
135821
135893
|
failure = "unavailable";
|
|
135822
135894
|
if (attempt < maxAttempts) {
|
|
135823
|
-
|
|
135895
|
+
const delay = computeSessionRetryDelayMs(response, attempt, random);
|
|
135896
|
+
onRetryEvent?.({ class: "http", status: response.status, attempt, delay });
|
|
135897
|
+
await sleepImpl(delay);
|
|
135824
135898
|
continue;
|
|
135825
135899
|
}
|
|
135826
135900
|
break;
|
|
@@ -135922,7 +135996,8 @@ async function runCredentialPreflight(args) {
|
|
|
135922
135996
|
accessToken,
|
|
135923
135997
|
fetchImpl: args.fetchImpl,
|
|
135924
135998
|
...args.sleepImpl ? { sleepImpl: args.sleepImpl } : {},
|
|
135925
|
-
...args.randomImpl ? { randomImpl: args.randomImpl } : {}
|
|
135999
|
+
...args.randomImpl ? { randomImpl: args.randomImpl } : {},
|
|
136000
|
+
onRetryEvent: args.retryEvent ?? args.log.retryEvent
|
|
135926
136001
|
});
|
|
135927
136002
|
} catch (error2) {
|
|
135928
136003
|
args.log.warning(
|
|
@@ -136574,6 +136649,11 @@ var postmanRepoSyncActionContract = {
|
|
|
136574
136649
|
description: "Contract collection ID used for exported artifacts.",
|
|
136575
136650
|
required: false
|
|
136576
136651
|
},
|
|
136652
|
+
"prebuilt-collections-json": {
|
|
136653
|
+
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.",
|
|
136654
|
+
required: false,
|
|
136655
|
+
default: ""
|
|
136656
|
+
},
|
|
136577
136657
|
"collection-sync-mode": {
|
|
136578
136658
|
description: "Collection sync lifecycle mode (refresh or version).",
|
|
136579
136659
|
required: false,
|
|
@@ -136816,7 +136896,7 @@ var postmanRepoSyncActionContract = {
|
|
|
136816
136896
|
"Create or update Postman environments from runtime URLs.",
|
|
136817
136897
|
"Associate Postman environments to system environments through Postman integration APIs.",
|
|
136818
136898
|
"Create mock servers and smoke monitors from generated collections.",
|
|
136819
|
-
"Export Postman collections in the Collection v3 multi-file YAML directory structure under `postman/collections/` (
|
|
136899
|
+
"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.",
|
|
136820
136900
|
"Link the Postman workspace to the repository (GitHub or GitLab) through Postman integration APIs.",
|
|
136821
136901
|
"Commit synced artifacts and push them back to the current checked out ref."
|
|
136822
136902
|
],
|
|
@@ -137601,6 +137681,7 @@ var AccessTokenProvider = class {
|
|
|
137601
137681
|
maxAttempts;
|
|
137602
137682
|
onToken;
|
|
137603
137683
|
sleep;
|
|
137684
|
+
onRetryEvent;
|
|
137604
137685
|
inflight;
|
|
137605
137686
|
constructor(options) {
|
|
137606
137687
|
this.token = String(options.accessToken || "").trim();
|
|
@@ -137612,6 +137693,7 @@ var AccessTokenProvider = class {
|
|
|
137612
137693
|
this.maxAttempts = Math.max(1, options.maxAttempts ?? 2);
|
|
137613
137694
|
this.onToken = options.onToken;
|
|
137614
137695
|
this.sleep = options.sleep;
|
|
137696
|
+
this.onRetryEvent = options.onRetryEvent;
|
|
137615
137697
|
}
|
|
137616
137698
|
current() {
|
|
137617
137699
|
return this.token;
|
|
@@ -137637,7 +137719,12 @@ var AccessTokenProvider = class {
|
|
|
137637
137719
|
delayMs: 1e3,
|
|
137638
137720
|
backoffMultiplier: 2,
|
|
137639
137721
|
...this.sleep ? { sleep: this.sleep } : {},
|
|
137640
|
-
shouldRetry: (error2) => !(error2 instanceof MintError && error2.permanent)
|
|
137722
|
+
shouldRetry: (error2) => !(error2 instanceof MintError && error2.permanent),
|
|
137723
|
+
onRetry: ({ attempt, delayMs, error: error2 }) => {
|
|
137724
|
+
const status = error2 instanceof MintError ? error2.status : void 0;
|
|
137725
|
+
const retryClass = status === void 0 ? "transport" : "http";
|
|
137726
|
+
this.onRetryEvent?.({ class: retryClass, ...status === void 0 ? {} : { status }, attempt, delay: Math.max(0, delayMs) });
|
|
137727
|
+
}
|
|
137641
137728
|
});
|
|
137642
137729
|
this.token = token;
|
|
137643
137730
|
this.onToken?.(token);
|
|
@@ -137668,7 +137755,7 @@ var AccessTokenProvider = class {
|
|
|
137668
137755
|
true
|
|
137669
137756
|
);
|
|
137670
137757
|
}
|
|
137671
|
-
throw new MintError(`postman: re-mint failed (service-account-tokens HTTP ${status}).`, false);
|
|
137758
|
+
throw new MintError(`postman: re-mint failed (service-account-tokens HTTP ${status}).`, false, status);
|
|
137672
137759
|
}
|
|
137673
137760
|
let parsed;
|
|
137674
137761
|
try {
|
|
@@ -137699,7 +137786,8 @@ async function mintAccessTokenIfNeeded(inputs, log, setSecret2, fetchImpl = fetc
|
|
|
137699
137786
|
apiKey: inputs.postmanApiKey,
|
|
137700
137787
|
apiBaseUrl,
|
|
137701
137788
|
fetchImpl,
|
|
137702
|
-
onToken: (token) => setSecret2?.(token)
|
|
137789
|
+
onToken: (token) => setSecret2?.(token),
|
|
137790
|
+
onRetryEvent: (event) => log.retryEvent?.(event)
|
|
137703
137791
|
});
|
|
137704
137792
|
try {
|
|
137705
137793
|
inputs.postmanAccessToken = await provider.refresh();
|
|
@@ -137739,6 +137827,7 @@ var AccessTokenGatewayClient = class {
|
|
|
137739
137827
|
requestTimeoutMs;
|
|
137740
137828
|
retryMaxDelayMs;
|
|
137741
137829
|
randomImpl;
|
|
137830
|
+
onRetryEvent;
|
|
137742
137831
|
constructor(options) {
|
|
137743
137832
|
this.tokenProvider = options.tokenProvider;
|
|
137744
137833
|
this.bifrostBaseUrl = String(
|
|
@@ -137757,6 +137846,7 @@ var AccessTokenGatewayClient = class {
|
|
|
137757
137846
|
this.requestTimeoutMs = options.requestTimeoutMs ?? 3e4;
|
|
137758
137847
|
this.retryMaxDelayMs = options.retryMaxDelayMs ?? 5e3;
|
|
137759
137848
|
this.randomImpl = options.randomImpl ?? Math.random;
|
|
137849
|
+
this.onRetryEvent = options.onRetryEvent;
|
|
137760
137850
|
}
|
|
137761
137851
|
configureTeamContext(teamId, orgMode) {
|
|
137762
137852
|
this.teamId = String(teamId || "").trim();
|
|
@@ -137825,8 +137915,9 @@ var AccessTokenGatewayClient = class {
|
|
|
137825
137915
|
if (!this.fallbackBaseUrl) return false;
|
|
137826
137916
|
return retryTransient || request.fallback === "auto";
|
|
137827
137917
|
}
|
|
137828
|
-
async attemptFallback(request, retryTransient) {
|
|
137918
|
+
async attemptFallback(request, retryTransient, status) {
|
|
137829
137919
|
if (!this.fallbackEligible(request, retryTransient)) return null;
|
|
137920
|
+
this.emitRetryEvent("fallback", status, 1, 0);
|
|
137830
137921
|
const response = await this.tryFallback(request);
|
|
137831
137922
|
if (!response) return null;
|
|
137832
137923
|
if (response.ok) return response;
|
|
@@ -137852,6 +137943,7 @@ var AccessTokenGatewayClient = class {
|
|
|
137852
137943
|
} catch (error2) {
|
|
137853
137944
|
if (retryTransient && attempt < this.maxRetries) {
|
|
137854
137945
|
const delay = this.retryDelayMs(attempt);
|
|
137946
|
+
this.emitRetryEvent("transport", void 0, attempt + 1, delay);
|
|
137855
137947
|
attempt += 1;
|
|
137856
137948
|
await this.sleepImpl(delay);
|
|
137857
137949
|
continue;
|
|
@@ -137865,7 +137957,9 @@ var AccessTokenGatewayClient = class {
|
|
|
137865
137957
|
const inner = this.innerStatus(okBody);
|
|
137866
137958
|
if (inner !== void 0) {
|
|
137867
137959
|
if (retryTransient && this.isTransient(inner, okBody) && attempt < this.maxRetries) {
|
|
137868
|
-
|
|
137960
|
+
const delay = this.retryDelayMs(attempt);
|
|
137961
|
+
this.emitRetryEvent("inner", inner, attempt + 1, delay);
|
|
137962
|
+
await this.sleepImpl(delay);
|
|
137869
137963
|
attempt += 1;
|
|
137870
137964
|
continue;
|
|
137871
137965
|
}
|
|
@@ -137875,6 +137969,7 @@ var AccessTokenGatewayClient = class {
|
|
|
137875
137969
|
}
|
|
137876
137970
|
const body = await response.text().catch(() => "");
|
|
137877
137971
|
if (isExpiredAuthError(response.status, body) && this.tokenProvider.canRefresh()) {
|
|
137972
|
+
this.emitRetryEvent("auth", response.status, 1, 0);
|
|
137878
137973
|
await this.tokenProvider.refresh();
|
|
137879
137974
|
response = await this.send(request);
|
|
137880
137975
|
if (response.ok) {
|
|
@@ -137885,11 +137980,12 @@ var AccessTokenGatewayClient = class {
|
|
|
137885
137980
|
}
|
|
137886
137981
|
if (retryTransient && this.isTransient(response.status, body) && attempt < this.maxRetries) {
|
|
137887
137982
|
const delay = this.retryDelayMs(attempt, parseRetryAfterMs2(response.headers.get("retry-after")));
|
|
137983
|
+
this.emitRetryEvent("http", response.status, attempt + 1, delay);
|
|
137888
137984
|
attempt += 1;
|
|
137889
137985
|
await this.sleepImpl(delay);
|
|
137890
137986
|
continue;
|
|
137891
137987
|
}
|
|
137892
|
-
const fallbackResponse = await this.attemptFallback(request, retryTransient);
|
|
137988
|
+
const fallbackResponse = await this.attemptFallback(request, retryTransient, response.status);
|
|
137893
137989
|
if (fallbackResponse) return fallbackResponse;
|
|
137894
137990
|
throw this.toHttpError(request, response, body);
|
|
137895
137991
|
}
|
|
@@ -137897,6 +137993,14 @@ var AccessTokenGatewayClient = class {
|
|
|
137897
137993
|
retryDelayMs(attempt, retryAfter) {
|
|
137898
137994
|
return retryAfter === void 0 ? fullJitterDelayMs(attempt, this.retryBaseDelayMs, this.retryMaxDelayMs, this.randomImpl) : Math.min(this.retryMaxDelayMs, retryAfter);
|
|
137899
137995
|
}
|
|
137996
|
+
emitRetryEvent(retryClass, status, attempt, delay) {
|
|
137997
|
+
this.onRetryEvent?.({
|
|
137998
|
+
class: retryClass,
|
|
137999
|
+
...status === void 0 ? {} : { status },
|
|
138000
|
+
attempt: Math.max(1, attempt),
|
|
138001
|
+
delay: Math.max(0, delay)
|
|
138002
|
+
});
|
|
138003
|
+
}
|
|
137900
138004
|
isTransient(status, body) {
|
|
137901
138005
|
return status === 408 || status === 429 || status >= 500 || /ESOCKETTIMEDOUT|ETIMEDOUT|ECONNRESET|serverError|downstream/.test(body);
|
|
137902
138006
|
}
|
|
@@ -138026,7 +138130,7 @@ function validateCertMaterial(certBase64, keyBase64, passphrase) {
|
|
|
138026
138130
|
}
|
|
138027
138131
|
|
|
138028
138132
|
// src/lib/repo/branch-decision.ts
|
|
138029
|
-
var
|
|
138133
|
+
var import_node_fs4 = require("node:fs");
|
|
138030
138134
|
var import_node_crypto3 = require("node:crypto");
|
|
138031
138135
|
var ContractError = class extends Error {
|
|
138032
138136
|
code;
|
|
@@ -138067,7 +138171,7 @@ function readGithubEvent(env) {
|
|
|
138067
138171
|
const path9 = clean(env.GITHUB_EVENT_PATH);
|
|
138068
138172
|
if (!path9) return void 0;
|
|
138069
138173
|
try {
|
|
138070
|
-
return JSON.parse((0,
|
|
138174
|
+
return JSON.parse((0, import_node_fs4.readFileSync)(path9, "utf8"));
|
|
138071
138175
|
} catch {
|
|
138072
138176
|
return void 0;
|
|
138073
138177
|
}
|
|
@@ -138523,6 +138627,7 @@ function resolveInputs(env = process.env) {
|
|
|
138523
138627
|
baselineCollectionId: getInput2("baseline-collection-id", env),
|
|
138524
138628
|
smokeCollectionId: getInput2("smoke-collection-id", env),
|
|
138525
138629
|
contractCollectionId: getInput2("contract-collection-id", env),
|
|
138630
|
+
prebuiltCollectionsJson: getInput2("prebuilt-collections-json", env),
|
|
138526
138631
|
specId: getInput2("spec-id", env),
|
|
138527
138632
|
specContentChanged: parseBooleanInput(getInput2("spec-content-changed", env), true),
|
|
138528
138633
|
specPath: getInput2("spec-path", env),
|
|
@@ -138638,7 +138743,7 @@ var StateUnreadableError = class extends Error {
|
|
|
138638
138743
|
function readResourcesState() {
|
|
138639
138744
|
let raw;
|
|
138640
138745
|
try {
|
|
138641
|
-
raw = (0,
|
|
138746
|
+
raw = (0, import_node_fs5.readFileSync)(".postman/resources.yaml", "utf8");
|
|
138642
138747
|
} catch {
|
|
138643
138748
|
return null;
|
|
138644
138749
|
}
|
|
@@ -138697,12 +138802,15 @@ function getEnvironmentUidsFromResources(resourcesState) {
|
|
|
138697
138802
|
function normalizeToPosix(filePath) {
|
|
138698
138803
|
return filePath.split(path8.sep).join("/").replace(/\\/g, "/");
|
|
138699
138804
|
}
|
|
138805
|
+
function canonicalizeRelativePath(value) {
|
|
138806
|
+
return normalizeToPosix(String(value ?? "").trim()).replace(/^\.\/+/, "").replace(/\/{2,}/g, "/").replace(/\/+$/g, "");
|
|
138807
|
+
}
|
|
138700
138808
|
function isOpenApiSpecFile(filePath) {
|
|
138701
138809
|
if (!(filePath.endsWith(".json") || filePath.endsWith(".yaml") || filePath.endsWith(".yml"))) {
|
|
138702
138810
|
return false;
|
|
138703
138811
|
}
|
|
138704
138812
|
try {
|
|
138705
|
-
const raw = (0,
|
|
138813
|
+
const raw = (0, import_node_fs5.readFileSync)(filePath, "utf8");
|
|
138706
138814
|
const parsed = filePath.endsWith(".json") ? JSON.parse(raw) : load(raw);
|
|
138707
138815
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
138708
138816
|
return false;
|
|
@@ -138731,7 +138839,7 @@ function scanLocalSpecReferences(baseDir = ".") {
|
|
|
138731
138839
|
const found = /* @__PURE__ */ new Set();
|
|
138732
138840
|
const refs = [];
|
|
138733
138841
|
const visit2 = (currentDir) => {
|
|
138734
|
-
for (const entry of (0,
|
|
138842
|
+
for (const entry of (0, import_node_fs5.readdirSync)(currentDir, { withFileTypes: true })) {
|
|
138735
138843
|
if (ignoredDirs.has(entry.name)) {
|
|
138736
138844
|
continue;
|
|
138737
138845
|
}
|
|
@@ -138761,7 +138869,7 @@ function resolveMappedSpecReference(explicitSpecPath, discoveredSpecs) {
|
|
|
138761
138869
|
const normalizedExplicitPath = normalizeToPosix(explicitSpecPath.trim());
|
|
138762
138870
|
if (normalizedExplicitPath) {
|
|
138763
138871
|
const explicitFullPath = path8.resolve(normalizedExplicitPath);
|
|
138764
|
-
if ((0,
|
|
138872
|
+
if ((0, import_node_fs5.existsSync)(explicitFullPath) && (0, import_node_fs5.statSync)(explicitFullPath).isFile()) {
|
|
138765
138873
|
return {
|
|
138766
138874
|
repoRelativePath: normalizedExplicitPath,
|
|
138767
138875
|
configRelativePath: normalizeToPosix(path8.join("..", normalizedExplicitPath))
|
|
@@ -138813,6 +138921,7 @@ function readActionInputs(actionCore) {
|
|
|
138813
138921
|
INPUT_BASELINE_COLLECTION_ID: readInput(actionCore, "baseline-collection-id"),
|
|
138814
138922
|
INPUT_SMOKE_COLLECTION_ID: readInput(actionCore, "smoke-collection-id"),
|
|
138815
138923
|
INPUT_CONTRACT_COLLECTION_ID: readInput(actionCore, "contract-collection-id"),
|
|
138924
|
+
INPUT_PREBUILT_COLLECTIONS_JSON: readInput(actionCore, "prebuilt-collections-json"),
|
|
138816
138925
|
INPUT_SPEC_ID: readInput(actionCore, "spec-id"),
|
|
138817
138926
|
INPUT_SPEC_PATH: readInput(actionCore, "spec-path"),
|
|
138818
138927
|
INPUT_COLLECTION_SYNC_MODE: readInput(actionCore, "collection-sync-mode") || "refresh",
|
|
@@ -139026,6 +139135,7 @@ async function upsertEnvironments(inputs, dependencies, resourcesState, assetMar
|
|
|
139026
139135
|
);
|
|
139027
139136
|
}
|
|
139028
139137
|
envUids[envName] = existingUid;
|
|
139138
|
+
dependencies.core.setOutput("environment-uids-json", JSON.stringify(envUids));
|
|
139029
139139
|
continue;
|
|
139030
139140
|
}
|
|
139031
139141
|
const values = buildEnvironmentValues(envName, runtimeUrl);
|
|
@@ -139036,6 +139146,7 @@ async function upsertEnvironments(inputs, dependencies, resourcesState, assetMar
|
|
|
139036
139146
|
displayName,
|
|
139037
139147
|
values
|
|
139038
139148
|
);
|
|
139149
|
+
dependencies.core.setOutput("environment-uids-json", JSON.stringify(envUids));
|
|
139039
139150
|
} catch (error2) {
|
|
139040
139151
|
throw new Error(
|
|
139041
139152
|
formatOrchestrationIssue({
|
|
@@ -139052,7 +139163,7 @@ async function upsertEnvironments(inputs, dependencies, resourcesState, assetMar
|
|
|
139052
139163
|
return envUids;
|
|
139053
139164
|
}
|
|
139054
139165
|
function ensureDir(path9) {
|
|
139055
|
-
(0,
|
|
139166
|
+
(0, import_node_fs5.mkdirSync)(path9, { recursive: true });
|
|
139056
139167
|
}
|
|
139057
139168
|
function getCollectionDirectoryName(kind, projectName) {
|
|
139058
139169
|
if (kind === "Baseline") {
|
|
@@ -139089,7 +139200,7 @@ function stripVolatileFields(obj) {
|
|
|
139089
139200
|
}
|
|
139090
139201
|
function writeJsonFile(path9, content, normalize4 = false) {
|
|
139091
139202
|
const data = normalize4 ? stripVolatileFields(content) : content;
|
|
139092
|
-
(0,
|
|
139203
|
+
(0, import_node_fs5.writeFileSync)(path9, JSON.stringify(data, null, 2));
|
|
139093
139204
|
}
|
|
139094
139205
|
function buildMappedSpecCloudKey(mappedSource, specSyncMode, releaseLabel) {
|
|
139095
139206
|
if (specSyncMode !== "version") {
|
|
@@ -139153,22 +139264,422 @@ function buildResourcesManifest(workspaceId, collectionMap, envMap, artifactDir,
|
|
|
139153
139264
|
sortKeys: false
|
|
139154
139265
|
});
|
|
139155
139266
|
}
|
|
139156
|
-
function
|
|
139157
|
-
return
|
|
139158
|
-
|
|
139159
|
-
|
|
139160
|
-
|
|
139161
|
-
|
|
139162
|
-
|
|
139163
|
-
|
|
139267
|
+
function isPlainObject2(value) {
|
|
139268
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
139269
|
+
}
|
|
139270
|
+
function buildSpecCollectionWorkflowManifest(specRef, collectionRefs, existingRaw) {
|
|
139271
|
+
const pairs = collectionRefs.map((collectionRef) => ({
|
|
139272
|
+
spec: specRef,
|
|
139273
|
+
collection: collectionRef
|
|
139274
|
+
}));
|
|
139275
|
+
let root = {};
|
|
139276
|
+
if (typeof existingRaw === "string" && existingRaw.trim()) {
|
|
139277
|
+
let parsed;
|
|
139278
|
+
try {
|
|
139279
|
+
parsed = load(existingRaw);
|
|
139280
|
+
} catch (error2) {
|
|
139281
|
+
throw new Error(
|
|
139282
|
+
`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.`,
|
|
139283
|
+
{ cause: error2 }
|
|
139284
|
+
);
|
|
139285
|
+
}
|
|
139286
|
+
if (parsed === null || parsed === void 0) {
|
|
139287
|
+
root = {};
|
|
139288
|
+
} else if (!isPlainObject2(parsed)) {
|
|
139289
|
+
throw new Error(
|
|
139290
|
+
"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."
|
|
139291
|
+
);
|
|
139292
|
+
} else {
|
|
139293
|
+
root = { ...parsed };
|
|
139294
|
+
}
|
|
139295
|
+
}
|
|
139296
|
+
const workflows = isPlainObject2(root.workflows) ? { ...root.workflows } : {};
|
|
139297
|
+
const desiredCollections = new Set(collectionRefs);
|
|
139298
|
+
const currentPairs = (Array.isArray(workflows.syncSpecToCollection) ? workflows.syncSpecToCollection : []).map((entry) => isPlainObject2(entry) ? { ...entry } : null).filter((entry) => Boolean(entry)).filter(
|
|
139299
|
+
(entry) => String(entry.spec ?? "") !== specRef || desiredCollections.has(String(entry.collection ?? ""))
|
|
139300
|
+
);
|
|
139301
|
+
for (const pair of pairs) {
|
|
139302
|
+
const index = currentPairs.findIndex(
|
|
139303
|
+
(entry) => String(entry.spec ?? "") === pair.spec && String(entry.collection ?? "") === pair.collection
|
|
139304
|
+
);
|
|
139305
|
+
if (index >= 0) {
|
|
139306
|
+
const previous = currentPairs[index];
|
|
139307
|
+
currentPairs[index] = { ...previous, spec: pair.spec, collection: pair.collection };
|
|
139308
|
+
} else {
|
|
139309
|
+
currentPairs.push({ spec: pair.spec, collection: pair.collection });
|
|
139310
|
+
}
|
|
139311
|
+
}
|
|
139312
|
+
workflows.syncSpecToCollection = currentPairs;
|
|
139313
|
+
root.workflows = workflows;
|
|
139314
|
+
return dump(root, {
|
|
139315
|
+
lineWidth: -1,
|
|
139316
|
+
noRefs: true,
|
|
139317
|
+
sortKeys: false
|
|
139318
|
+
});
|
|
139319
|
+
}
|
|
139320
|
+
var PREBUILT_COLLECTION_ROLES = /* @__PURE__ */ new Set([
|
|
139321
|
+
"baseline",
|
|
139322
|
+
"smoke",
|
|
139323
|
+
"contract"
|
|
139324
|
+
]);
|
|
139325
|
+
var SHA256_HEX = /^[a-f0-9]{64}$/;
|
|
139326
|
+
var PREBUILT_CLOUD_ID = /^[A-Za-z0-9][A-Za-z0-9._:-]*$/;
|
|
139327
|
+
function failPrebuiltCollections(detail) {
|
|
139328
|
+
throw new Error(`CONTRACT_PREBUILT_COLLECTIONS_INVALID: ${detail}`);
|
|
139329
|
+
}
|
|
139330
|
+
function parsePrebuiltCollectionsJson(raw) {
|
|
139331
|
+
const trimmed = String(raw ?? "").trim();
|
|
139332
|
+
if (!trimmed) {
|
|
139333
|
+
return [];
|
|
139334
|
+
}
|
|
139335
|
+
let parsed;
|
|
139336
|
+
try {
|
|
139337
|
+
parsed = JSON.parse(trimmed);
|
|
139338
|
+
} catch (error2) {
|
|
139339
|
+
throw new Error(
|
|
139340
|
+
`CONTRACT_PREBUILT_COLLECTIONS_INVALID: malformed JSON (${error2 instanceof Error ? error2.message : String(error2)})`,
|
|
139341
|
+
{ cause: error2 }
|
|
139342
|
+
);
|
|
139343
|
+
}
|
|
139344
|
+
let entriesRaw;
|
|
139345
|
+
if (Array.isArray(parsed)) {
|
|
139346
|
+
entriesRaw = parsed;
|
|
139347
|
+
} else if (isPlainObject2(parsed)) {
|
|
139348
|
+
if (parsed.schemaVersion !== 1) {
|
|
139349
|
+
failPrebuiltCollections("schemaVersion must be 1");
|
|
139350
|
+
}
|
|
139351
|
+
if (!Array.isArray(parsed.collections)) {
|
|
139352
|
+
failPrebuiltCollections("collections must be an array when schemaVersion is set");
|
|
139353
|
+
}
|
|
139354
|
+
entriesRaw = parsed.collections;
|
|
139355
|
+
} else {
|
|
139356
|
+
failPrebuiltCollections("expected a JSON array or {schemaVersion:1,collections:[]}");
|
|
139357
|
+
}
|
|
139358
|
+
const seenRoles = /* @__PURE__ */ new Set();
|
|
139359
|
+
const entries = [];
|
|
139360
|
+
for (const [index, value] of entriesRaw.entries()) {
|
|
139361
|
+
if (!isPlainObject2(value)) {
|
|
139362
|
+
failPrebuiltCollections(`collections[${index}] must be an object`);
|
|
139363
|
+
}
|
|
139364
|
+
const roleRaw = String(value.role ?? "").trim();
|
|
139365
|
+
if (!PREBUILT_COLLECTION_ROLES.has(roleRaw)) {
|
|
139366
|
+
failPrebuiltCollections(
|
|
139367
|
+
`collections[${index}].role must be one of baseline|smoke|contract`
|
|
139368
|
+
);
|
|
139369
|
+
}
|
|
139370
|
+
const role = roleRaw;
|
|
139371
|
+
if (seenRoles.has(role)) {
|
|
139372
|
+
failPrebuiltCollections(`duplicate role ${role}`);
|
|
139373
|
+
}
|
|
139374
|
+
seenRoles.add(role);
|
|
139375
|
+
const collectionPath = String(
|
|
139376
|
+
value.collectionPath ?? value.path ?? ""
|
|
139377
|
+
).trim();
|
|
139378
|
+
if (!collectionPath || hasControlCharacter2(collectionPath)) {
|
|
139379
|
+
failPrebuiltCollections(
|
|
139380
|
+
`collections[${index}].collectionPath must be a non-empty confined relative path`
|
|
139381
|
+
);
|
|
139382
|
+
}
|
|
139383
|
+
const cloudId = String(value.cloudId ?? "").trim();
|
|
139384
|
+
if (!cloudId || !PREBUILT_CLOUD_ID.test(cloudId)) {
|
|
139385
|
+
failPrebuiltCollections(
|
|
139386
|
+
`collections[${index}].cloudId must be a non-empty Postman collection id`
|
|
139387
|
+
);
|
|
139388
|
+
}
|
|
139389
|
+
let payloadDigest;
|
|
139390
|
+
if (Object.prototype.hasOwnProperty.call(value, "payloadDigest")) {
|
|
139391
|
+
const payloadDigestRaw = value.payloadDigest;
|
|
139392
|
+
if (payloadDigestRaw !== void 0 && payloadDigestRaw !== null) {
|
|
139393
|
+
payloadDigest = String(payloadDigestRaw).trim();
|
|
139394
|
+
if (!SHA256_HEX.test(payloadDigest)) {
|
|
139395
|
+
failPrebuiltCollections(
|
|
139396
|
+
`collections[${index}].payloadDigest must be lowercase 64-hex`
|
|
139397
|
+
);
|
|
139398
|
+
}
|
|
139164
139399
|
}
|
|
139165
|
-
},
|
|
139166
|
-
{
|
|
139167
|
-
lineWidth: -1,
|
|
139168
|
-
noRefs: true,
|
|
139169
|
-
sortKeys: false
|
|
139170
139400
|
}
|
|
139401
|
+
const artifactDigest = String(value.artifactDigest ?? "").trim();
|
|
139402
|
+
if (!SHA256_HEX.test(artifactDigest)) {
|
|
139403
|
+
failPrebuiltCollections(
|
|
139404
|
+
`collections[${index}].artifactDigest must be lowercase 64-hex`
|
|
139405
|
+
);
|
|
139406
|
+
}
|
|
139407
|
+
entries.push({
|
|
139408
|
+
role,
|
|
139409
|
+
collectionPath,
|
|
139410
|
+
cloudId,
|
|
139411
|
+
...payloadDigest !== void 0 ? { payloadDigest } : {},
|
|
139412
|
+
artifactDigest
|
|
139413
|
+
});
|
|
139414
|
+
}
|
|
139415
|
+
return entries;
|
|
139416
|
+
}
|
|
139417
|
+
function assertPathWithinArtifactRoot(targetPath, artifactDir, fieldName) {
|
|
139418
|
+
assertPathWithinCwd(targetPath, fieldName);
|
|
139419
|
+
assertPathWithinCwd(artifactDir, "artifact-dir");
|
|
139420
|
+
const cwd = (0, import_node_fs5.realpathSync)(process.cwd());
|
|
139421
|
+
const artifactRoot = path8.resolve(cwd, artifactDir.trim());
|
|
139422
|
+
const resolved = path8.resolve(cwd, targetPath.trim());
|
|
139423
|
+
const relativeToArtifact = path8.relative(artifactRoot, resolved);
|
|
139424
|
+
if (!relativeToArtifact || relativeToArtifact.startsWith("..") || path8.isAbsolute(relativeToArtifact)) {
|
|
139425
|
+
failPrebuiltCollections(
|
|
139426
|
+
`${fieldName} must stay under artifact-dir (${artifactDir}); received ${targetPath}`
|
|
139427
|
+
);
|
|
139428
|
+
}
|
|
139429
|
+
let existingPath = resolved;
|
|
139430
|
+
while (!(0, import_node_fs5.existsSync)(existingPath)) {
|
|
139431
|
+
const parent = path8.dirname(existingPath);
|
|
139432
|
+
if (parent === existingPath) {
|
|
139433
|
+
break;
|
|
139434
|
+
}
|
|
139435
|
+
existingPath = parent;
|
|
139436
|
+
}
|
|
139437
|
+
const realExisting = (0, import_node_fs5.realpathSync)(existingPath);
|
|
139438
|
+
const realRelative = path8.relative(artifactRoot, realExisting);
|
|
139439
|
+
if (realRelative.startsWith("..") || path8.isAbsolute(realRelative)) {
|
|
139440
|
+
failPrebuiltCollections(
|
|
139441
|
+
`${fieldName} resolves outside artifact-dir via symlink; received ${targetPath}`
|
|
139442
|
+
);
|
|
139443
|
+
}
|
|
139444
|
+
return normalizeToPosix(path8.relative(cwd, resolved));
|
|
139445
|
+
}
|
|
139446
|
+
function prebuiltDirectoryTraversalIdentity(absolutePath, stats, options = {}) {
|
|
139447
|
+
const platform2 = options.platform ?? process.platform;
|
|
139448
|
+
const inodeIsZero = stats.ino === 0 || stats.ino === 0n;
|
|
139449
|
+
if (platform2 !== "win32" && !inodeIsZero) {
|
|
139450
|
+
return `${stats.dev}:${stats.ino}`;
|
|
139451
|
+
}
|
|
139452
|
+
const resolveCanonicalPath = options.resolveCanonicalPath ?? ((candidate) => import_node_fs5.realpathSync.native(candidate));
|
|
139453
|
+
const canonical = resolveCanonicalPath(absolutePath);
|
|
139454
|
+
return platform2 === "win32" ? canonical.toLowerCase() : canonical;
|
|
139455
|
+
}
|
|
139456
|
+
function listPrebuiltCollectionTreeFiles(collectionPath, artifactDir) {
|
|
139457
|
+
const confined = assertPathWithinArtifactRoot(
|
|
139458
|
+
collectionPath,
|
|
139459
|
+
artifactDir,
|
|
139460
|
+
"prebuilt collection path"
|
|
139461
|
+
);
|
|
139462
|
+
const absRoot = path8.resolve(process.cwd(), confined);
|
|
139463
|
+
if (!(0, import_node_fs5.existsSync)(absRoot)) {
|
|
139464
|
+
return [];
|
|
139465
|
+
}
|
|
139466
|
+
let rootStat;
|
|
139467
|
+
try {
|
|
139468
|
+
rootStat = (0, import_node_fs5.lstatSync)(absRoot);
|
|
139469
|
+
} catch {
|
|
139470
|
+
return [];
|
|
139471
|
+
}
|
|
139472
|
+
if (rootStat.isSymbolicLink()) {
|
|
139473
|
+
failPrebuiltCollections(
|
|
139474
|
+
`prebuilt collection path must not be a symlink; received ${collectionPath}`
|
|
139475
|
+
);
|
|
139476
|
+
}
|
|
139477
|
+
if (!rootStat.isDirectory()) {
|
|
139478
|
+
return [];
|
|
139479
|
+
}
|
|
139480
|
+
const files = [];
|
|
139481
|
+
const pendingDirectories = [absRoot];
|
|
139482
|
+
const seenDirectories = /* @__PURE__ */ new Set();
|
|
139483
|
+
while (pendingDirectories.length > 0) {
|
|
139484
|
+
const currentAbsolute = pendingDirectories.pop();
|
|
139485
|
+
if (!currentAbsolute) {
|
|
139486
|
+
break;
|
|
139487
|
+
}
|
|
139488
|
+
const currentStat = (0, import_node_fs5.lstatSync)(currentAbsolute);
|
|
139489
|
+
if (currentStat.isSymbolicLink() || !currentStat.isDirectory()) {
|
|
139490
|
+
failPrebuiltCollections(
|
|
139491
|
+
`prebuilt collection tree directory changed or became unsupported at ${normalizeToPosix(path8.relative(absRoot, currentAbsolute)) || "."}`
|
|
139492
|
+
);
|
|
139493
|
+
}
|
|
139494
|
+
const currentKey = prebuiltDirectoryTraversalIdentity(currentAbsolute, currentStat);
|
|
139495
|
+
if (seenDirectories.has(currentKey)) {
|
|
139496
|
+
failPrebuiltCollections(
|
|
139497
|
+
`prebuilt collection tree directory cycle detected at ${normalizeToPosix(path8.relative(absRoot, currentAbsolute)) || "."}`
|
|
139498
|
+
);
|
|
139499
|
+
}
|
|
139500
|
+
seenDirectories.add(currentKey);
|
|
139501
|
+
const entries = (0, import_node_fs5.readdirSync)(currentAbsolute, { withFileTypes: true });
|
|
139502
|
+
for (const entry of entries) {
|
|
139503
|
+
const abs = path8.join(currentAbsolute, entry.name);
|
|
139504
|
+
if (entry.isSymbolicLink()) {
|
|
139505
|
+
failPrebuiltCollections(
|
|
139506
|
+
`prebuilt collection tree must not contain symlinks; received ${normalizeToPosix(path8.relative(absRoot, abs))}`
|
|
139507
|
+
);
|
|
139508
|
+
}
|
|
139509
|
+
if (entry.isDirectory()) {
|
|
139510
|
+
pendingDirectories.push(abs);
|
|
139511
|
+
continue;
|
|
139512
|
+
}
|
|
139513
|
+
if (!entry.isFile()) {
|
|
139514
|
+
failPrebuiltCollections(
|
|
139515
|
+
`prebuilt collection tree contains unsupported entry type at ${normalizeToPosix(path8.relative(absRoot, abs))}`
|
|
139516
|
+
);
|
|
139517
|
+
}
|
|
139518
|
+
const fileLstat = (0, import_node_fs5.lstatSync)(abs);
|
|
139519
|
+
if (fileLstat.isSymbolicLink() || !fileLstat.isFile()) {
|
|
139520
|
+
failPrebuiltCollections(
|
|
139521
|
+
`prebuilt collection tree file changed or became unsupported at ${normalizeToPosix(path8.relative(absRoot, abs))}`
|
|
139522
|
+
);
|
|
139523
|
+
}
|
|
139524
|
+
files.push({
|
|
139525
|
+
absolute: abs,
|
|
139526
|
+
relative: normalizeToPosix(path8.relative(absRoot, abs)),
|
|
139527
|
+
dev: fileLstat.dev,
|
|
139528
|
+
ino: fileLstat.ino,
|
|
139529
|
+
size: fileLstat.size
|
|
139530
|
+
});
|
|
139531
|
+
}
|
|
139532
|
+
}
|
|
139533
|
+
files.sort((a, b) => a.relative.localeCompare(b.relative));
|
|
139534
|
+
return files;
|
|
139535
|
+
}
|
|
139536
|
+
function validateCanonicalV3CollectionFile(relative4, bytes) {
|
|
139537
|
+
let expectedKind;
|
|
139538
|
+
if (/(^|\/)\.resources\/definition\.yaml$/.test(relative4)) {
|
|
139539
|
+
expectedKind = "collection";
|
|
139540
|
+
} else if (relative4.endsWith(".request.yaml")) {
|
|
139541
|
+
expectedKind = "request";
|
|
139542
|
+
} else if (relative4.endsWith(".example.yaml")) {
|
|
139543
|
+
expectedKind = "example";
|
|
139544
|
+
} else if (relative4.endsWith(".message.yaml")) {
|
|
139545
|
+
expectedKind = "message";
|
|
139546
|
+
} else {
|
|
139547
|
+
failPrebuiltCollections(`prebuilt collection tree contains unexpected file ${relative4}`);
|
|
139548
|
+
}
|
|
139549
|
+
let parsed;
|
|
139550
|
+
try {
|
|
139551
|
+
parsed = load(bytes.toString("utf8"));
|
|
139552
|
+
} catch (error2) {
|
|
139553
|
+
failPrebuiltCollections(
|
|
139554
|
+
`prebuilt collection tree contains malformed YAML at ${relative4} (${error2 instanceof Error ? error2.message : String(error2)})`
|
|
139555
|
+
);
|
|
139556
|
+
}
|
|
139557
|
+
if (!isPlainObject2(parsed)) {
|
|
139558
|
+
failPrebuiltCollections(`prebuilt collection tree file ${relative4} must contain a YAML mapping`);
|
|
139559
|
+
}
|
|
139560
|
+
const kind = typeof parsed.$kind === "string" ? parsed.$kind.trim() : "";
|
|
139561
|
+
if (!kind) {
|
|
139562
|
+
failPrebuiltCollections(`prebuilt collection tree file ${relative4} must contain a nonempty $kind`);
|
|
139563
|
+
}
|
|
139564
|
+
const agrees = expectedKind === "collection" ? kind === "collection" : kind.endsWith(`-${expectedKind}`);
|
|
139565
|
+
if (!agrees) {
|
|
139566
|
+
failPrebuiltCollections(
|
|
139567
|
+
`prebuilt collection tree file ${relative4} has $kind ${kind} inconsistent with its filename`
|
|
139568
|
+
);
|
|
139569
|
+
}
|
|
139570
|
+
}
|
|
139571
|
+
async function digestAndValidatePrebuiltCollectionTree(files) {
|
|
139572
|
+
if (!files.some((file) => file.relative === ".resources/definition.yaml")) {
|
|
139573
|
+
failPrebuiltCollections("prebuilt collection tree is missing .resources/definition.yaml");
|
|
139574
|
+
}
|
|
139575
|
+
const hash = (0, import_node_crypto4.createHash)("sha256");
|
|
139576
|
+
for (const file of files) {
|
|
139577
|
+
let bytes;
|
|
139578
|
+
try {
|
|
139579
|
+
bytes = await appendArtifactDigestFileStreaming(hash, file.relative, file.absolute, {
|
|
139580
|
+
dev: file.dev,
|
|
139581
|
+
ino: file.ino,
|
|
139582
|
+
size: file.size
|
|
139583
|
+
});
|
|
139584
|
+
} catch (error2) {
|
|
139585
|
+
if (error2 instanceof ArtifactDigestStreamError) {
|
|
139586
|
+
failPrebuiltCollections(error2.message);
|
|
139587
|
+
}
|
|
139588
|
+
const code = error2?.code;
|
|
139589
|
+
if (code === "ELOOP" || code === "EPERM") {
|
|
139590
|
+
failPrebuiltCollections(
|
|
139591
|
+
`prebuilt collection tree file became a symlink or unsupported node at ${file.relative}`
|
|
139592
|
+
);
|
|
139593
|
+
}
|
|
139594
|
+
failPrebuiltCollections(
|
|
139595
|
+
`prebuilt collection tree file changed or became unsupported at ${file.relative}`
|
|
139596
|
+
);
|
|
139597
|
+
}
|
|
139598
|
+
validateCanonicalV3CollectionFile(file.relative, bytes);
|
|
139599
|
+
}
|
|
139600
|
+
return hash.digest("hex");
|
|
139601
|
+
}
|
|
139602
|
+
async function preparePrebuiltCollections(inputs) {
|
|
139603
|
+
const prepared = /* @__PURE__ */ new Map();
|
|
139604
|
+
for (const entry of parsePrebuiltCollectionsJson(inputs.prebuiltCollectionsJson ?? "")) {
|
|
139605
|
+
const confinedPath = assertPathWithinArtifactRoot(
|
|
139606
|
+
entry.collectionPath,
|
|
139607
|
+
inputs.artifactDir,
|
|
139608
|
+
`prebuilt ${entry.role} collection path`
|
|
139609
|
+
);
|
|
139610
|
+
const absolute = path8.resolve(process.cwd(), confinedPath);
|
|
139611
|
+
if (!(0, import_node_fs5.existsSync)(absolute)) {
|
|
139612
|
+
prepared.set(entry.role, { entry, confinedPath });
|
|
139613
|
+
continue;
|
|
139614
|
+
}
|
|
139615
|
+
const files = listPrebuiltCollectionTreeFiles(confinedPath, inputs.artifactDir);
|
|
139616
|
+
const artifactDigest = await digestAndValidatePrebuiltCollectionTree(files);
|
|
139617
|
+
prepared.set(entry.role, {
|
|
139618
|
+
entry,
|
|
139619
|
+
confinedPath,
|
|
139620
|
+
artifactDigest
|
|
139621
|
+
});
|
|
139622
|
+
}
|
|
139623
|
+
return prepared;
|
|
139624
|
+
}
|
|
139625
|
+
function tryReusePrebuiltCollection(options) {
|
|
139626
|
+
const { prepared, expectedPath, expectedCloudId } = options;
|
|
139627
|
+
const { entry } = prepared;
|
|
139628
|
+
if (!expectedCloudId || entry.cloudId !== expectedCloudId) {
|
|
139629
|
+
return false;
|
|
139630
|
+
}
|
|
139631
|
+
const expectedNormalized = canonicalizeRelativePath(expectedPath);
|
|
139632
|
+
const entryNormalized = canonicalizeRelativePath(entry.collectionPath);
|
|
139633
|
+
if (entryNormalized !== expectedNormalized) {
|
|
139634
|
+
return false;
|
|
139635
|
+
}
|
|
139636
|
+
const confined = canonicalizeRelativePath(prepared.confinedPath);
|
|
139637
|
+
if (confined !== expectedNormalized) {
|
|
139638
|
+
return false;
|
|
139639
|
+
}
|
|
139640
|
+
const expectedName = path8.posix.basename(expectedNormalized);
|
|
139641
|
+
if (path8.posix.basename(confined) !== expectedName) {
|
|
139642
|
+
return false;
|
|
139643
|
+
}
|
|
139644
|
+
return prepared.artifactDigest === entry.artifactDigest;
|
|
139645
|
+
}
|
|
139646
|
+
async function exportCollectionArtifact(options) {
|
|
139647
|
+
const {
|
|
139648
|
+
role,
|
|
139649
|
+
collectionId,
|
|
139650
|
+
dirName,
|
|
139651
|
+
collectionsDir,
|
|
139652
|
+
prebuiltByRole,
|
|
139653
|
+
postman,
|
|
139654
|
+
core
|
|
139655
|
+
} = options;
|
|
139656
|
+
if (!collectionId) {
|
|
139657
|
+
return void 0;
|
|
139658
|
+
}
|
|
139659
|
+
const expectedPath = `${collectionsDir}/${dirName}`;
|
|
139660
|
+
const entry = prebuiltByRole.get(role);
|
|
139661
|
+
if (entry) {
|
|
139662
|
+
const reused = tryReusePrebuiltCollection({
|
|
139663
|
+
prepared: entry,
|
|
139664
|
+
expectedPath,
|
|
139665
|
+
expectedCloudId: collectionId
|
|
139666
|
+
});
|
|
139667
|
+
if (reused) {
|
|
139668
|
+
core.info(
|
|
139669
|
+
`Reusing prebuilt ${role} collection tree at ${expectedPath} (artifactDigest match)`
|
|
139670
|
+
);
|
|
139671
|
+
return `../${expectedPath}`;
|
|
139672
|
+
}
|
|
139673
|
+
core.info(
|
|
139674
|
+
`Prebuilt ${role} collection entry present but did not exactly match; exporting from cloud`
|
|
139675
|
+
);
|
|
139676
|
+
}
|
|
139677
|
+
const col = await postman.getCollection(collectionId);
|
|
139678
|
+
await convertAndSplitAnyCollection(
|
|
139679
|
+
col,
|
|
139680
|
+
expectedPath
|
|
139171
139681
|
);
|
|
139682
|
+
return `../${expectedPath}`;
|
|
139172
139683
|
}
|
|
139173
139684
|
function hasControlCharacter2(value) {
|
|
139174
139685
|
for (let index = 0; index < value.length; index += 1) {
|
|
@@ -139186,21 +139697,21 @@ function assertPathWithinCwd(targetPath, fieldName) {
|
|
|
139186
139697
|
if (!rawPath || hasControlCharacter2(originalPath) || path8.isAbsolute(rawPath) || path8.win32.isAbsolute(rawPath) || segments.includes("..") || rawPath.startsWith(":") || hasControlCharacter2(rawPath)) {
|
|
139187
139698
|
throw new Error(`${fieldName} must stay within the repository root; received ${targetPath}`);
|
|
139188
139699
|
}
|
|
139189
|
-
const base = (0,
|
|
139700
|
+
const base = (0, import_node_fs5.realpathSync)(process.cwd());
|
|
139190
139701
|
const resolved = path8.resolve(base, rawPath);
|
|
139191
139702
|
const relative4 = path8.relative(base, resolved);
|
|
139192
139703
|
if (relative4.startsWith("..") || path8.isAbsolute(relative4)) {
|
|
139193
139704
|
throw new Error(`${fieldName} must stay within the repository root; received ${targetPath}`);
|
|
139194
139705
|
}
|
|
139195
139706
|
let existingPath = resolved;
|
|
139196
|
-
while (!(0,
|
|
139707
|
+
while (!(0, import_node_fs5.existsSync)(existingPath)) {
|
|
139197
139708
|
const parent = path8.dirname(existingPath);
|
|
139198
139709
|
if (parent === existingPath) {
|
|
139199
139710
|
break;
|
|
139200
139711
|
}
|
|
139201
139712
|
existingPath = parent;
|
|
139202
139713
|
}
|
|
139203
|
-
const realExistingPath = (0,
|
|
139714
|
+
const realExistingPath = (0, import_node_fs5.realpathSync)(existingPath);
|
|
139204
139715
|
const realRelative = path8.relative(base, realExistingPath);
|
|
139205
139716
|
if (realRelative.startsWith("..") || path8.isAbsolute(realRelative)) {
|
|
139206
139717
|
throw new Error(`${fieldName} must stay within the repository root; received ${targetPath}`);
|
|
@@ -139228,8 +139739,8 @@ async function exportArtifacts(inputs, dependencies, envUids, assetProjectName,
|
|
|
139228
139739
|
ensureDir(specsDir);
|
|
139229
139740
|
ensureDir(".postman");
|
|
139230
139741
|
const globalsFilePath = `${globalsDir}/workspace.globals.yaml`;
|
|
139231
|
-
if (!(0,
|
|
139232
|
-
(0,
|
|
139742
|
+
if (!(0, import_node_fs5.existsSync)(globalsFilePath)) {
|
|
139743
|
+
(0, import_node_fs5.writeFileSync)(globalsFilePath, "name: Globals\nvalues: []\n");
|
|
139233
139744
|
}
|
|
139234
139745
|
if (inputs.generateCiWorkflow) {
|
|
139235
139746
|
const ciDir = inputs.ciWorkflowPath.split("/").slice(0, -1).join("/");
|
|
@@ -139245,23 +139756,42 @@ async function exportArtifacts(inputs, dependencies, envUids, assetProjectName,
|
|
|
139245
139756
|
inputs.specSyncMode,
|
|
139246
139757
|
options.releaseLabel
|
|
139247
139758
|
) : void 0;
|
|
139248
|
-
|
|
139249
|
-
|
|
139250
|
-
|
|
139251
|
-
|
|
139252
|
-
|
|
139253
|
-
|
|
139254
|
-
|
|
139255
|
-
|
|
139256
|
-
|
|
139257
|
-
|
|
139258
|
-
|
|
139259
|
-
|
|
139260
|
-
|
|
139261
|
-
|
|
139262
|
-
|
|
139263
|
-
|
|
139264
|
-
|
|
139759
|
+
const prebuiltByRole = options.preparedPrebuiltCollections;
|
|
139760
|
+
const baselineRef = await exportCollectionArtifact({
|
|
139761
|
+
role: "baseline",
|
|
139762
|
+
collectionId: inputs.baselineCollectionId,
|
|
139763
|
+
dirName: getCollectionDirectoryName("Baseline", assetProjectName),
|
|
139764
|
+
collectionsDir,
|
|
139765
|
+
prebuiltByRole,
|
|
139766
|
+
postman: dependencies.postman,
|
|
139767
|
+
core: dependencies.core
|
|
139768
|
+
});
|
|
139769
|
+
if (baselineRef) {
|
|
139770
|
+
manifestCollections[baselineRef] = inputs.baselineCollectionId;
|
|
139771
|
+
}
|
|
139772
|
+
const smokeRef = await exportCollectionArtifact({
|
|
139773
|
+
role: "smoke",
|
|
139774
|
+
collectionId: inputs.smokeCollectionId,
|
|
139775
|
+
dirName: getCollectionDirectoryName("Smoke", assetProjectName),
|
|
139776
|
+
collectionsDir,
|
|
139777
|
+
prebuiltByRole,
|
|
139778
|
+
postman: dependencies.postman,
|
|
139779
|
+
core: dependencies.core
|
|
139780
|
+
});
|
|
139781
|
+
if (smokeRef) {
|
|
139782
|
+
manifestCollections[smokeRef] = inputs.smokeCollectionId;
|
|
139783
|
+
}
|
|
139784
|
+
const contractRef = await exportCollectionArtifact({
|
|
139785
|
+
role: "contract",
|
|
139786
|
+
collectionId: inputs.contractCollectionId,
|
|
139787
|
+
dirName: getCollectionDirectoryName("Contract", assetProjectName),
|
|
139788
|
+
collectionsDir,
|
|
139789
|
+
prebuiltByRole,
|
|
139790
|
+
postman: dependencies.postman,
|
|
139791
|
+
core: dependencies.core
|
|
139792
|
+
});
|
|
139793
|
+
if (contractRef) {
|
|
139794
|
+
manifestCollections[contractRef] = inputs.contractCollectionId;
|
|
139265
139795
|
}
|
|
139266
139796
|
for (const [envName, envUid] of Object.entries(envUids)) {
|
|
139267
139797
|
writeJsonFile(
|
|
@@ -139276,7 +139806,7 @@ async function exportArtifacts(inputs, dependencies, envUids, assetProjectName,
|
|
|
139276
139806
|
workspaceLinkEnabled: inputs.workspaceLinkEnabled,
|
|
139277
139807
|
workspaceLinkStatus: options.workspaceLinkStatus
|
|
139278
139808
|
});
|
|
139279
|
-
(0,
|
|
139809
|
+
(0, import_node_fs5.writeFileSync)(".postman/resources.yaml", buildResourcesManifest(
|
|
139280
139810
|
durableWorkspaceId,
|
|
139281
139811
|
manifestCollections,
|
|
139282
139812
|
envUids,
|
|
@@ -139288,11 +139818,18 @@ async function exportArtifacts(inputs, dependencies, envUids, assetProjectName,
|
|
|
139288
139818
|
options.priorState
|
|
139289
139819
|
));
|
|
139290
139820
|
if (mappedSpec && Object.keys(manifestCollections).length > 0) {
|
|
139291
|
-
|
|
139821
|
+
let existingWorkflows;
|
|
139822
|
+
try {
|
|
139823
|
+
existingWorkflows = (0, import_node_fs5.readFileSync)(".postman/workflows.yaml", "utf8");
|
|
139824
|
+
} catch {
|
|
139825
|
+
existingWorkflows = void 0;
|
|
139826
|
+
}
|
|
139827
|
+
(0, import_node_fs5.writeFileSync)(
|
|
139292
139828
|
".postman/workflows.yaml",
|
|
139293
139829
|
buildSpecCollectionWorkflowManifest(
|
|
139294
139830
|
mappedSpec.configRelativePath,
|
|
139295
|
-
Object.keys(manifestCollections)
|
|
139831
|
+
Object.keys(manifestCollections),
|
|
139832
|
+
existingWorkflows
|
|
139296
139833
|
)
|
|
139297
139834
|
);
|
|
139298
139835
|
}
|
|
@@ -139337,12 +139874,12 @@ async function commitAndPushGeneratedFiles(inputs, dependencies) {
|
|
|
139337
139874
|
const dir = parts.slice(0, -1).join("/");
|
|
139338
139875
|
ensureDir(dir);
|
|
139339
139876
|
}
|
|
139340
|
-
(0,
|
|
139877
|
+
(0, import_node_fs5.writeFileSync)(inputs.ciWorkflowPath, ciWorkflow);
|
|
139341
139878
|
if (inputs.provider === "github" || inputs.provider === "unknown") {
|
|
139342
139879
|
const gcPath = ".github/workflows/postman-preview-gc.yml";
|
|
139343
139880
|
if (inputs.ciWorkflowPath.endsWith(".github/workflows/ci.yml") || inputs.ciWorkflowPath === ".github/workflows/ci.yml") {
|
|
139344
139881
|
ensureDir(".github/workflows");
|
|
139345
|
-
(0,
|
|
139882
|
+
(0, import_node_fs5.writeFileSync)(gcPath, renderGcWorkflowTemplate());
|
|
139346
139883
|
}
|
|
139347
139884
|
}
|
|
139348
139885
|
}
|
|
@@ -139350,16 +139887,16 @@ async function commitAndPushGeneratedFiles(inputs, dependencies) {
|
|
|
139350
139887
|
return { commitSha: "", resolvedCurrentRef: "", pushed: false };
|
|
139351
139888
|
}
|
|
139352
139889
|
const provisionPath = ".github/workflows/provision.yml";
|
|
139353
|
-
const provisionExists = inputs.provider === "github" && (0,
|
|
139890
|
+
const provisionExists = inputs.provider === "github" && (0, import_node_fs5.existsSync)(provisionPath);
|
|
139354
139891
|
const gcWorkflowPath = ".github/workflows/postman-preview-gc.yml";
|
|
139355
|
-
const gcExists = inputs.generateCiWorkflow && (0,
|
|
139892
|
+
const gcExists = inputs.generateCiWorkflow && (0, import_node_fs5.existsSync)(gcWorkflowPath);
|
|
139356
139893
|
const stagePaths = [
|
|
139357
139894
|
inputs.artifactDir,
|
|
139358
139895
|
".postman",
|
|
139359
139896
|
inputs.generateCiWorkflow ? inputs.ciWorkflowPath : null,
|
|
139360
139897
|
gcExists ? gcWorkflowPath : null,
|
|
139361
139898
|
provisionExists ? provisionPath : null
|
|
139362
|
-
].filter((entry) => typeof entry === "string" && ((0,
|
|
139899
|
+
].filter((entry) => typeof entry === "string" && ((0, import_node_fs5.existsSync)(entry) || entry === provisionPath));
|
|
139363
139900
|
if (stagePaths.length === 0) {
|
|
139364
139901
|
dependencies.core.info("No generated repository paths were found; skipping repo mutation.");
|
|
139365
139902
|
return {
|
|
@@ -139467,6 +140004,7 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
139467
140004
|
}
|
|
139468
140005
|
}
|
|
139469
140006
|
}
|
|
140007
|
+
const preparedPrebuiltCollections = await preparePrebuiltCollections(inputs);
|
|
139470
140008
|
let skipRepositoryLinkPost = false;
|
|
139471
140009
|
let repositoryLinkPreflightWasFree = false;
|
|
139472
140010
|
if (inputs.workspaceLinkEnabled && inputs.workspaceId && inputs.repoUrl && dependencies.internalIntegration?.findWorkspaceForRepo) {
|
|
@@ -139503,6 +140041,7 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
139503
140041
|
const branchAssetMarker = buildBranchAssetMarker(branchDecision, inputs);
|
|
139504
140042
|
const envUids = await upsertEnvironments(inputs, dependencies, resourcesState, branchAssetMarker);
|
|
139505
140043
|
outputs["environment-uids-json"] = JSON.stringify(envUids);
|
|
140044
|
+
dependencies.core.setOutput("environment-uids-json", outputs["environment-uids-json"]);
|
|
139506
140045
|
if (inputs.environmentSyncEnabled && inputs.workspaceId && dependencies.internalIntegration) {
|
|
139507
140046
|
const associations = Object.entries(envUids).map(([envName, envUid]) => ({
|
|
139508
140047
|
envUid,
|
|
@@ -139621,6 +140160,7 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
139621
140160
|
}
|
|
139622
140161
|
}
|
|
139623
140162
|
outputs["mock-url"] = resolvedMockUrl;
|
|
140163
|
+
dependencies.core.setOutput("mock-url", resolvedMockUrl);
|
|
139624
140164
|
}
|
|
139625
140165
|
}
|
|
139626
140166
|
if (inputs.workspaceId && inputs.smokeCollectionId && Object.keys(envUids).length > 0) {
|
|
@@ -139696,6 +140236,7 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
139696
140236
|
}
|
|
139697
140237
|
}
|
|
139698
140238
|
outputs["monitor-id"] = resolvedMonitorId;
|
|
140239
|
+
dependencies.core.setOutput("monitor-id", resolvedMonitorId);
|
|
139699
140240
|
if (!effectiveCron && resolvedMonitorId) {
|
|
139700
140241
|
try {
|
|
139701
140242
|
await dependencies.postman.runMonitor(resolvedMonitorId);
|
|
@@ -139753,7 +140294,8 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
139753
140294
|
priorWorkspaceId: resourcesState?.workspace?.id,
|
|
139754
140295
|
existingSpecs: resourcesState?.cloudResources?.specs,
|
|
139755
140296
|
releaseLabel,
|
|
139756
|
-
priorState: resourcesState
|
|
140297
|
+
priorState: resourcesState,
|
|
140298
|
+
preparedPrebuiltCollections
|
|
139757
140299
|
});
|
|
139758
140300
|
const commit = await commitAndPushGeneratedFiles(inputs, dependencies);
|
|
139759
140301
|
outputs["commit-sha"] = commit.commitSha;
|
|
@@ -139979,7 +140521,12 @@ async function resolvePostmanApiKeyAndTeamId(inputs, actionCore, actionExec, mas
|
|
|
139979
140521
|
bifrostBaseUrl: inputs.postmanBifrostBase,
|
|
139980
140522
|
// No fallback on the org-mode probe: the expected non-org 400 must
|
|
139981
140523
|
// surface verbatim, not be re-fired against the /_api alias.
|
|
139982
|
-
secretMasker: masker
|
|
140524
|
+
secretMasker: masker,
|
|
140525
|
+
onRetryEvent: (event) => {
|
|
140526
|
+
actionCore.info(
|
|
140527
|
+
`[postman retry] action=repo-sync class=${event.class} status=${event.status ?? "none"} attempt=${event.attempt} delayMs=${event.delay}`
|
|
140528
|
+
);
|
|
140529
|
+
}
|
|
139983
140530
|
});
|
|
139984
140531
|
const squads = await gateway.getSquads(teamId);
|
|
139985
140532
|
if (squads.length > 0) {
|
|
@@ -140043,7 +140590,12 @@ function createRepoSyncDependencies(inputs, resolved, factories, options = {}) {
|
|
|
140043
140590
|
fallbackBaseUrl: inputs.postmanFallbackBase,
|
|
140044
140591
|
teamId: resolved.teamId,
|
|
140045
140592
|
orgMode: inputs.orgMode,
|
|
140046
|
-
secretMasker: masker
|
|
140593
|
+
secretMasker: masker,
|
|
140594
|
+
onRetryEvent: (event) => {
|
|
140595
|
+
factories.core.info(
|
|
140596
|
+
`[postman retry] action=repo-sync class=${event.class} status=${event.status ?? "none"} attempt=${event.attempt} delayMs=${event.delay}`
|
|
140597
|
+
);
|
|
140598
|
+
}
|
|
140047
140599
|
});
|
|
140048
140600
|
const gatewayAssets = new PostmanGatewayAssetsClient({
|
|
140049
140601
|
gateway,
|
|
@@ -140162,7 +140714,10 @@ async function runAction(actionCore = core_exports, actionExec = exec_exports) {
|
|
|
140162
140714
|
}
|
|
140163
140715
|
await mintAccessTokenIfNeeded(inputs, {
|
|
140164
140716
|
info: (message) => actionCore.info(message),
|
|
140165
|
-
warning: (message) => actionCore.warning(message)
|
|
140717
|
+
warning: (message) => actionCore.warning(message),
|
|
140718
|
+
retryEvent: (event) => actionCore.info(
|
|
140719
|
+
`[postman retry] action=repo-sync class=${event.class} status=${event.status ?? "none"} attempt=${event.attempt} delayMs=${event.delay}`
|
|
140720
|
+
)
|
|
140166
140721
|
}, (secret) => actionCore.setSecret(secret));
|
|
140167
140722
|
const masker = createSecretMasker([
|
|
140168
140723
|
inputs.postmanApiKey,
|
|
@@ -140183,7 +140738,12 @@ async function runAction(actionCore = core_exports, actionExec = exec_exports) {
|
|
|
140183
140738
|
explicitTeamId: inputs.teamId || void 0,
|
|
140184
140739
|
mode: inputs.credentialPreflight,
|
|
140185
140740
|
mask: masker,
|
|
140186
|
-
log:
|
|
140741
|
+
log: {
|
|
140742
|
+
...actionCore,
|
|
140743
|
+
retryEvent: (event) => actionCore.info(
|
|
140744
|
+
`[postman retry] action=repo-sync class=${event.class} status=${event.status ?? "none"} attempt=${event.attempt} delayMs=${event.delay}`
|
|
140745
|
+
)
|
|
140746
|
+
}
|
|
140187
140747
|
});
|
|
140188
140748
|
const resolved = await resolvePostmanApiKeyAndTeamId(inputs, actionCore, actionExec, masker, {
|
|
140189
140749
|
env: process.env
|
|
@@ -140224,6 +140784,7 @@ async function runAction(actionCore = core_exports, actionExec = exec_exports) {
|
|
|
140224
140784
|
decideBranchTier,
|
|
140225
140785
|
getInput,
|
|
140226
140786
|
hasInput,
|
|
140787
|
+
prebuiltDirectoryTraversalIdentity,
|
|
140227
140788
|
readActionInputs,
|
|
140228
140789
|
resolveInputs,
|
|
140229
140790
|
resolvePostmanApiKeyAndTeamId,
|