@postman-cse/onboarding-repo-sync 2.1.0 → 2.1.2

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/dist/index.cjs CHANGED
@@ -119790,6 +119790,7 @@ __export(index_exports, {
119790
119790
  assertPathWithinCwd: () => assertPathWithinCwd,
119791
119791
  createRepoSyncDependencies: () => createRepoSyncDependencies,
119792
119792
  getInput: () => getInput2,
119793
+ hasInput: () => hasInput,
119793
119794
  readActionInputs: () => readActionInputs,
119794
119795
  resolveInputs: () => resolveInputs,
119795
119796
  resolvePostmanApiKeyAndTeamId: () => resolvePostmanApiKeyAndTeamId,
@@ -122077,7 +122078,7 @@ function getIDToken(aud) {
122077
122078
  }
122078
122079
 
122079
122080
  // src/index.ts
122080
- var import_node_fs2 = require("node:fs");
122081
+ var import_node_fs3 = require("node:fs");
122081
122082
  var path8 = __toESM(require("node:path"), 1);
122082
122083
 
122083
122084
  // node_modules/js-yaml/dist/js-yaml.mjs
@@ -125380,6 +125381,7 @@ function getCiWorkflowTemplate(provider, options = {}) {
125380
125381
  }
125381
125382
 
125382
125383
  // src/lib/github/repo-mutation.ts
125384
+ var import_node_fs = require("node:fs");
125383
125385
  var import_node_path = __toESM(require("node:path"), 1);
125384
125386
 
125385
125387
  // src/lib/secrets.ts
@@ -125621,17 +125623,21 @@ function normalizeStagePaths(stagePaths) {
125621
125623
  if (hasControlCharacter(rawPath) || import_node_path.default.isAbsolute(stagePath) || import_node_path.default.win32.isAbsolute(stagePath) || segments.includes("..") || stagePath.startsWith(":") || hasControlCharacter(stagePath)) {
125622
125624
  throw new Error(`Unsafe git stage path: ${stagePath}`);
125623
125625
  }
125624
- normalized.push(stagePath);
125626
+ if (!normalized.includes(stagePath)) {
125627
+ normalized.push(stagePath);
125628
+ }
125625
125629
  }
125626
125630
  return normalized;
125627
125631
  }
125628
125632
  var RepoMutationService = class {
125633
+ cwd;
125629
125634
  execute;
125630
125635
  provider;
125631
125636
  repository;
125632
125637
  repoUrl;
125633
125638
  secretMasker;
125634
125639
  constructor(options) {
125640
+ this.cwd = options.cwd ?? process.cwd();
125635
125641
  this.execute = options.execute;
125636
125642
  this.provider = options.provider ?? "github";
125637
125643
  this.repository = options.repository;
@@ -125640,7 +125646,8 @@ var RepoMutationService = class {
125640
125646
  }
125641
125647
  async commitAndPush(options) {
125642
125648
  const resolvedCurrentRef = resolveCurrentRef(options);
125643
- const stagePaths = normalizeStagePaths(options.stagePaths);
125649
+ const removePaths = normalizeStagePaths(options.removePaths ?? []);
125650
+ const stagePaths = normalizeStagePaths([...options.stagePaths, ...removePaths]);
125644
125651
  const tokens = this.provider === "azure-devops" ? buildPushTokenOrder({ adoToken: options.adoToken }) : buildPushTokenOrder({
125645
125652
  fallbackToken: options.fallbackToken,
125646
125653
  githubToken: options.githubToken
@@ -125653,8 +125660,43 @@ var RepoMutationService = class {
125653
125660
  resolvedCurrentRef
125654
125661
  };
125655
125662
  }
125663
+ const changed = await this.execute("git", [
125664
+ "status",
125665
+ "--porcelain=v1",
125666
+ "--untracked-files=all",
125667
+ "--",
125668
+ ...stagePaths
125669
+ ]);
125670
+ if (changed.exitCode !== 0) {
125671
+ throw new Error(this.secretMasker(changed.stderr || changed.stdout || "Failed to inspect generated changes"));
125672
+ }
125673
+ const hasPlannedRemoval = removePaths.some(
125674
+ (removePath) => (0, import_node_fs.existsSync)(import_node_path.default.resolve(this.cwd, removePath))
125675
+ );
125676
+ if (!changed.stdout.trim() && !hasPlannedRemoval) {
125677
+ return {
125678
+ commitSha: "",
125679
+ pushed: false,
125680
+ resolvedCurrentRef
125681
+ };
125682
+ }
125683
+ const usePersistedCredentials = tokens.length === 0 && this.provider === "azure-devops";
125684
+ if (options.repoWriteMode === "commit-and-push") {
125685
+ if (!supportsTokenRemote(this.provider)) {
125686
+ throw new Error(`repo-write-mode=commit-and-push is not supported for git provider "${this.provider}"`);
125687
+ }
125688
+ if (!resolvedCurrentRef) {
125689
+ throw new Error("No current ref could be resolved for repo-write-mode=commit-and-push");
125690
+ }
125691
+ if (tokens.length === 0 && !usePersistedCredentials) {
125692
+ throw new Error("No push token configured for repo-write-mode=commit-and-push");
125693
+ }
125694
+ }
125656
125695
  await this.execute("git", ["config", "user.name", options.committerName]);
125657
125696
  await this.execute("git", ["config", "user.email", options.committerEmail]);
125697
+ for (const removePath of removePaths) {
125698
+ (0, import_node_fs.rmSync)(import_node_path.default.resolve(this.cwd, removePath), { force: true });
125699
+ }
125658
125700
  await this.execute("git", ["add", "-A", "--", ...stagePaths]);
125659
125701
  const staged = await this.execute("git", ["diff", "--cached", "--quiet"]);
125660
125702
  if (staged.exitCode === 0) {
@@ -125677,16 +125719,6 @@ var RepoMutationService = class {
125677
125719
  resolvedCurrentRef
125678
125720
  };
125679
125721
  }
125680
- if (!resolvedCurrentRef) {
125681
- throw new Error("No current ref could be resolved for repo-write-mode=commit-and-push");
125682
- }
125683
- const usePersistedCredentials = tokens.length === 0 && this.provider === "azure-devops";
125684
- if (tokens.length === 0 && !usePersistedCredentials) {
125685
- throw new Error("No push token configured for repo-write-mode=commit-and-push");
125686
- }
125687
- if (tokens.length > 0 && !supportsTokenRemote(this.provider)) {
125688
- throw new Error(`repo-write-mode=commit-and-push is not supported for git provider "${this.provider}"`);
125689
- }
125690
125722
  const originalRemote = (await this.execute("git", ["remote", "get-url", "origin"])).stdout.trim();
125691
125723
  let pushed = false;
125692
125724
  let lastError = "";
@@ -126206,11 +126238,11 @@ function createTelemetryContext(options) {
126206
126238
  }
126207
126239
 
126208
126240
  // src/action-version.ts
126209
- var import_node_fs = require("node:fs");
126241
+ var import_node_fs2 = require("node:fs");
126210
126242
  var import_node_path2 = require("node:path");
126211
126243
  function resolveActionVersion2() {
126212
126244
  try {
126213
- const raw = (0, import_node_fs.readFileSync)((0, import_node_path2.join)(__dirname, "..", "package.json"), "utf8");
126245
+ const raw = (0, import_node_fs2.readFileSync)((0, import_node_path2.join)(__dirname, "..", "package.json"), "utf8");
126214
126246
  return JSON.parse(raw).version ?? "unknown";
126215
126247
  } catch {
126216
126248
  return "unknown";
@@ -127274,12 +127306,20 @@ async function retry(operation, options = {}) {
127274
127306
  }
127275
127307
 
127276
127308
  // src/lib/postman/postman-gateway-assets-client.ts
127309
+ var MAX_CREATE_FLIGHTS = 256;
127310
+ var createFlights = /* @__PURE__ */ new Map();
127277
127311
  var PostmanGatewayAssetsClient = class {
127278
127312
  gateway;
127279
127313
  workspaceId;
127314
+ sleep;
127315
+ reconcileAttempts;
127316
+ reconcileDelayMs;
127280
127317
  constructor(options) {
127281
127318
  this.gateway = options.gateway;
127282
127319
  this.workspaceId = String(options.workspaceId || "").trim();
127320
+ this.sleep = options.sleep ?? sleep;
127321
+ this.reconcileAttempts = Math.max(1, options.reconcileAttempts ?? 3);
127322
+ this.reconcileDelayMs = Math.max(0, options.reconcileDelayMs ?? 500);
127283
127323
  }
127284
127324
  asRecord(value) {
127285
127325
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
@@ -127309,8 +127349,64 @@ var PostmanGatewayAssetsClient = class {
127309
127349
  const parts = trimmed.split("-");
127310
127350
  return parts.length >= 6 ? parts.slice(1).join("-") : trimmed;
127311
127351
  }
127312
- isTransient(error2) {
127313
- return error2 instanceof HttpError && (error2.status === 429 || error2.status >= 500);
127352
+ isAmbiguousCreateOutcome(error2) {
127353
+ if (error2 instanceof HttpError) {
127354
+ return error2.status === 408 || error2.status === 429 || error2.status >= 500;
127355
+ }
127356
+ return error2 instanceof Error;
127357
+ }
127358
+ isRetryableIdempotentWriteOutcome(error2) {
127359
+ if (error2 instanceof HttpError) {
127360
+ return error2.status === 408 || error2.status === 429 || error2.status >= 500;
127361
+ }
127362
+ return error2 instanceof Error;
127363
+ }
127364
+ selectExactMatch(kind, identity, matches) {
127365
+ if (matches.length > 1) {
127366
+ const ids = matches.map((match) => match.uid).join(", ");
127367
+ throw new Error(
127368
+ `Multiple ${kind}s match ${identity}: ${ids}. Refusing to choose one; remove duplicates or pass an explicit asset ID.`
127369
+ );
127370
+ }
127371
+ return matches[0] ?? null;
127372
+ }
127373
+ async singleFlight(key, fingerprint, kind, operation) {
127374
+ const existing = createFlights.get(key);
127375
+ if (existing) {
127376
+ if (existing.fingerprint !== fingerprint) {
127377
+ throw new Error(`Incompatible concurrent ${kind} create for ${key}`);
127378
+ }
127379
+ return existing.promise;
127380
+ }
127381
+ if (createFlights.size >= MAX_CREATE_FLIGHTS) {
127382
+ throw new Error(`Too many concurrent Postman asset creates (limit ${MAX_CREATE_FLIGHTS})`);
127383
+ }
127384
+ const pending = operation().finally(() => {
127385
+ if (createFlights.get(key)?.promise === pending) {
127386
+ createFlights.delete(key);
127387
+ }
127388
+ });
127389
+ createFlights.set(key, { fingerprint, promise: pending });
127390
+ return pending;
127391
+ }
127392
+ async discoverAfterAmbiguousCreate(discover, error2) {
127393
+ if (!this.isAmbiguousCreateOutcome(error2)) {
127394
+ return null;
127395
+ }
127396
+ for (let attempt = 0; attempt < this.reconcileAttempts; attempt += 1) {
127397
+ if (attempt > 0) {
127398
+ await this.sleep(this.reconcileDelayMs);
127399
+ }
127400
+ const found = await discover();
127401
+ if (found) {
127402
+ return found;
127403
+ }
127404
+ }
127405
+ return null;
127406
+ }
127407
+ publicEnvironmentUid(data, bareId) {
127408
+ const owner = String(data?.owner ?? "").trim();
127409
+ return owner && !bareId.startsWith(`${owner}-`) ? `${owner}-${bareId}` : bareId;
127314
127410
  }
127315
127411
  // --- environments (service: sync) ---
127316
127412
  //
@@ -127321,9 +127417,10 @@ var PostmanGatewayAssetsClient = class {
127321
127417
  /**
127322
127418
  * Create/upsert an environment through the sync service.
127323
127419
  * POST /environment/import?workspace=:ws { id:<uuid>, name, values } ->
127324
- * { data:{ id:<bare uuid>, owner } }. The id is generated once and reused
127325
- * across retries so the import is idempotent (a retry upserts the same
127326
- * environment instead of duplicating it).
127420
+ * { data:{ id:<bare uuid>, owner } }. The id is generated once for the
127421
+ * operation. Unsafe creates submit once (no blind retry); on an ambiguous
127422
+ * response the client discovers by exact workspace-scoped name before
127423
+ * failing.
127327
127424
  *
127328
127425
  * Returns the PUBLIC uid (`<owner>-<uuid>`), not the bare model id the sync
127329
127426
  * import echoes: mock/monitor create reference the environment by its public
@@ -127333,33 +127430,54 @@ var PostmanGatewayAssetsClient = class {
127333
127430
  */
127334
127431
  async createEnvironment(workspaceId, name, values) {
127335
127432
  const ws = workspaceId || this.workspaceId;
127336
- const id = crypto.randomUUID();
127337
- const body = {
127338
- id,
127339
- name,
127340
- values: values.map((v) => ({
127341
- key: v.key,
127342
- value: v.value,
127343
- type: v.type ?? "default",
127344
- enabled: v.enabled ?? true
127345
- }))
127346
- };
127347
- const response = await retry(
127348
- () => this.gateway.requestJson({
127349
- service: "sync",
127350
- method: "post",
127351
- path: `/environment/import?workspace=${ws}`,
127352
- body
127353
- }),
127354
- { maxAttempts: 5, delayMs: 2e3, backoffMultiplier: 2, maxDelayMs: 15e3, shouldRetry: (e) => this.isTransient(e) }
127355
- );
127356
- const data = this.dataOf(response);
127357
- const bareId = this.idOf(data);
127358
- if (!bareId) {
127359
- throw new Error("Environment import did not return a UID");
127360
- }
127361
- const owner = String(data?.owner ?? "").trim();
127362
- return owner && !bareId.startsWith(`${owner}-`) ? `${owner}-${bareId}` : bareId;
127433
+ const envName = String(name ?? "").trim();
127434
+ const flightKey = `environment:${ws}:${envName}`;
127435
+ const normalizedValues = values.map((v) => ({
127436
+ key: v.key,
127437
+ value: v.value,
127438
+ type: v.type ?? "default",
127439
+ enabled: v.enabled ?? true
127440
+ }));
127441
+ return this.singleFlight(flightKey, JSON.stringify(normalizedValues), "environment", async () => {
127442
+ const existing = await this.findEnvironmentByName(ws, envName);
127443
+ if (existing?.uid) {
127444
+ await this.updateEnvironment(existing.uid, envName, values);
127445
+ return existing.uid;
127446
+ }
127447
+ const id = crypto.randomUUID();
127448
+ const body = {
127449
+ id,
127450
+ name: envName,
127451
+ values: normalizedValues
127452
+ };
127453
+ try {
127454
+ const response = await this.gateway.requestJson(
127455
+ {
127456
+ service: "sync",
127457
+ method: "post",
127458
+ path: `/environment/import?workspace=${ws}`,
127459
+ body
127460
+ },
127461
+ { retryTransient: false }
127462
+ );
127463
+ const data = this.dataOf(response);
127464
+ const bareId = this.idOf(data);
127465
+ if (!bareId) {
127466
+ throw new Error("Environment import did not return a UID");
127467
+ }
127468
+ return this.publicEnvironmentUid(data, bareId);
127469
+ } catch (error2) {
127470
+ const adopted = await this.discoverAfterAmbiguousCreate(async () => {
127471
+ const match = await this.findEnvironmentByName(ws, envName);
127472
+ return match?.uid ?? null;
127473
+ }, error2);
127474
+ if (adopted) {
127475
+ await this.updateEnvironment(adopted, envName, values);
127476
+ return adopted;
127477
+ }
127478
+ throw error2;
127479
+ }
127480
+ });
127363
127481
  }
127364
127482
  /**
127365
127483
  * Update an existing environment through the sync service.
@@ -127389,7 +127507,7 @@ var PostmanGatewayAssetsClient = class {
127389
127507
  path: `/environment/${id}`,
127390
127508
  body
127391
127509
  }),
127392
- { maxAttempts: 5, delayMs: 2e3, backoffMultiplier: 2, maxDelayMs: 15e3, shouldRetry: (e) => this.isTransient(e) }
127510
+ { maxAttempts: 5, delayMs: 2e3, backoffMultiplier: 2, maxDelayMs: 15e3, shouldRetry: (e) => this.isRetryableIdempotentWriteOutcome(e) }
127393
127511
  );
127394
127512
  }
127395
127513
  /**
@@ -127413,13 +127531,37 @@ var PostmanGatewayAssetsClient = class {
127413
127531
  */
127414
127532
  async listEnvironments(workspaceId) {
127415
127533
  const ws = workspaceId || this.workspaceId;
127416
- const response = await this.gateway.requestJson({
127417
- service: "sync",
127418
- method: "post",
127419
- path: `/list/environment?workspace=${ws}`
127420
- });
127534
+ const response = await this.gateway.requestJson(
127535
+ {
127536
+ service: "sync",
127537
+ method: "post",
127538
+ path: `/list/environment?workspace=${ws}`
127539
+ },
127540
+ { retryTransient: true }
127541
+ );
127421
127542
  const items = Array.isArray(response?.data) ? response.data : [];
127422
- return items.map((raw) => this.asRecord(raw)).filter((e) => e !== null).map((e) => ({ name: String(e.name ?? ""), uid: this.idOf(e) }));
127543
+ return items.map((raw) => this.asRecord(raw)).filter((e) => e !== null).map((e) => {
127544
+ const bareOrPublic = this.idOf(e);
127545
+ return {
127546
+ name: String(e.name ?? ""),
127547
+ uid: this.publicEnvironmentUid(e, bareOrPublic)
127548
+ };
127549
+ });
127550
+ }
127551
+ /** Exact name match within a workspace. Prefer tracked UIDs before calling. */
127552
+ async findEnvironmentByName(workspaceId, name) {
127553
+ const want = String(name ?? "").trim();
127554
+ if (!want) {
127555
+ return null;
127556
+ }
127557
+ const environments = await this.listEnvironments(workspaceId);
127558
+ const matches = environments.filter((entry) => entry.name === want);
127559
+ const match = this.selectExactMatch(
127560
+ "environment",
127561
+ `workspace ${workspaceId} and name "${want}"`,
127562
+ matches
127563
+ );
127564
+ return match?.uid ? { uid: match.uid, name: match.name } : null;
127423
127565
  }
127424
127566
  // --- collection read (service: collection, v3 export) ---
127425
127567
  //
@@ -127449,32 +127591,51 @@ var PostmanGatewayAssetsClient = class {
127449
127591
  // --- mocks (service: mock) ---
127450
127592
  async createMock(workspaceId, name, collectionUid, environmentUid) {
127451
127593
  const ws = workspaceId || this.workspaceId;
127594
+ const mockName = String(name ?? "").trim();
127452
127595
  const collection = String(collectionUid ?? "").trim();
127453
127596
  const environment = String(environmentUid ?? "").trim();
127454
- const body = {
127455
- name,
127456
- collection,
127457
- private: false,
127458
- ...environment ? { environment } : {}
127459
- };
127460
- const response = await retry(
127461
- () => this.gateway.requestJson({
127462
- service: "mock",
127463
- method: "post",
127464
- path: `/mocks?workspace=${ws}`,
127465
- body
127466
- }),
127467
- { maxAttempts: 5, delayMs: 2e3, backoffMultiplier: 2, maxDelayMs: 15e3, shouldRetry: (e) => this.isTransient(e) }
127468
- );
127469
- const record = this.dataOf(response);
127470
- const uid = this.idOf(record);
127471
- if (!uid) {
127472
- throw new Error("Mock create did not return a UID");
127473
- }
127474
- return {
127475
- uid,
127476
- url: String(record?.url ?? record?.mockUrl ?? "").trim()
127477
- };
127597
+ const flightKey = `mock:${ws}:${collection}:${environment}:${mockName}`;
127598
+ return this.singleFlight(flightKey, flightKey, "mock", async () => {
127599
+ const existing = await this.findMockByCollection(collection, environment, mockName);
127600
+ if (existing) {
127601
+ return { uid: existing.uid, url: existing.mockUrl };
127602
+ }
127603
+ const body = {
127604
+ name: mockName,
127605
+ collection,
127606
+ private: false,
127607
+ ...environment ? { environment } : {}
127608
+ };
127609
+ try {
127610
+ const response = await this.gateway.requestJson(
127611
+ {
127612
+ service: "mock",
127613
+ method: "post",
127614
+ path: `/mocks?workspace=${ws}`,
127615
+ body
127616
+ },
127617
+ { retryTransient: false }
127618
+ );
127619
+ const record = this.dataOf(response);
127620
+ const uid = this.idOf(record);
127621
+ if (!uid) {
127622
+ throw new Error("Mock create did not return a UID");
127623
+ }
127624
+ return {
127625
+ uid,
127626
+ url: String(record?.url ?? record?.mockUrl ?? "").trim()
127627
+ };
127628
+ } catch (error2) {
127629
+ const adopted = await this.discoverAfterAmbiguousCreate(
127630
+ () => this.findMockByCollection(collection, environment, mockName),
127631
+ error2
127632
+ );
127633
+ if (adopted) {
127634
+ return { uid: adopted.uid, url: adopted.mockUrl };
127635
+ }
127636
+ throw error2;
127637
+ }
127638
+ });
127478
127639
  }
127479
127640
  async listMocks() {
127480
127641
  const response = await this.gateway.requestJson({
@@ -127503,10 +127664,19 @@ var PostmanGatewayAssetsClient = class {
127503
127664
  return false;
127504
127665
  }
127505
127666
  }
127506
- async findMockByCollection(collectionUid) {
127667
+ async findMockByCollection(collectionUid, environmentUid, name) {
127507
127668
  const mocks = await this.listMocks();
127508
127669
  const want = String(collectionUid ?? "").trim();
127509
- const match = mocks.find((m) => m.collection === want);
127670
+ const environment = String(environmentUid ?? "").trim();
127671
+ const mockName = String(name ?? "").trim();
127672
+ const matches = mocks.filter(
127673
+ (mock) => mock.collection === want && mock.environment === environment && mock.name === mockName
127674
+ );
127675
+ const match = this.selectExactMatch(
127676
+ "mock",
127677
+ `workspace ${this.workspaceId}, name "${mockName}", collection ${want}, and environment ${environment || "(none)"}`,
127678
+ matches
127679
+ );
127510
127680
  return match ? { uid: match.uid, mockUrl: match.mockUrl } : null;
127511
127681
  }
127512
127682
  // --- monitors (service: monitors; collection-based = jobTemplates) ---
@@ -127523,32 +127693,51 @@ var PostmanGatewayAssetsClient = class {
127523
127693
  async createMonitor(workspaceId, name, collectionUid, environmentUid, cronSchedule) {
127524
127694
  const ws = workspaceId || this.workspaceId;
127525
127695
  const effectiveCron = cronSchedule && cronSchedule.trim() ? cronSchedule.trim() : "0 0 * * 0";
127696
+ const monitorName = String(name ?? "").trim();
127526
127697
  const collection = String(collectionUid ?? "").trim();
127527
127698
  const environment = String(environmentUid ?? "").trim();
127528
- const body = {
127529
- name,
127530
- collection,
127531
- options: { strictSSL: false, followRedirects: true, requestTimeout: null, requestDelay: 0 },
127532
- notifications: { onFailure: [], onError: [] },
127533
- retry: {},
127534
- schedule: { cronPattern: effectiveCron, timeZone: "UTC" },
127535
- distribution: null,
127536
- ...environment ? { environment } : {}
127537
- };
127538
- const response = await retry(
127539
- () => this.gateway.requestJson({
127540
- service: "monitors",
127541
- method: "post",
127542
- path: `/jobTemplates?workspace=${ws}`,
127543
- body
127544
- }),
127545
- { maxAttempts: 5, delayMs: 2e3, backoffMultiplier: 2, maxDelayMs: 15e3, shouldRetry: (e) => this.isTransient(e) }
127546
- );
127547
- const uid = this.idOf(this.dataOf(response));
127548
- if (!uid) {
127549
- throw new Error("Monitor create did not return a UID");
127550
- }
127551
- return uid;
127699
+ const flightKey = `monitor:${ws}:${collection}:${environment}:${monitorName}`;
127700
+ return this.singleFlight(flightKey, effectiveCron, "monitor", async () => {
127701
+ const existing = await this.findMonitorByCollection(collection, environment, monitorName);
127702
+ if (existing?.uid) {
127703
+ return existing.uid;
127704
+ }
127705
+ const body = {
127706
+ name: monitorName,
127707
+ collection,
127708
+ options: { strictSSL: false, followRedirects: true, requestTimeout: null, requestDelay: 0 },
127709
+ notifications: { onFailure: [], onError: [] },
127710
+ retry: {},
127711
+ schedule: { cronPattern: effectiveCron, timeZone: "UTC" },
127712
+ distribution: null,
127713
+ ...environment ? { environment } : {}
127714
+ };
127715
+ try {
127716
+ const response = await this.gateway.requestJson(
127717
+ {
127718
+ service: "monitors",
127719
+ method: "post",
127720
+ path: `/jobTemplates?workspace=${ws}`,
127721
+ body
127722
+ },
127723
+ { retryTransient: false }
127724
+ );
127725
+ const uid = this.idOf(this.dataOf(response));
127726
+ if (!uid) {
127727
+ throw new Error("Monitor create did not return a UID");
127728
+ }
127729
+ return uid;
127730
+ } catch (error2) {
127731
+ const adopted = await this.discoverAfterAmbiguousCreate(
127732
+ () => this.findMonitorByCollection(collection, environment, monitorName),
127733
+ error2
127734
+ );
127735
+ if (adopted?.uid) {
127736
+ return adopted.uid;
127737
+ }
127738
+ throw error2;
127739
+ }
127740
+ });
127552
127741
  }
127553
127742
  async listMonitors() {
127554
127743
  const response = await this.gateway.requestJson({
@@ -127571,24 +127760,30 @@ var PostmanGatewayAssetsClient = class {
127571
127760
  return false;
127572
127761
  }
127573
127762
  }
127574
- async findMonitorByCollection(collectionUid) {
127763
+ async findMonitorByCollection(collectionUid, environmentUid, name) {
127575
127764
  const want = String(collectionUid ?? "").trim();
127576
- const response = await this.gateway.requestJson({
127577
- service: "monitors",
127578
- method: "get",
127579
- path: `/collections/${want}/jobTemplates?_etc=true`
127580
- });
127581
- const data = response?.data;
127582
- const monitors = this.mapJobTemplates(Array.isArray(data) ? data : []);
127583
- const match = monitors.find((m) => m.collectionUid === want) ?? monitors[0];
127765
+ const environment = String(environmentUid ?? "").trim();
127766
+ const monitorName = String(name ?? "").trim();
127767
+ const monitors = await this.listMonitors();
127768
+ const matches = monitors.filter(
127769
+ (monitor) => monitor.collectionUid === want && monitor.environmentUid === environment && monitor.name === monitorName
127770
+ );
127771
+ const match = this.selectExactMatch(
127772
+ "monitor",
127773
+ `workspace ${this.workspaceId}, name "${monitorName}", collection ${want}, and environment ${environment || "(none)"}`,
127774
+ matches
127775
+ );
127584
127776
  return match?.uid ? { uid: match.uid, name: match.name } : null;
127585
127777
  }
127586
127778
  async runMonitor(uid) {
127587
- await this.gateway.requestJson({
127588
- service: "monitors",
127589
- method: "post",
127590
- path: `/jobTemplates/${uid}/jobs`
127591
- });
127779
+ await this.gateway.requestJson(
127780
+ {
127781
+ service: "monitors",
127782
+ method: "post",
127783
+ path: `/jobTemplates/${uid}/jobs`
127784
+ },
127785
+ { retryTransient: false }
127786
+ );
127592
127787
  }
127593
127788
  };
127594
127789
 
@@ -127754,12 +127949,8 @@ async function mintAccessTokenIfNeeded(inputs, log, setSecret2, fetchImpl = fetc
127754
127949
  function isExpiredAuthError(status, body) {
127755
127950
  return status === 401 || body.includes("UNAUTHENTICATED") || body.includes("authenticationError");
127756
127951
  }
127757
- function isTransientGatewayError(status, body) {
127758
- if (status === 502 || status === 503 || status === 504) return true;
127759
- if (status >= 500 && (body.includes("ESOCKETTIMEDOUT") || body.includes("ETIMEDOUT") || body.includes("ECONNRESET") || body.includes("serverError") || body.includes("downstream"))) {
127760
- return true;
127761
- }
127762
- return false;
127952
+ function isRetryableSafeReadResponse(status) {
127953
+ return status === 408 || status === 429 || status >= 500;
127763
127954
  }
127764
127955
  function defaultSleep(ms) {
127765
127956
  return new Promise((resolve3) => setTimeout(resolve3, ms));
@@ -127818,14 +128009,28 @@ var AccessTokenGatewayClient = class {
127818
128009
  }
127819
128010
  /**
127820
128011
  * Send a gateway request, refreshing the token once on an auth failure and
127821
- * retrying transient downstream failures (5xx / Bifrost read timeouts) with
127822
- * exponential backoff. The auth-refresh-once path is independent of the
127823
- * transient-retry budget.
128012
+ * optionally retrying transient downstream failures (5xx / Bifrost read
128013
+ * timeouts) with exponential backoff. Safe reads keep transient retries;
128014
+ * unsafe creates pass `{ retryTransient: false }` and reconcile after an
128015
+ * ambiguous response instead of re-POSTing. Auth refresh remains independent
128016
+ * of the transient-retry budget.
127824
128017
  */
127825
- async request(request) {
128018
+ async request(request, options = {}) {
128019
+ const retryTransient = options.retryTransient ?? request.method === "get";
127826
128020
  let attempt = 0;
127827
128021
  for (; ; ) {
127828
- let response = await this.send(request);
128022
+ let response;
128023
+ try {
128024
+ response = await this.send(request);
128025
+ } catch (error2) {
128026
+ if (retryTransient && attempt < this.maxRetries) {
128027
+ const delay = this.retryBaseDelayMs * 2 ** attempt;
128028
+ attempt += 1;
128029
+ await this.sleepImpl(delay);
128030
+ continue;
128031
+ }
128032
+ throw error2;
128033
+ }
127829
128034
  if (response.ok) {
127830
128035
  return response;
127831
128036
  }
@@ -127839,7 +128044,7 @@ var AccessTokenGatewayClient = class {
127839
128044
  const retryBody = await response.text().catch(() => "");
127840
128045
  throw this.toHttpError(request, response, retryBody);
127841
128046
  }
127842
- if (isTransientGatewayError(response.status, body) && attempt < this.maxRetries) {
128047
+ if (retryTransient && isRetryableSafeReadResponse(response.status) && attempt < this.maxRetries) {
127843
128048
  const delay = this.retryBaseDelayMs * 2 ** attempt;
127844
128049
  attempt += 1;
127845
128050
  await this.sleepImpl(delay);
@@ -127849,8 +128054,8 @@ var AccessTokenGatewayClient = class {
127849
128054
  }
127850
128055
  }
127851
128056
  /** Send a gateway request and parse the JSON body, or null when empty. */
127852
- async requestJson(request) {
127853
- const response = await this.request(request);
128057
+ async requestJson(request, options = {}) {
128058
+ const response = await this.request(request, options);
127854
128059
  const text = await response.text().catch(() => "");
127855
128060
  if (!text.trim()) {
127856
128061
  return null;
@@ -127965,8 +128170,27 @@ function normalizeInputValue(value) {
127965
128170
  return String(value ?? "").trim();
127966
128171
  }
127967
128172
  function getInput2(name, env = process.env) {
127968
- const envName = `INPUT_${name.replace(/-/g, "_").toUpperCase()}`;
127969
- return normalizeInputValue(env[envName]);
128173
+ const normalizedName = `INPUT_${name.replace(/-/g, "_").toUpperCase()}`;
128174
+ const runnerName = `INPUT_${name.replace(/ /g, "_").toUpperCase()}`;
128175
+ const normalizedRaw = env[normalizedName];
128176
+ const runnerRaw = runnerName === normalizedName ? void 0 : env[runnerName];
128177
+ const hasNormalized = normalizedRaw !== void 0;
128178
+ const hasRunner = runnerRaw !== void 0;
128179
+ if (hasNormalized && hasRunner) {
128180
+ const normalizedValue = normalizeInputValue(normalizedRaw);
128181
+ const runnerValue = normalizeInputValue(runnerRaw);
128182
+ if (normalizedValue !== runnerValue) {
128183
+ throw new Error(
128184
+ `Conflicting values for ${name}: ${normalizedName}=${JSON.stringify(normalizedValue)} vs ${runnerName}=${JSON.stringify(runnerValue)}`
128185
+ );
128186
+ }
128187
+ }
128188
+ return normalizeInputValue(hasNormalized ? normalizedRaw : runnerRaw);
128189
+ }
128190
+ function hasInput(name, env = process.env) {
128191
+ const normalizedName = `INPUT_${name.replace(/-/g, "_").toUpperCase()}`;
128192
+ const runnerName = `INPUT_${name.replace(/ /g, "_").toUpperCase()}`;
128193
+ return env[normalizedName] !== void 0 || runnerName !== normalizedName && env[runnerName] !== void 0;
127970
128194
  }
127971
128195
  function parseJsonMap(raw) {
127972
128196
  if (!raw.trim()) return {};
@@ -127996,7 +128220,9 @@ function normalizeRepoWriteMode(value) {
127996
128220
  if (value === "none" || value === "commit-only" || value === "commit-and-push") {
127997
128221
  return value;
127998
128222
  }
127999
- return "commit-and-push";
128223
+ throw new Error(
128224
+ `Unsupported repo-write-mode "${value}". Allowed values: none, commit-only, commit-and-push`
128225
+ );
128000
128226
  }
128001
128227
  function normalizeCollectionSyncMode(value) {
128002
128228
  if (value === "refresh" || value === "version") {
@@ -128078,7 +128304,7 @@ function resolveInputs(env = process.env) {
128078
128304
  environmentUids,
128079
128305
  envRuntimeUrls,
128080
128306
  artifactDir: getInput2("artifact-dir", env) || "postman",
128081
- repoWriteMode: normalizeRepoWriteMode(getInput2("repo-write-mode", env) || "commit-and-push"),
128307
+ repoWriteMode: hasInput("repo-write-mode", env) ? normalizeRepoWriteMode(getInput2("repo-write-mode", env)) : "commit-and-push",
128082
128308
  currentRef: getInput2("current-ref", env) || normalizeInputValue(env.GITHUB_REF) || normalizeInputValue(env.BUILD_SOURCEBRANCH),
128083
128309
  githubHeadRef: getInput2("github-head-ref", env) || normalizeInputValue(env.GITHUB_HEAD_REF) || normalizeInputValue(env.SYSTEM_PULLREQUEST_SOURCEBRANCH),
128084
128310
  githubRefName: getInput2("github-ref-name", env) || normalizeInputValue(env.GITHUB_REF_NAME) || normalizeInputValue(repoContext.ref),
@@ -128127,7 +128353,7 @@ function buildEnvironmentValues(envName, baseUrl) {
128127
128353
  var LEGACY_BASELINE_COLLECTION_PREFIX = "[Baseline]";
128128
128354
  function readResourcesState() {
128129
128355
  try {
128130
- return load((0, import_node_fs2.readFileSync)(".postman/resources.yaml", "utf8"));
128356
+ return load((0, import_node_fs3.readFileSync)(".postman/resources.yaml", "utf8"));
128131
128357
  } catch {
128132
128358
  return null;
128133
128359
  }
@@ -128165,7 +128391,7 @@ function isOpenApiSpecFile(filePath) {
128165
128391
  return false;
128166
128392
  }
128167
128393
  try {
128168
- const raw = (0, import_node_fs2.readFileSync)(filePath, "utf8");
128394
+ const raw = (0, import_node_fs3.readFileSync)(filePath, "utf8");
128169
128395
  const parsed = filePath.endsWith(".json") ? JSON.parse(raw) : load(raw);
128170
128396
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
128171
128397
  return false;
@@ -128194,7 +128420,7 @@ function scanLocalSpecReferences(baseDir = ".") {
128194
128420
  const found = /* @__PURE__ */ new Set();
128195
128421
  const refs = [];
128196
128422
  const visit2 = (currentDir) => {
128197
- for (const entry of (0, import_node_fs2.readdirSync)(currentDir, { withFileTypes: true })) {
128423
+ for (const entry of (0, import_node_fs3.readdirSync)(currentDir, { withFileTypes: true })) {
128198
128424
  if (ignoredDirs.has(entry.name)) {
128199
128425
  continue;
128200
128426
  }
@@ -128224,7 +128450,7 @@ function resolveMappedSpecReference(explicitSpecPath, discoveredSpecs) {
128224
128450
  const normalizedExplicitPath = normalizeToPosix(explicitSpecPath.trim());
128225
128451
  if (normalizedExplicitPath) {
128226
128452
  const explicitFullPath = path8.resolve(normalizedExplicitPath);
128227
- if ((0, import_node_fs2.existsSync)(explicitFullPath) && (0, import_node_fs2.statSync)(explicitFullPath).isFile()) {
128453
+ if ((0, import_node_fs3.existsSync)(explicitFullPath) && (0, import_node_fs3.statSync)(explicitFullPath).isFile()) {
128228
128454
  return {
128229
128455
  repoRelativePath: normalizedExplicitPath,
128230
128456
  configRelativePath: normalizeToPosix(path8.join("..", normalizedExplicitPath))
@@ -128421,25 +128647,35 @@ async function upsertEnvironments(inputs, dependencies, resourcesState) {
128421
128647
  for (const envName of inputs.environments) {
128422
128648
  const runtimeUrl = String(inputs.envRuntimeUrls[envName] || "").trim();
128423
128649
  const values = buildEnvironmentValues(envName, runtimeUrl);
128424
- const existingUid = envUids[envName];
128425
- if (existingUid) {
128426
- await dependencies.postman.updateEnvironment(
128427
- existingUid,
128428
- `${inputs.projectName} - ${envName}`,
128429
- values
128650
+ const displayName = `${inputs.projectName} - ${envName}`;
128651
+ let existingUid = String(envUids[envName] || "").trim();
128652
+ if (!existingUid) {
128653
+ const discovered = await dependencies.postman.findEnvironmentByName(
128654
+ inputs.workspaceId,
128655
+ displayName
128430
128656
  );
128657
+ if (discovered?.uid) {
128658
+ existingUid = discovered.uid;
128659
+ dependencies.core.info(
128660
+ `Discovered existing environment for ${displayName}: ${existingUid}`
128661
+ );
128662
+ }
128663
+ }
128664
+ if (existingUid) {
128665
+ await dependencies.postman.updateEnvironment(existingUid, displayName, values);
128666
+ envUids[envName] = existingUid;
128431
128667
  continue;
128432
128668
  }
128433
128669
  envUids[envName] = await dependencies.postman.createEnvironment(
128434
128670
  inputs.workspaceId,
128435
- `${inputs.projectName} - ${envName}`,
128671
+ displayName,
128436
128672
  values
128437
128673
  );
128438
128674
  }
128439
128675
  return envUids;
128440
128676
  }
128441
128677
  function ensureDir(path9) {
128442
- (0, import_node_fs2.mkdirSync)(path9, { recursive: true });
128678
+ (0, import_node_fs3.mkdirSync)(path9, { recursive: true });
128443
128679
  }
128444
128680
  function getCollectionDirectoryName(kind, projectName) {
128445
128681
  if (kind === "Baseline") {
@@ -128476,7 +128712,7 @@ function stripVolatileFields(obj) {
128476
128712
  }
128477
128713
  function writeJsonFile(path9, content, normalize3 = false) {
128478
128714
  const data = normalize3 ? stripVolatileFields(content) : content;
128479
- (0, import_node_fs2.writeFileSync)(path9, JSON.stringify(data, null, 2));
128715
+ (0, import_node_fs3.writeFileSync)(path9, JSON.stringify(data, null, 2));
128480
128716
  }
128481
128717
  function buildResourcesManifest(workspaceId, collectionMap, envMap, artifactDir, localSpecRefs, mappedSpecRef, specId) {
128482
128718
  const manifest = {
@@ -128550,21 +128786,21 @@ function assertPathWithinCwd(targetPath, fieldName) {
128550
128786
  if (!rawPath || hasControlCharacter2(originalPath) || path8.isAbsolute(rawPath) || path8.win32.isAbsolute(rawPath) || segments.includes("..") || rawPath.startsWith(":") || hasControlCharacter2(rawPath)) {
128551
128787
  throw new Error(`${fieldName} must stay within the repository root; received ${targetPath}`);
128552
128788
  }
128553
- const base = (0, import_node_fs2.realpathSync)(process.cwd());
128789
+ const base = (0, import_node_fs3.realpathSync)(process.cwd());
128554
128790
  const resolved = path8.resolve(base, rawPath);
128555
128791
  const relative3 = path8.relative(base, resolved);
128556
128792
  if (relative3.startsWith("..") || path8.isAbsolute(relative3)) {
128557
128793
  throw new Error(`${fieldName} must stay within the repository root; received ${targetPath}`);
128558
128794
  }
128559
128795
  let existingPath = resolved;
128560
- while (!(0, import_node_fs2.existsSync)(existingPath)) {
128796
+ while (!(0, import_node_fs3.existsSync)(existingPath)) {
128561
128797
  const parent = path8.dirname(existingPath);
128562
128798
  if (parent === existingPath) {
128563
128799
  break;
128564
128800
  }
128565
128801
  existingPath = parent;
128566
128802
  }
128567
- const realExistingPath = (0, import_node_fs2.realpathSync)(existingPath);
128803
+ const realExistingPath = (0, import_node_fs3.realpathSync)(existingPath);
128568
128804
  const realRelative = path8.relative(base, realExistingPath);
128569
128805
  if (realRelative.startsWith("..") || path8.isAbsolute(realRelative)) {
128570
128806
  throw new Error(`${fieldName} must stay within the repository root; received ${targetPath}`);
@@ -128592,8 +128828,8 @@ async function exportArtifacts(inputs, dependencies, envUids, assetProjectName)
128592
128828
  ensureDir(specsDir);
128593
128829
  ensureDir(".postman");
128594
128830
  const globalsFilePath = `${globalsDir}/workspace.globals.yaml`;
128595
- if (!(0, import_node_fs2.existsSync)(globalsFilePath)) {
128596
- (0, import_node_fs2.writeFileSync)(globalsFilePath, "name: Globals\nvalues: []\n");
128831
+ if (!(0, import_node_fs3.existsSync)(globalsFilePath)) {
128832
+ (0, import_node_fs3.writeFileSync)(globalsFilePath, "name: Globals\nvalues: []\n");
128597
128833
  }
128598
128834
  if (inputs.generateCiWorkflow) {
128599
128835
  const ciDir = inputs.ciWorkflowPath.split("/").slice(0, -1).join("/");
@@ -128629,7 +128865,7 @@ async function exportArtifacts(inputs, dependencies, envUids, assetProjectName)
128629
128865
  true
128630
128866
  );
128631
128867
  }
128632
- (0, import_node_fs2.writeFileSync)(".postman/resources.yaml", buildResourcesManifest(
128868
+ (0, import_node_fs3.writeFileSync)(".postman/resources.yaml", buildResourcesManifest(
128633
128869
  inputs.workspaceId,
128634
128870
  manifestCollections,
128635
128871
  envUids,
@@ -128639,7 +128875,7 @@ async function exportArtifacts(inputs, dependencies, envUids, assetProjectName)
128639
128875
  inputs.specId || void 0
128640
128876
  ));
128641
128877
  if (mappedSpec && Object.keys(manifestCollections).length > 0) {
128642
- (0, import_node_fs2.writeFileSync)(
128878
+ (0, import_node_fs3.writeFileSync)(
128643
128879
  ".postman/workflows.yaml",
128644
128880
  buildSpecCollectionWorkflowManifest(
128645
128881
  mappedSpec.configRelativePath,
@@ -128676,29 +128912,27 @@ function createRepoSummary(outputs, envUids, pushed) {
128676
128912
  });
128677
128913
  }
128678
128914
  async function commitAndPushGeneratedFiles(inputs, dependencies) {
128679
- if (!dependencies.repoMutation || inputs.repoWriteMode === "none") {
128680
- return { commitSha: "", resolvedCurrentRef: "", pushed: false };
128681
- }
128682
128915
  if (inputs.generateCiWorkflow) {
128916
+ assertPathWithinCwd(inputs.ciWorkflowPath, "ci-workflow-path");
128683
128917
  const ciWorkflow = renderCiWorkflow(inputs);
128684
128918
  const parts = inputs.ciWorkflowPath.split("/");
128685
128919
  if (parts.length > 1) {
128686
128920
  const dir = parts.slice(0, -1).join("/");
128687
128921
  ensureDir(dir);
128688
128922
  }
128689
- (0, import_node_fs2.writeFileSync)(inputs.ciWorkflowPath, ciWorkflow);
128923
+ (0, import_node_fs3.writeFileSync)(inputs.ciWorkflowPath, ciWorkflow);
128690
128924
  }
128691
- const provisionPath = ".github/workflows/provision.yml";
128692
- const provisionExists = inputs.provider === "github" && (0, import_node_fs2.existsSync)(provisionPath);
128693
- if (provisionExists) {
128694
- (0, import_node_fs2.rmSync)(provisionPath);
128925
+ if (!dependencies.repoMutation || inputs.repoWriteMode === "none") {
128926
+ return { commitSha: "", resolvedCurrentRef: "", pushed: false };
128695
128927
  }
128928
+ const provisionPath = ".github/workflows/provision.yml";
128929
+ const provisionExists = inputs.provider === "github" && (0, import_node_fs3.existsSync)(provisionPath);
128696
128930
  const stagePaths = [
128697
128931
  inputs.artifactDir,
128698
128932
  ".postman",
128699
128933
  inputs.generateCiWorkflow ? inputs.ciWorkflowPath : null,
128700
128934
  provisionExists ? provisionPath : null
128701
- ].filter((entry) => typeof entry === "string" && ((0, import_node_fs2.existsSync)(entry) || entry === provisionPath));
128935
+ ].filter((entry) => typeof entry === "string" && ((0, import_node_fs3.existsSync)(entry) || entry === provisionPath));
128702
128936
  if (stagePaths.length === 0) {
128703
128937
  dependencies.core.info("No generated repository paths were found; skipping repo mutation.");
128704
128938
  return {
@@ -128722,6 +128956,7 @@ async function commitAndPushGeneratedFiles(inputs, dependencies) {
128722
128956
  adoToken: inputs.provider === "azure-devops" ? inputs.adoToken : void 0,
128723
128957
  githubToken: inputs.provider === "azure-devops" ? void 0 : inputs.githubToken,
128724
128958
  fallbackToken: inputs.provider === "azure-devops" ? void 0 : inputs.ghFallbackToken,
128959
+ removePaths: provisionExists ? [provisionPath] : [],
128725
128960
  stagePaths
128726
128961
  });
128727
128962
  return {
@@ -128804,12 +129039,17 @@ async function runRepoSyncInner(inputs, dependencies) {
128804
129039
  const mockEnvUid = envUids.dev || envUids.prod || Object.values(envUids)[0];
128805
129040
  if (mockEnvUid) {
128806
129041
  let resolvedMockUrl = "";
129042
+ const mockName = `${assetProjectName} Mock`;
128807
129043
  if (inputs.mockUrl) {
128808
129044
  resolvedMockUrl = inputs.mockUrl;
128809
129045
  dependencies.core.info(`Reusing mock from explicit input: ${resolvedMockUrl}`);
128810
129046
  }
128811
129047
  if (!resolvedMockUrl && inputs.baselineCollectionId) {
128812
- const discovered = await dependencies.postman.findMockByCollection(inputs.baselineCollectionId);
129048
+ const discovered = await dependencies.postman.findMockByCollection(
129049
+ inputs.baselineCollectionId,
129050
+ mockEnvUid,
129051
+ mockName
129052
+ );
128813
129053
  if (discovered) {
128814
129054
  resolvedMockUrl = discovered.mockUrl;
128815
129055
  dependencies.core.info(`Discovered existing mock for collection ${inputs.baselineCollectionId}: ${resolvedMockUrl}`);
@@ -128818,7 +129058,7 @@ async function runRepoSyncInner(inputs, dependencies) {
128818
129058
  if (!resolvedMockUrl) {
128819
129059
  const mock = await dependencies.postman.createMock(
128820
129060
  inputs.workspaceId,
128821
- `${assetProjectName} Mock`,
129061
+ mockName,
128822
129062
  inputs.baselineCollectionId,
128823
129063
  mockEnvUid
128824
129064
  );
@@ -128833,6 +129073,7 @@ async function runRepoSyncInner(inputs, dependencies) {
128833
129073
  const effectiveCron = inputs.monitorCron && inputs.monitorCron.trim() ? inputs.monitorCron.trim() : "";
128834
129074
  if (monitorEnvUid && inputs.monitorType !== "cli") {
128835
129075
  let resolvedMonitorId = "";
129076
+ const monitorName = `${assetProjectName} - Smoke Monitor`;
128836
129077
  if (inputs.monitorId) {
128837
129078
  const valid = await dependencies.postman.monitorExists(inputs.monitorId);
128838
129079
  if (valid) {
@@ -128843,7 +129084,11 @@ async function runRepoSyncInner(inputs, dependencies) {
128843
129084
  }
128844
129085
  }
128845
129086
  if (!resolvedMonitorId && inputs.smokeCollectionId) {
128846
- const discovered = await dependencies.postman.findMonitorByCollection(inputs.smokeCollectionId);
129087
+ const discovered = await dependencies.postman.findMonitorByCollection(
129088
+ inputs.smokeCollectionId,
129089
+ monitorEnvUid,
129090
+ monitorName
129091
+ );
128847
129092
  if (discovered) {
128848
129093
  resolvedMonitorId = discovered.uid;
128849
129094
  dependencies.core.info(`Discovered existing monitor for collection ${inputs.smokeCollectionId}: ${resolvedMonitorId}`);
@@ -128852,7 +129097,7 @@ async function runRepoSyncInner(inputs, dependencies) {
128852
129097
  if (!resolvedMonitorId) {
128853
129098
  resolvedMonitorId = await dependencies.postman.createMonitor(
128854
129099
  inputs.workspaceId,
128855
- `${assetProjectName} - Smoke Monitor`,
129100
+ monitorName,
128856
129101
  inputs.smokeCollectionId,
128857
129102
  monitorEnvUid,
128858
129103
  effectiveCron || void 0
@@ -129065,6 +129310,7 @@ function createRepoSyncDependencies(inputs, resolved, factories, options = {}) {
129065
129310
  createEnvironment: gatewayAssets.createEnvironment.bind(gatewayAssets),
129066
129311
  getEnvironment: gatewayAssets.getEnvironment.bind(gatewayAssets),
129067
129312
  updateEnvironment: gatewayAssets.updateEnvironment.bind(gatewayAssets),
129313
+ findEnvironmentByName: gatewayAssets.findEnvironmentByName.bind(gatewayAssets),
129068
129314
  // Collection read via the v3 export endpoint — returns canonical v3 IR,
129069
129315
  // written to disk by `convertAndSplitAnyCollection`. PMAK is never used for
129070
129316
  // collection reads.
@@ -129179,6 +129425,7 @@ async function runAction(actionCore = core_exports, actionExec = exec_exports) {
129179
129425
  assertPathWithinCwd,
129180
129426
  createRepoSyncDependencies,
129181
129427
  getInput,
129428
+ hasInput,
129182
129429
  readActionInputs,
129183
129430
  resolveInputs,
129184
129431
  resolvePostmanApiKeyAndTeamId,