tegami 1.1.2 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { f as Tegami, j as Draft, t as Awaitable, v as PublishPlan } from "../types-B50RK1rR.js";
1
+ import { f as Tegami, j as Draft, t as Awaitable, v as PublishPlan } from "../types-BbwOrNZ2.js";
2
2
 
3
3
  //#region src/cli/index.d.ts
4
4
  interface TegamiCLIOptions {
package/dist/cli/index.js CHANGED
@@ -279,11 +279,12 @@ function createTegamiCliRegistry(tegami) {
279
279
  };
280
280
  commands.set(definition.path.join("\0"), definition);
281
281
  const api = {
282
- option(name, { short, description = "", type }) {
282
+ option(name, { short, description = "", type, multiple }) {
283
283
  definition.options.push({
284
284
  name,
285
285
  short,
286
286
  type,
287
+ multiple,
287
288
  description
288
289
  });
289
290
  return api;
@@ -295,6 +296,14 @@ function createTegamiCliRegistry(tegami) {
295
296
  });
296
297
  return api;
297
298
  },
299
+ positionals(name) {
300
+ definition.positionals.push({
301
+ name,
302
+ required: false,
303
+ multiple: true
304
+ });
305
+ return api;
306
+ },
298
307
  action(fn) {
299
308
  definition.action = fn;
300
309
  }
@@ -332,7 +341,12 @@ function createTegamiCliRegistry(tegami) {
332
341
  };
333
342
  }
334
343
  function formatUsage(command) {
335
- return [...command.path, ...command.positionals.map((positional) => positional.required ? `<${positional.name}>` : `[${positional.name}]`)].join(" ");
344
+ const s = [...command.path];
345
+ for (const positional of command.positionals) {
346
+ let c = positional.multiple ? `...${positional.name}` : positional.name;
347
+ s.push(positional.required ? `<${c}>` : `[${c}]`);
348
+ }
349
+ return s.join(" ");
336
350
  }
337
351
  function findCommand(commands, argv) {
338
352
  if (argv.length === 0) return commands.get("");
@@ -343,28 +357,34 @@ function findCommand(commands, argv) {
343
357
  }
344
358
  }
345
359
  function parseCommandArgs(command, args) {
346
- const optionConfig = { help: {
360
+ const optionsConfig = { help: {
347
361
  type: "boolean",
348
362
  short: "h"
349
363
  } };
350
- for (const option of command.options) optionConfig[option.name] = option.short ? {
351
- type: option.type,
352
- short: option.short
353
- } : { type: option.type };
364
+ for (const option of command.options) {
365
+ const config = optionsConfig[option.name] = { type: option.type };
366
+ if (option.short) config.short = option.short;
367
+ if (option.multiple) config.multiple = true;
368
+ }
354
369
  const parsed = parseArgs({
355
370
  args,
356
- options: optionConfig,
371
+ options: optionsConfig,
357
372
  strict: true,
358
373
  allowPositionals: command.positionals.length > 0
359
374
  });
360
375
  const positionals = {};
361
- if (parsed.positionals.length > command.positionals.length) throw new Error("Too many arguments");
362
376
  for (const positional of command.positionals) {
377
+ if (positional.multiple) {
378
+ const value = positionals[positional.name] = [];
379
+ while (parsed.positionals.length > 0) value.push(parsed.positionals.shift());
380
+ continue;
381
+ }
363
382
  const value = parsed.positionals.shift();
364
383
  if (value === void 0 && positional.required) throw new Error(`missing required argument: ${positional.name}`);
365
384
  if (value === void 0) continue;
366
385
  positionals[positional.name] = value;
367
386
  }
387
+ if (parsed.positionals.length > 0) throw new Error("Too many arguments");
368
388
  return {
369
389
  values: parsed.values,
370
390
  positionals
@@ -471,9 +491,10 @@ function registerCoreCommands(cli, tegami, options) {
471
491
  cli.command("publish", { description: "publish packages from the publish lock" }).option("dry-run", {
472
492
  type: "boolean",
473
493
  description: "validate the publish lock without publishing"
474
- }).action(async ({ values }) => {
494
+ }).positionals("packages").action(async ({ values, positionals }) => {
475
495
  await publishPackages(tegami, {
476
496
  dryRun: values["dry-run"],
497
+ packages: positionals.packages?.length ? positionals.packages : void 0,
477
498
  cli: options
478
499
  });
479
500
  });
@@ -538,7 +559,10 @@ async function publishPackages(tegami, options) {
538
559
  intro(dryRun ? "Publish packages (dry run)" : "Publish packages");
539
560
  const s = spinner();
540
561
  s.start(dryRun ? "Validating publish lock" : "Publishing packages");
541
- const plan = customPublish ? await customPublish() : await tegami.publish({ dryRun });
562
+ const plan = customPublish ? await customPublish() : await tegami.publish({
563
+ dryRun,
564
+ packages: options.packages && options.packages.length > 0 ? options.packages : void 0
565
+ });
542
566
  if (plan === "skipped") {
543
567
  s.stop(dryRun ? "No publish lock to validate" : "Nothing to publish");
544
568
  outro(`No publishable packages were found in ${context.lockPath}.`);
@@ -1,4 +1,4 @@
1
- import { r as LogGenerator } from "../types-B50RK1rR.js";
1
+ import { r as LogGenerator } from "../types-BbwOrNZ2.js";
2
2
 
3
3
  //#region src/generators/simple.d.ts
4
4
  declare function simpleGenerator(): LogGenerator;
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { A as WorkspacePackage, M as DraftPolicy, N as PackageDraft, O as PackageGraph, P as BumpType, _ as PublishOptions, a as PublishPreflight, b as TegamiContext, c as TegamiPluginOption, d as GenerateChangelogOptions, f as Tegami, g as PackagePublishResult, h as PackagePublishPlan, i as PackageOptions, j as Draft, k as PackageGroup, m as PublishLock, n as GroupOptions, o as TegamiOptions, p as tegami, r as LogGenerator, s as TegamiPlugin, v as PublishPlan, y as CommitChangelog } from "./types-B50RK1rR.js";
1
+ import { A as WorkspacePackage, M as DraftPolicy, N as PackageDraft, O as PackageGraph, P as BumpType, _ as PublishOptions, a as PublishPreflight, b as TegamiContext, c as TegamiPluginOption, d as GenerateChangelogOptions, f as Tegami, g as PackagePublishResult, h as PackagePublishPlan, i as PackageOptions, j as Draft, k as PackageGroup, m as PublishLock, n as GroupOptions, o as TegamiOptions, p as tegami, r as LogGenerator, s as TegamiPlugin, v as PublishPlan, y as CommitChangelog } from "./types-BbwOrNZ2.js";
2
2
  export { type BumpType, type CommitChangelog, type Draft, type DraftPolicy, GenerateChangelogOptions, type GroupOptions, type LogGenerator, type PackageDraft, PackageGraph, type PackageGroup, type PackageOptions, type PackagePublishPlan, type PackagePublishResult, type PublishLock, type PublishOptions, type PublishPlan, type PublishPreflight, Tegami, type TegamiContext, type TegamiOptions, type TegamiPlugin, type TegamiPluginOption, WorkspacePackage, tegami };
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { n as generateFromCommits } from "./generate-Bg86OJP4.js";
2
2
  import { r as handlePluginError } from "./error-BhMYq9iW.js";
3
- import { a as parseChangelogFile, o as readChangelogEntries, t as createDraft } from "./draft-CzUiQasJ.js";
4
- import { a as runPreflights, i as publishPlanStatus, o as runPublishPlan, r as initPublishPlan, t as npm } from "./npm-DoPhFKji.js";
3
+ import { a as createDraft, c as parseChangelogFile, i as runPublishPlan, l as readChangelogEntries, n as publishPlanStatus, r as runPreflights, t as initPublishPlan } from "./publish-v30y8Lwq.js";
4
+ import { t as npm } from "./npm-DaUHTtlV.js";
5
5
  import { n as WorkspacePackage, t as PackageGraph } from "./graph-BmXTJZxx.js";
6
6
  import { mkdir, rm, writeFile } from "node:fs/promises";
7
7
  import path, { join } from "node:path";
@@ -98,9 +98,9 @@ function tegami(options = {}) {
98
98
  }
99
99
  return createDraft(changelogs, context);
100
100
  },
101
- async publishStatus() {
101
+ async publishStatus(publishOptions = {}) {
102
102
  const context = await getContextResolved();
103
- const plan = await initPublishPlan(context, {});
103
+ const plan = await initPublishPlan(context, publishOptions);
104
104
  if (!plan) return "idle";
105
105
  await runPreflights(context, plan);
106
106
  return publishPlanStatus(plan, context);
@@ -115,9 +115,9 @@ function tegami(options = {}) {
115
115
  if (Array.from(plan.packages.values()).every((pkg) => pkg.publishResult.type === "skipped")) return "skipped";
116
116
  return plan;
117
117
  },
118
- async cleanup() {
118
+ async cleanup(publishOptions = {}) {
119
119
  const context = await getContextResolved();
120
- const plan = await initPublishPlan(context, {});
120
+ const plan = await initPublishPlan(context, publishOptions);
121
121
  if (!plan) return {
122
122
  state: "skipped",
123
123
  reason: "no-plan"
@@ -1,151 +1,18 @@
1
- import { c as somePromise, i as isNodeError, n as execFailure, r as handlePluginError, s as joinPath } from "./error-BhMYq9iW.js";
1
+ import { i as isNodeError, n as execFailure, s as joinPath } from "./error-BhMYq9iW.js";
2
2
  import { t as _accessExpressionAsString } from "./_accessExpressionAsString-QhbUZzwv.js";
3
3
  import { n as _validateReport, t as _createStandardSchema } from "./_createStandardSchema-BGQyz-uA.js";
4
- import { a as parseChangelogFile, i as parsePublishLock, n as validateChangelogStore, r as validatePackageStore } from "./draft-CzUiQasJ.js";
4
+ import { r as runPreflights, s as parsePublishLock, t as initPublishPlan } from "./publish-v30y8Lwq.js";
5
5
  import { t as _assertGuard } from "./_assertGuard-BBn2NbSz.js";
6
6
  import { n as WorkspacePackage } from "./graph-BmXTJZxx.js";
7
7
  import fs, { readFile, writeFile } from "node:fs/promises";
8
8
  import path, { join } from "node:path";
9
9
  import { x } from "tinyexec";
10
10
  import * as semver$1 from "semver";
11
- import { parse as parse$1, parseDocument, stringify } from "yaml";
11
+ import { parseDocument } from "yaml";
12
12
  import { detect } from "package-manager-detector";
13
13
  import { tmpdir } from "node:os";
14
14
  import { intro, note, outro } from "@clack/prompts";
15
15
  import { glob } from "tinyglobby";
16
- //#region src/plans/publish.ts
17
- async function initPublishPlan(context, options) {
18
- let lock;
19
- try {
20
- lock = parsePublishLock(await fs.readFile(context.lockPath, "utf8"));
21
- } catch {
22
- return;
23
- }
24
- let data;
25
- const packages = /* @__PURE__ */ new Map();
26
- const changelogs = /* @__PURE__ */ new Map();
27
- while (data = lock.read("core:changelogs")) {
28
- const validated = validateChangelogStore(data);
29
- if (!validated.success) continue;
30
- const entry = validated.data;
31
- const parsed = parseChangelogFile(entry.filename, entry.content);
32
- if (!parsed) continue;
33
- changelogs.set(parsed.id, parsed);
34
- }
35
- while (data = lock.read("core:packages")) {
36
- const validated = validatePackageStore(data);
37
- if (!validated.success) continue;
38
- const parsed = validated.data;
39
- if (!context.graph.get(parsed.id)) continue;
40
- const pkgChangelogs = [];
41
- for (const id of parsed.changelogIds ?? []) {
42
- const entry = changelogs.get(id);
43
- if (entry) pkgChangelogs.push(entry);
44
- }
45
- packages.set(parsed.id, {
46
- changelogs: pkgChangelogs,
47
- updated: parsed.updated
48
- });
49
- }
50
- const plan = {
51
- options,
52
- changelogs,
53
- packages
54
- };
55
- for (const plugin of context.plugins) await handlePluginError(plugin, "initPublishPlan", () => plugin.initPublishPlan?.call(context, {
56
- lock,
57
- plan
58
- }));
59
- return plan;
60
- }
61
- function resolvePublishTargets(plan) {
62
- const ordered = [];
63
- const scanned = /* @__PURE__ */ new Set();
64
- function scan(id, stack) {
65
- const preflight = plan.packages.get(id)?.preflight;
66
- if (!preflight || !preflight.shouldPublish) return;
67
- if (stack.has(id)) throw new Error(`circular reference of deps: ${[...stack, id].join(" -> ")}`);
68
- if (scanned.has(id)) return;
69
- if (preflight.wait) {
70
- stack.add(id);
71
- for (const dep of preflight.wait) scan(dep, stack);
72
- stack.delete(id);
73
- }
74
- ordered.push(id);
75
- scanned.add(id);
76
- }
77
- const stack = /* @__PURE__ */ new Set();
78
- for (const id of plan.packages.keys()) scan(id, stack);
79
- return ordered;
80
- }
81
- async function runPublishPlan(context, plan) {
82
- const { dryRun = false } = plan.options;
83
- const onPublishResult = async (pkg, publishResult) => {
84
- const packagePlan = plan.packages.get(pkg.id);
85
- if (!packagePlan) return;
86
- packagePlan.publishResult = publishResult;
87
- if (publishResult.type === "skipped") return;
88
- for (const plugin of context.plugins) await handlePluginError(plugin, "afterPublish", () => plugin.afterPublish?.call(context, {
89
- pkg,
90
- plan
91
- }));
92
- };
93
- publishLoop: for (const id of resolvePublishTargets(plan)) {
94
- const pkg = context.graph.get(id);
95
- if (dryRun) {
96
- await onPublishResult(pkg, { type: "published" });
97
- continue;
98
- }
99
- for (const plugin of context.plugins) if (await handlePluginError(plugin, "willPublish", () => plugin.willPublish?.call(context, { pkg })) === false) continue publishLoop;
100
- for (const plugin of context.plugins) {
101
- const publishResult = await handlePluginError(plugin, "publish", () => plugin.publish?.call(context, {
102
- pkg,
103
- plan
104
- }));
105
- if (publishResult) {
106
- await onPublishResult(pkg, publishResult);
107
- continue publishLoop;
108
- }
109
- }
110
- await onPublishResult(pkg, {
111
- type: "failed",
112
- error: `There is no plugin to publish package "${pkg.id}", please make sure the package has a supported provider plugin.`
113
- });
114
- }
115
- for (const packagePlan of plan.packages.values()) packagePlan.publishResult ??= { type: "skipped" };
116
- for (const plugin of context.plugins) await handlePluginError(plugin, "afterPublishAll", () => plugin.afterPublishAll?.call(context, { plan }));
117
- }
118
- async function runPreflights(context, plan) {
119
- const promises = [];
120
- for (const [id, packagePlan] of plan.packages) {
121
- const pkg = context.graph.get(id);
122
- packagePlan.preflight = { shouldPublish: false };
123
- if (!packagePlan.updated) continue;
124
- promises.push((async () => {
125
- for (const plugin of context.plugins) {
126
- const res = await handlePluginError(plugin, "publishPreflight", () => plugin.publishPreflight?.call(context, {
127
- pkg,
128
- plan
129
- }));
130
- if (res) {
131
- packagePlan.preflight = res;
132
- break;
133
- }
134
- }
135
- })());
136
- }
137
- await Promise.all(promises);
138
- for (const plugin of context.plugins) await handlePluginError(plugin, "afterPreflight", () => plugin.afterPreflight?.call(context, { plan }));
139
- }
140
- async function publishPlanStatus(plan, context) {
141
- for (const plugin of context.plugins) {
142
- const status = await handlePluginError(plugin, "resolvePlanStatus", () => plugin.resolvePlanStatus?.call(context, { plan }));
143
- if (Array.isArray(status) && await somePromise(status, (v) => v === "pending")) return "pending";
144
- if (status === "pending") return "pending";
145
- }
146
- return "success";
147
- }
148
- //#endregion
149
16
  //#region src/providers/npm/cli.ts
150
17
  const PLACEHOLDER_VERSION = "0.0.0-tegami-trusted-publish-setup";
151
18
  const PLACEHOLDER_DIST_TAG = "temp";
@@ -752,9 +619,10 @@ async function resolveNpmGraph(cwd, client) {
752
619
  if (isNodeError(error) && error.code === "ENOENT") return void 0;
753
620
  throw error;
754
621
  });
755
- const data = content && assertPnpmWorkspace(parse$1(content));
756
- if (data) {
757
- catalogSources.push(createPnpmCatalogSource(pnpmWorkspacePath, data));
622
+ if (content) {
623
+ const doc = parseDocument(content);
624
+ const data = assertPnpmWorkspace(doc.toJSON());
625
+ catalogSources.push(createPnpmCatalogSource(pnpmWorkspacePath, doc));
758
626
  patterns.push(...data.packages ?? []);
759
627
  }
760
628
  } else if (client === "yarn") {
@@ -846,24 +714,26 @@ async function readManifest(packagePath) {
846
714
  assertPackageManifest(parsed);
847
715
  return parsed;
848
716
  }
849
- function createPnpmCatalogSource(filePath, workspace) {
717
+ function createPnpmCatalogSource(filePath, doc) {
850
718
  return {
851
719
  resolve(name, catalogName) {
852
- if (catalogName === "default") return workspace.catalog?.[name];
853
- return workspace.catalogs?.[catalogName]?.[name];
720
+ const value = doc.getIn(catalogName === "default" ? ["catalog", name] : [
721
+ "catalogs",
722
+ catalogName,
723
+ name
724
+ ]);
725
+ return typeof value === "string" ? value : void 0;
854
726
  },
855
727
  setRange(name, catalogName, range) {
856
- if (catalogName === "default") {
857
- workspace.catalog ??= {};
858
- workspace.catalog[name] = range;
859
- } else {
860
- workspace.catalogs ??= {};
861
- workspace.catalogs[catalogName] ??= {};
862
- workspace.catalogs[catalogName][name] = range;
863
- }
728
+ doc.setIn(catalogName === "default" ? ["catalog", name] : [
729
+ "catalogs",
730
+ catalogName,
731
+ name
732
+ ], range);
864
733
  },
865
734
  async write() {
866
- await writeFile(filePath, `${stringify(workspace, { lineWidth: 0 }).trim()}\n`);
735
+ const output = doc.toString();
736
+ await writeFile(filePath, output.endsWith("\n") ? output : `${output}\n`);
867
737
  }
868
738
  };
869
739
  }
@@ -1035,8 +905,13 @@ function npm({ client: defaultClient, onBreakPeerDep = "set", updateLockFile = t
1035
905
  active = true;
1036
906
  },
1037
907
  async publishPreflight({ pkg }) {
1038
- if (!(pkg instanceof NpmPackage)) return;
1039
- return { shouldPublish: pkg.version !== void 0 && pkg.manifest.private !== true };
908
+ if (!(pkg instanceof NpmPackage) || !this.npm?.graph) return;
909
+ const optionalWait = [];
910
+ for (const { linked } of pkg.listDependencies(this.npm.graph)) if (linked) optionalWait.push(linked.id);
911
+ return {
912
+ shouldPublish: pkg.version !== void 0 && pkg.manifest.private !== true,
913
+ optionalWait: optionalWait.length > 0 ? optionalWait : void 0
914
+ };
1040
915
  },
1041
916
  resolvePlanStatus({ plan }) {
1042
917
  if (!active) return;
@@ -1110,8 +985,8 @@ function npm({ client: defaultClient, onBreakPeerDep = "set", updateLockFile = t
1110
985
  }
1111
986
  for (const pkg of npmGraph.packages.values()) {
1112
987
  for (const dep of pkg.listDependencies(npmGraph)) {
1113
- if (!dep.linked || !dep.range || !dep.setRange) continue;
1114
- if (!dep.linked.version || semver$1.satisfies(dep.linked.version, dep.range)) continue;
988
+ if (!dep.linked?.version || !dep.range || !dep.setRange) continue;
989
+ if (semver$1.satisfies(dep.linked.version, dep.range, { includePrerelease: dep.spec.protocol === "workspace" })) continue;
1115
990
  const isPeer = dep.field === "peerDependencies";
1116
991
  if (isPeer && onBreakPeerDep === "ignore") continue;
1117
992
  let updatedRange;
@@ -1164,7 +1039,7 @@ function depsPolicy(context, getBumpDepType) {
1164
1039
  case "":
1165
1040
  case "*": return true;
1166
1041
  case "^":
1167
- case "~": return !semver$1.satisfies(target, `${resolved.spec.range}${resolved.linked.version ?? "0.0.0"}`);
1042
+ case "~": return !semver$1.satisfies(target, `${resolved.spec.range}${resolved.linked.version ?? "0.0.0"}`, { includePrerelease: true });
1168
1043
  }
1169
1044
  }
1170
1045
  if (!resolved.range || !semver$1.validRange(resolved.range)) return false;
@@ -1249,4 +1124,4 @@ async function isPackagePublished(name, version, registry) {
1249
1124
  return true;
1250
1125
  }
1251
1126
  //#endregion
1252
- export { runPreflights as a, publishPlanStatus as i, NpmPackage as n, runPublishPlan as o, initPublishPlan as r, npm as t };
1127
+ export { NpmPackage as n, npm as t };
@@ -1,2 +1,2 @@
1
- import { D as cargo, E as CargoPluginOptions, T as CargoPackage, w as CargoGraph } from "../types-B50RK1rR.js";
1
+ import { D as cargo, E as CargoPluginOptions, T as CargoPackage, w as CargoGraph } from "../types-BbwOrNZ2.js";
2
2
  export { CargoGraph, CargoPackage, CargoPluginOptions, cargo };
@@ -1,4 +1,4 @@
1
- import { s as TegamiPlugin } from "../types-B50RK1rR.js";
1
+ import { s as TegamiPlugin } from "../types-BbwOrNZ2.js";
2
2
 
3
3
  //#region src/plugins/git.d.ts
4
4
  interface GitPluginOptions {
@@ -1,5 +1,6 @@
1
- import { A as WorkspacePackage, b as TegamiContext, j as Draft, s as TegamiPlugin, t as Awaitable, v as PublishPlan } from "../types-B50RK1rR.js";
1
+ import { A as WorkspacePackage, b as TegamiContext, s as TegamiPlugin, t as Awaitable, v as PublishPlan } from "../types-BbwOrNZ2.js";
2
2
  import { GitPluginOptions } from "./git.js";
3
+ import { t as VersionRequestOptions } from "../version-request-C24d9RIW.js";
3
4
 
4
5
  //#region src/plugins/github.d.ts
5
6
  interface GithubRelease {
@@ -10,36 +11,6 @@ interface GithubRelease {
10
11
  /** Whether to mark release as prerelease */
11
12
  prerelease?: boolean;
12
13
  }
13
- interface VersionPullRequest {
14
- /** Pull request title. */
15
- title?: string;
16
- /** Pull request body. */
17
- body?: string;
18
- }
19
- interface VersionPullRequestOptions {
20
- /**
21
- * Create the PR even outside of CI.
22
- *
23
- * @default false
24
- */
25
- forceCreate?: boolean;
26
- /**
27
- * Pull request branch.
28
- *
29
- * @default "tegami/version-packages"
30
- */
31
- branch?: string;
32
- /**
33
- * Pull request base branch.
34
- *
35
- * @default "main"
36
- */
37
- base?: string;
38
- /** Override details for "Version Packages" PR. */
39
- create?: (this: TegamiContext, opts: {
40
- draft: Draft;
41
- }) => Awaitable<VersionPullRequest>;
42
- }
43
14
  /** Options for creating GitHub releases after a successful publish. */
44
15
  interface GitHubPluginOptions extends GitPluginOptions {
45
16
  /** GitHub repository. */
@@ -74,7 +45,7 @@ interface GitHubPluginOptions extends GitPluginOptions {
74
45
  *
75
46
  * Defaults to enabled in CI and disabled locally.
76
47
  */
77
- versionPr?: VersionPullRequestOptions | false;
48
+ versionPr?: VersionRequestOptions | false;
78
49
  }
79
50
  /** Create GitHub releases for successfully published packages after the whole plan succeeds. */
80
51
  declare function github(options?: GitHubPluginOptions): TegamiPlugin[];
@@ -1,9 +1,9 @@
1
1
  import { i as formatPackageVersion, r as formatNpmDistTag } from "../semver-EKJ8yK5U.js";
2
2
  import { t as changelogFilename } from "../generate-Bg86OJP4.js";
3
3
  import { a as cached, n as execFailure, o as isCI } from "../error-BhMYq9iW.js";
4
- import { o as readChangelogEntries, t as createDraft } from "../draft-CzUiQasJ.js";
4
+ import { a as createDraft, l as readChangelogEntries } from "../publish-v30y8Lwq.js";
5
5
  import { git } from "./git.js";
6
- import { n as createVersionRequestBody, r as hasGitChanges, t as commitVersionBranchChanges } from "../version-request-oxy16TJ1.js";
6
+ import { t as onVersionRequest } from "../version-request-l6IJdFM6.js";
7
7
  import { readFile, writeFile } from "node:fs/promises";
8
8
  import { basename, join, relative, resolve } from "node:path";
9
9
  import { x } from "tinyexec";
@@ -346,8 +346,32 @@ function github(options = {}) {
346
346
  function getRenderer(context) {
347
347
  return renderer ??= createChangelogRenderer(context);
348
348
  }
349
- const cliSnapshots = /* @__PURE__ */ new Map();
350
- return [git(options), {
349
+ const versionRequests = onVersionRequest({
350
+ name: "github",
351
+ options: options.versionPr,
352
+ canCreate(context) {
353
+ const { repo, token } = context.github ?? {};
354
+ return Boolean(repo && token);
355
+ },
356
+ async upsert(context, request, update) {
357
+ const { repo, token } = context.github;
358
+ const openPr = await findOpenPullRequest(repo, request.head, token);
359
+ if (openPr === void 0) await createPullRequest(repo, {
360
+ title: request.title,
361
+ body: request.body,
362
+ head: request.head,
363
+ base: request.base,
364
+ token
365
+ });
366
+ else if (update) await updatePullRequest(repo, openPr, {
367
+ title: request.title,
368
+ body: request.body,
369
+ token
370
+ });
371
+ }
372
+ });
373
+ const plugin = {
374
+ ...versionRequests,
351
375
  name: "github",
352
376
  init() {
353
377
  this.github = {
@@ -356,6 +380,7 @@ function github(options = {}) {
356
380
  };
357
381
  },
358
382
  async resolvePlanStatus({ plan }) {
383
+ if (versionRequests.resolvePlanStatus.call(this, { plan }) === "pending") return "pending";
359
384
  const { repo, token } = this.github;
360
385
  if (!repo || !token || releaseOptions === false) return;
361
386
  const requiredTags = /* @__PURE__ */ new Set();
@@ -428,41 +453,9 @@ function github(options = {}) {
428
453
  `https://x-access-token:${token}@github.com/${repo}.git`
429
454
  ], { nodeOptions: { cwd: this.cwd } });
430
455
  if (result.exitCode !== 0) throw execFailure("Failed to configure git remote for GitHub Actions.", result);
431
- },
432
- initCliDraft() {
433
- for (const pkg of this.graph.getPackages()) cliSnapshots.set(pkg.id, pkg.version);
434
- },
435
- async applyCliDraft(draft) {
436
- const config = options.versionPr ?? {};
437
- if (config === false || !(config.forceCreate || isCI()) || !await hasGitChanges(this.cwd)) return;
438
- const repo = this.github?.repo;
439
- const { branch = "tegami/version-packages", base = "main" } = config;
440
- const basePR = await config.create?.call(this, { draft });
441
- const pr = {
442
- title: basePR?.title ?? "Version Packages",
443
- body: basePR?.body ?? createVersionRequestBody(draft, this, cliSnapshots, "Merge this PR to publish the versioned packages.")
444
- };
445
- await commitVersionBranchChanges(this.cwd, branch, pr.title);
446
- const token = this.github?.token;
447
- if (!repo) return;
448
- const openPr = await findOpenPullRequest(repo, branch, token);
449
- if (openPr !== void 0) {
450
- await updatePullRequest(repo, openPr, {
451
- title: pr.title,
452
- body: pr.body,
453
- token
454
- });
455
- return;
456
- }
457
- await createPullRequest(repo, {
458
- title: pr.title,
459
- body: pr.body,
460
- head: branch,
461
- base,
462
- token
463
- });
464
456
  }
465
- }];
457
+ };
458
+ return [git(options), plugin];
466
459
  }
467
460
  function createChangelogRenderer(context) {
468
461
  const { repo, token } = context.github;
@@ -1,5 +1,6 @@
1
- import { A as WorkspacePackage, b as TegamiContext, j as Draft, s as TegamiPlugin, t as Awaitable, v as PublishPlan } from "../types-B50RK1rR.js";
1
+ import { A as WorkspacePackage, b as TegamiContext, s as TegamiPlugin, t as Awaitable, v as PublishPlan } from "../types-BbwOrNZ2.js";
2
2
  import { GitPluginOptions } from "./git.js";
3
+ import { t as VersionRequestOptions } from "../version-request-C24d9RIW.js";
3
4
 
4
5
  //#region src/plugins/gitlab.d.ts
5
6
  interface GitlabRelease {
@@ -8,36 +9,6 @@ interface GitlabRelease {
8
9
  /** Release notes */
9
10
  notes?: string;
10
11
  }
11
- interface VersionMergeRequest {
12
- /** Merge request title. */
13
- title?: string;
14
- /** Merge request body. */
15
- body?: string;
16
- }
17
- interface VersionMergeRequestOptions {
18
- /**
19
- * Create the MR even outside of CI.
20
- *
21
- * @default false
22
- */
23
- forceCreate?: boolean;
24
- /**
25
- * Merge request branch.
26
- *
27
- * @default "tegami/version-packages"
28
- */
29
- branch?: string;
30
- /**
31
- * Merge request base branch.
32
- *
33
- * @default "main"
34
- */
35
- base?: string;
36
- /** Override details for "Version Packages" MR. */
37
- create?: (this: TegamiContext, opts: {
38
- draft: Draft;
39
- }) => Awaitable<VersionMergeRequest>;
40
- }
41
12
  /** Options for creating GitLab releases after a successful publish. */
42
13
  interface GitLabPluginOptions extends GitPluginOptions {
43
14
  /** GitLab repository. */
@@ -76,7 +47,7 @@ interface GitLabPluginOptions extends GitPluginOptions {
76
47
  *
77
48
  * Defaults to enabled in CI and disabled locally.
78
49
  */
79
- versionMr?: VersionMergeRequestOptions | false;
50
+ versionMr?: VersionRequestOptions | false;
80
51
  }
81
52
  /** Create GitLab releases for successfully published packages after the whole plan succeeds. */
82
53
  declare function gitlab(options?: GitLabPluginOptions): TegamiPlugin[];