tegami 0.2.1 → 1.0.0-beta.1

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,5 @@
1
- import { O as Draft, S as PublishPlan, g as Tegami, t as Awaitable } from "../types-DEaKjB3O.js";
1
+ import { p as PublishPlan, t as Awaitable, w as Draft } from "../types-BbDtPn8I.js";
2
+ import { n as Tegami } from "../index-CH40idD8.js";
2
3
  import { Command } from "commander";
3
4
 
4
5
  //#region src/cli/index.d.ts
package/dist/cli/index.js CHANGED
@@ -1,9 +1,9 @@
1
- import { r as formatNpmDistTag } from "../semver-C4vJ4SK8.js";
2
- import { a as renderChangelog, n as generateFromCommits, r as generateReplays, t as changelogFilename } from "../generate-L7ucD7ic.js";
1
+ import { r as formatNpmDistTag } from "../semver-EKJ8yK5U.js";
2
+ import { i as renderChangelog, n as generateFromCommits, t as changelogFilename } from "../generate-BqkwhjRy.js";
3
3
  import { a as isCI, n as execFailure, r as handlePluginError, t as CancelledError } from "../error-DNy8R5ue.js";
4
4
  import { c as updateIssueComment, i as findIssueCommentByPrefix, o as getPullRequest, t as createIssueComment } from "../api-D-jf_8xY.js";
5
5
  import { mkdir, readFile, writeFile } from "node:fs/promises";
6
- import path, { basename, isAbsolute, join, normalize, relative } from "node:path";
6
+ import path, { basename, join, relative } from "node:path";
7
7
  import { x } from "tinyexec";
8
8
  import z from "zod";
9
9
  import { resolveCommand } from "package-manager-detector";
@@ -15,35 +15,32 @@ async function getChangedPackages(graph, cwd) {
15
15
  }
16
16
  async function getChangedFilePaths(cwd) {
17
17
  const files = /* @__PURE__ */ new Set();
18
- for (const args of [["diff", "--name-only"], [
18
+ await Promise.all([["diff", "--name-only"], [
19
19
  "diff",
20
20
  "--cached",
21
21
  "--name-only"
22
- ]]) await addGitOutput(files, cwd, args);
22
+ ]].map(async (args) => {
23
+ const result = await x("git", args, { nodeOptions: { cwd } });
24
+ if (result.exitCode !== 0) return;
25
+ for (const line of result.stdout.split("\n")) {
26
+ const trimmed = line.trim();
27
+ if (trimmed) files.add(trimmed);
28
+ }
29
+ }));
23
30
  return Array.from(files);
24
31
  }
25
32
  function resolveChangedPackages(graph, files, cwd) {
26
33
  const packages = [...graph.getPackages()].sort((a, b) => b.path.length - a.path.length);
27
34
  const matched = /* @__PURE__ */ new Map();
28
- for (const file of files) for (const pkg of packages) if (isUnderDir(file, pkg.path, cwd)) {
29
- matched.set(pkg.id, pkg);
30
- break;
35
+ for (const file of files) {
36
+ const fullPath = join(cwd, file);
37
+ for (const pkg of packages) if (!relative(pkg.path, fullPath).startsWith("..")) {
38
+ matched.set(pkg.id, pkg);
39
+ break;
40
+ }
31
41
  }
32
42
  return [...matched.values()];
33
43
  }
34
- function isUnderDir(file, dir, cwd) {
35
- const absolute = join(cwd, file);
36
- const rel = relative(normalize(dir), absolute);
37
- return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
38
- }
39
- async function addGitOutput(files, cwd, args) {
40
- const result = await x("git", args, { nodeOptions: { cwd } });
41
- if (result.exitCode !== 0) return;
42
- for (const line of result.stdout.split("\n")) {
43
- const trimmed = line.trim();
44
- if (trimmed) files.add(trimmed);
45
- }
46
- }
47
44
  //#endregion
48
45
  //#region src/cli/changelog.ts
49
46
  async function runChangelogTui(tegami) {
@@ -81,11 +78,10 @@ async function runChangelogTui(tegami) {
81
78
  }
82
79
  });
83
80
  if (isCancel(message)) throw new CancelledError();
84
- const packages = generateReplays(context.graph, packageBumpMap);
85
81
  await persistChangelogs(context, [{
86
82
  filename: changelogFilename(),
87
- content: renderChangelog({ packages }, `## ${message.trim()}`),
88
- packages
83
+ content: renderChangelog({ packages: packageBumpMap }, `## ${message.trim()}`),
84
+ packages: packageBumpMap
89
85
  }]);
90
86
  }
91
87
  async function persistChangelogs(context, entries, emptyMessage = "No changelogs created.") {
@@ -291,12 +287,14 @@ async function buildPrPreview(context, draft, options = {}) {
291
287
  const pendingPackages = [];
292
288
  for (const pkg of context.graph.getPackages()) {
293
289
  const plan = draft.getPackageDraft(pkg.id);
294
- if (!plan || plan.bumpVersion(pkg) === pkg.version) continue;
290
+ if (!plan) continue;
291
+ const bumped = plan.bumpVersion(pkg);
292
+ if (!bumped || !pkg.version || bumped === pkg.version) continue;
295
293
  pendingPackages.push({
296
294
  name: pkg.name,
297
295
  type: plan.type ?? "—",
298
296
  from: pkg.version,
299
- to: plan.bumpVersion(pkg),
297
+ to: bumped,
300
298
  distTag: plan.npm?.distTag
301
299
  });
302
300
  }
@@ -307,11 +305,8 @@ async function buildPrPreview(context, draft, options = {}) {
307
305
  lines.push("");
308
306
  }
309
307
  if (prChangelogs.length > 0) {
310
- lines.push("#### Changelogs in this PR", "");
311
- for (const entry of prChangelogs) {
312
- const title = entry.sections[0]?.title ?? entry.filename;
313
- lines.push(`- \`${entry.filename}\` — ${title}`);
314
- }
308
+ lines.push("#### Changelogs in this PR", "", "| Changelog | Title |", "| --- | --- |");
309
+ for (const entry of prChangelogs) for (const section of entry.sections) lines.push(`| \`${entry.filename}\` | ${section.title} |`);
315
310
  lines.push("");
316
311
  } else if (pendingPackages.length === 0) lines.push("#### No changelogs yet", "", "This PR has no pending changelog files. If your changes require a release, add a changelog before merging.", "");
317
312
  else if (prChangelogFiles.size === 0) lines.push("This PR does not add changelog files. Pending changelogs from other branches are included in the preview above.", "");
@@ -511,8 +506,10 @@ async function versionPackages(tegami, options) {
511
506
  const lines = [];
512
507
  for (const pkg of context.graph.getPackages()) {
513
508
  const plan = draft.getPackageDraft(pkg.id);
514
- if (!plan || plan.bumpVersion(pkg) === pkg.version) continue;
515
- lines.push(`${pkg.id}: ${pkg.version} ${plan.bumpVersion(pkg)} (${plan.changelogs?.length ?? 0} changelogs)`);
509
+ if (!plan) continue;
510
+ const bumped = plan.bumpVersion(pkg);
511
+ if (!pkg.version || !bumped || bumped === pkg.version) continue;
512
+ lines.push(`${pkg.id}: ${pkg.version} → ${bumped} (${plan.changelogs?.length ?? 0} changelogs)`);
516
513
  if (plan.bumpReasons) for (const reason of plan.bumpReasons) lines.push(` - ${reason}`);
517
514
  }
518
515
  note(lines.join("\n"), "Release plan");
@@ -1,8 +1,6 @@
1
- import { a as maxBump, t as bumpDepth } from "./semver-C4vJ4SK8.js";
1
+ import { a as maxBump, t as bumpDepth } from "./semver-EKJ8yK5U.js";
2
2
  import { n as execFailure } from "./error-DNy8R5ue.js";
3
- import { t as bumpTypeSchema } from "./schemas-BdUlXfSu.js";
4
3
  import { x } from "tinyexec";
5
- import * as semver from "semver";
6
4
  import z from "zod";
7
5
  import { dump } from "js-yaml";
8
6
  //#region src/utils/conventional-commit.ts
@@ -71,6 +69,11 @@ function conventionalCommitToBump(type, breaking) {
71
69
  }
72
70
  //#endregion
73
71
  //#region src/changelog/shared.ts
72
+ const bumpTypeSchema = z.enum([
73
+ "major",
74
+ "minor",
75
+ "patch"
76
+ ]);
74
77
  const changelogPackageConfigSchema = z.object({
75
78
  type: bumpTypeSchema.optional(),
76
79
  replay: z.array(z.string().min(1)).optional()
@@ -109,8 +112,7 @@ async function generateFromCommits(context, { from, to } = {}) {
109
112
  let bumpType = "patch";
110
113
  for (const change of changes) bumpType = maxBump(change.type, bumpType);
111
114
  const packageBumpMap = Object.fromEntries(packageNames.map((name) => [name, bumpType]));
112
- const packages = generateReplays(context.graph, packageBumpMap);
113
- const content = renderChangelog({ packages }, changes.map((change) => {
115
+ const content = renderChangelog({ packages: packageBumpMap }, changes.map((change) => {
114
116
  const heading = "#".repeat(bumpDepth(change.type));
115
117
  if (!change.body) return `${heading} ${change.title}`;
116
118
  return `${heading} ${change.title}\n\n${change.body}`;
@@ -118,7 +120,7 @@ async function generateFromCommits(context, { from, to } = {}) {
118
120
  return {
119
121
  filename: changelogFilename(index),
120
122
  content,
121
- packages,
123
+ packages: packageBumpMap,
122
124
  changes
123
125
  };
124
126
  });
@@ -164,26 +166,9 @@ async function latestTag(cwd) {
164
166
  if (result.exitCode !== 0) return;
165
167
  return result.stdout.trim() || void 0;
166
168
  }
167
- function generateReplays(graph, base) {
168
- const packages = { ...base };
169
- for (const [ref, type] of Object.entries(base)) {
170
- const resolved = graph.getByName(ref);
171
- for (const pkg of resolved) {
172
- const plan = pkg.initDraft();
173
- pkg.configureDraft(plan, graph.getPackageGroup(pkg.id));
174
- const prerelease = semver.prerelease(pkg.version)?.[0];
175
- const targetPrerelease = plan.prerelease;
176
- if (targetPrerelease && !prerelease || targetPrerelease && prerelease && targetPrerelease === prerelease) packages[pkg.id] = {
177
- type,
178
- replay: [`exit prerelease: ${pkg.name}`]
179
- };
180
- }
181
- }
182
- return packages;
183
- }
184
169
  function changelogFilename(disambiguator = 0) {
185
170
  const date = /* @__PURE__ */ new Date();
186
171
  return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}-${(Date.now() + disambiguator).toString(36)}.md`;
187
172
  }
188
173
  //#endregion
189
- export { renderChangelog as a, changelogFrontmatterSchema as i, generateFromCommits as n, generateReplays as r, changelogFilename as t };
174
+ export { renderChangelog as i, generateFromCommits as n, changelogFrontmatterSchema as r, changelogFilename as t };
@@ -1,4 +1,4 @@
1
- import { r as LogGenerator } from "../types-DEaKjB3O.js";
1
+ import { r as LogGenerator } from "../types-BbDtPn8I.js";
2
2
 
3
3
  //#region src/generators/simple.d.ts
4
4
  declare function simpleGenerator(): LogGenerator;
@@ -1,4 +1,4 @@
1
- import { i as formatPackageVersion } from "../semver-C4vJ4SK8.js";
1
+ import { i as formatPackageVersion } from "../semver-EKJ8yK5U.js";
2
2
  //#region src/generators/simple.ts
3
3
  function simpleGenerator() {
4
4
  return { generate({ pkg, packageDraft }) {
@@ -1,4 +1,4 @@
1
- import { n as bumpVersion } from "./semver-C4vJ4SK8.js";
1
+ import { n as bumpVersion } from "./semver-EKJ8yK5U.js";
2
2
  //#region src/graph.ts
3
3
  /** Package discovered in the workspace. */
4
4
  var WorkspacePackage = class {
@@ -16,18 +16,14 @@ var WorkspacePackage = class {
16
16
  /** create the initial draft. */
17
17
  initDraft() {
18
18
  return { bumpVersion(pkg) {
19
+ if (!pkg.version) return;
19
20
  return bumpVersion(pkg.version, this.type, this.prerelease);
20
21
  } };
21
22
  }
22
23
  /** configure an initial draft to match script-level configs. */
23
24
  configureDraft(draft, group) {
24
- const groupOptions = group?.options;
25
- const { prerelease = groupOptions?.prerelease, npm: { distTag = groupOptions?.npm?.distTag } = {} } = this.opts;
25
+ const { prerelease = group?.options?.prerelease } = this.opts;
26
26
  if (prerelease !== void 0) draft.prerelease = prerelease;
27
- if (distTag) {
28
- draft.npm ??= {};
29
- draft.npm.distTag = distTag;
30
- }
31
27
  }
32
28
  };
33
29
  /** Dependency graph for discovered workspace packages. */
@@ -0,0 +1,64 @@
1
+ import { D as ChangelogPackageConfig, O as BumpType, b as TegamiContext, f as PublishOptions, o as TegamiOptions, p as PublishPlan, w as Draft, x as PackageGraph } from "./types-BbDtPn8I.js";
2
+
3
+ //#region src/changelog/generate.d.ts
4
+ interface GenerateFromCommitsOptions {
5
+ /** Start revision. Defaults to the latest reachable git tag, or all history if none exists. */
6
+ from?: string;
7
+ /** End revision. Defaults to HEAD. */
8
+ to?: string;
9
+ }
10
+ interface CommitChangelog {
11
+ filename: string;
12
+ content: string;
13
+ packages: Record<string, BumpType | ChangelogPackageConfig>;
14
+ changes: CommitChange[];
15
+ }
16
+ interface CommitChange {
17
+ hash: string;
18
+ subject: string;
19
+ body: string;
20
+ packages: string[];
21
+ type: BumpType;
22
+ title: string;
23
+ }
24
+ //#endregion
25
+ //#region src/index.d.ts
26
+ interface GenerateChangelogOptions extends GenerateFromCommitsOptions {
27
+ /**
28
+ * Write changelog files to disk.
29
+ *
30
+ * @default true
31
+ */
32
+ write?: boolean;
33
+ }
34
+ interface Tegami {
35
+ /** Create pending changelog files from git commit history. */
36
+ generateChangelog(options?: GenerateChangelogOptions): Promise<CommitChangelog[]>;
37
+ /** Build a draft from pending changelog files. */
38
+ draft(): Promise<Draft>;
39
+ /** Publish packages from the publish lock. */
40
+ publish(options?: PublishOptions): Promise<PublishPlan | "skipped">;
41
+ /**
42
+ * Check publish status.
43
+ *
44
+ * Prefer `publish()` over this if you are publishing packages, it will also check the publish status.
45
+ */
46
+ publishStatus(): Promise<"pending" | "success" | "idle">;
47
+ /** Remove the publish lock file after publishing has finished successfully. */
48
+ cleanup(): Promise<{
49
+ state: "removed";
50
+ } | {
51
+ state: "skipped";
52
+ reason: "no-plan" | "pending";
53
+ }>;
54
+ /** Internal APIs, do not use it unless you know what you are doing */
55
+ _internal: {
56
+ context(): Promise<TegamiContext>;
57
+ graph(): Promise<PackageGraph>;
58
+ options: TegamiOptions;
59
+ };
60
+ }
61
+ /** Create a Tegami project handle. */
62
+ declare function tegami<const Groups extends string = string>(options?: TegamiOptions<Groups>): Tegami;
63
+ //#endregion
64
+ export { CommitChangelog as i, Tegami as n, tegami as r, GenerateChangelogOptions as t };
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
- import { A as PackageDraft, C as CommitChangelog, D as WorkspacePackage, E as PackageGroup, O as Draft, S as PublishPlan, T as PackageGraph, _ as tegami, a as PublishPreflight, b as PackagePublishResult, c as TegamiPluginOption, g as Tegami, h as GenerateChangelogOptions, i as PackageOptions, k as DraftPolicy, n as GroupOptions, o as TegamiOptions, r as LogGenerator, s as TegamiPlugin, v as PublishLock, x as PublishOptions, y as PackagePublishPlan } from "./types-DEaKjB3O.js";
1
+ import { C as WorkspacePackage, E as PackageDraft, S as PackageGroup, T as DraftPolicy, a as PublishPreflight, c as TegamiPluginOption, d as PackagePublishResult, f as PublishOptions, i as PackageOptions, l as PublishLock, n as GroupOptions, o as TegamiOptions, p as PublishPlan, r as LogGenerator, s as TegamiPlugin, u as PackagePublishPlan, w as Draft, x as PackageGraph } from "./types-BbDtPn8I.js";
2
+ import { i as CommitChangelog, n as Tegami, r as tegami, t as GenerateChangelogOptions } from "./index-CH40idD8.js";
2
3
  export { type CommitChangelog, type Draft, type DraftPolicy, GenerateChangelogOptions, type GroupOptions, type LogGenerator, type PackageDraft, type PackageGraph, type PackageGroup, type PackageOptions, type PackagePublishPlan, type PackagePublishResult, type PublishLock, type PublishOptions, type PublishPlan, type PublishPreflight, Tegami, type TegamiOptions, type TegamiPlugin, type TegamiPluginOption, type WorkspacePackage, tegami };
package/dist/index.js CHANGED
@@ -1,13 +1,13 @@
1
- import { a as maxBump } from "./semver-C4vJ4SK8.js";
2
- import { i as changelogFrontmatterSchema, n as generateFromCommits } from "./generate-L7ucD7ic.js";
1
+ import { a as maxBump } from "./semver-EKJ8yK5U.js";
2
+ import { n as generateFromCommits, r as changelogFrontmatterSchema } from "./generate-BqkwhjRy.js";
3
3
  import { r as handlePluginError } from "./error-DNy8R5ue.js";
4
- import { t as PackageGraph } from "./graph-DrzluXw8.js";
4
+ import { t as PackageGraph } from "./graph-gThXu8Cz.js";
5
5
  import { cargo } from "./providers/cargo.js";
6
- import { npm } from "./providers/npm.js";
6
+ import { n as npm } from "./npm-DqGyAsdo.js";
7
7
  import { simpleGenerator } from "./generators/simple.js";
8
8
  import fs, { mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
9
9
  import path, { basename, dirname, join } from "node:path";
10
- import * as semver from "semver";
10
+ import * as semver$1 from "semver";
11
11
  import z from "zod";
12
12
  import { dump, load, visit } from "js-yaml";
13
13
  import { fromMarkdown } from "mdast-util-from-markdown";
@@ -36,12 +36,18 @@ async function createTegamiContext(options = {}) {
36
36
  return (pkg) => pkg.name === pattern || pkg.id === pattern;
37
37
  });
38
38
  for (const [name, groupOptions] of Object.entries(options.groups ?? {})) graph.registerGroup(name, groupOptions);
39
+ let getPackageOptions;
40
+ if (typeof options.packages === "function") getPackageOptions = options.packages;
41
+ else if (options.packages) {
42
+ const packages = options.packages;
43
+ getPackageOptions = (pkg) => packages[pkg.id] ?? packages[pkg.name];
44
+ }
39
45
  for (const pkg of graph.getPackages()) {
40
- if (ignoreMatchers?.length && ignoreMatchers.some((matcher) => matcher(pkg))) {
46
+ if (ignoreMatchers && ignoreMatchers.some((matcher) => matcher(pkg))) {
41
47
  graph.delete(pkg.id);
42
48
  continue;
43
49
  }
44
- const packageOptions = options.packages?.[pkg.id] ?? options.packages?.[pkg.name];
50
+ const packageOptions = getPackageOptions?.(pkg);
45
51
  if (!packageOptions) continue;
46
52
  pkg.setPackageOptions(packageOptions);
47
53
  if (packageOptions.group) graph.addGroupMember(packageOptions.group, pkg.id);
@@ -329,6 +335,7 @@ var Draft = class {
329
335
  }
330
336
  return false;
331
337
  }
338
+ /** get all changelogs, note that this includes replay-only changelogs, as long as they are in the `.tegami` folder. */
332
339
  getChangelogs() {
333
340
  return Array.from(this.changelogs.values());
334
341
  }
@@ -375,20 +382,23 @@ var Draft = class {
375
382
  /** write persistent data to publish lock */
376
383
  async writeLockFile(snapshots) {
377
384
  const lock = new PublishLock();
378
- for (const entry of this.getChangelogs()) lock.write("core:changelogs", {
379
- v: "0.0.0",
380
- filename: entry.filename,
381
- content: entry.getRawContent()
382
- });
385
+ const changelogs = /* @__PURE__ */ new Set();
383
386
  for (const pkg of this.context.graph.getPackages()) {
384
387
  const draft = this.getPackageDraft(pkg.id);
385
388
  const snapshot = snapshots.get(pkg.id);
389
+ if (!snapshot) continue;
390
+ for (const entry of draft?.changelogs ?? []) changelogs.add(entry);
386
391
  lock.write("core:packages", {
387
392
  id: pkg.id,
388
- updated: draft !== void 0 && (snapshot === void 0 || snapshot.version !== pkg.version),
393
+ updated: draft !== void 0 && snapshot.version !== pkg.version,
389
394
  changelogIds: draft?.changelogs?.map((entry) => entry.id)
390
395
  });
391
396
  }
397
+ for (const entry of changelogs) lock.write("core:changelogs", {
398
+ v: "0.0.0",
399
+ filename: entry.filename,
400
+ content: entry.getRawContent()
401
+ });
392
402
  for (const plugin of this.context.plugins) await handlePluginError(plugin, "initPublishLock", () => plugin.initPublishLock?.call(this.context, {
393
403
  lock,
394
404
  draft: this
@@ -410,10 +420,15 @@ var Draft = class {
410
420
  applyReplays(snapshots) {
411
421
  const updated = /* @__PURE__ */ new Map();
412
422
  const { graph } = this.context;
423
+ const defaultReplays = (name) => {
424
+ const replay = [];
425
+ for (const pkg of graph.getByName(name)) if (this.packages.get(pkg.id)?.prerelease) replay.push(`exit prerelease: ${pkg.id}`);
426
+ return replay;
427
+ };
413
428
  const isMatch = (condition) => {
414
429
  if (condition.type === "on-exit-prerelease") return graph.getByName(condition.name).some((pkg) => {
415
430
  const previous = snapshots.get(pkg.id);
416
- return previous && semver.inc(previous.version, "release") === pkg.version;
431
+ return previous?.version && semver$1.inc(previous.version, "release") === pkg.version;
417
432
  });
418
433
  return graph.getByName(condition.name).some((pkg) => pkg.version === condition.version);
419
434
  };
@@ -421,8 +436,10 @@ var Draft = class {
421
436
  const updatedPackages = /* @__PURE__ */ new Map();
422
437
  const matchedNames = /* @__PURE__ */ new Set();
423
438
  for (const [name, config] of entry.packages) {
424
- if (!config.replay || config.replay.length === 0) continue;
425
- const replay = config.replay.filter((item) => {
439
+ let replay = config.replay;
440
+ if (config.type) replay ??= defaultReplays(name);
441
+ if (!replay || replay.length === 0) continue;
442
+ replay = replay.filter((item) => {
426
443
  const condition = parseReplayCondition(item);
427
444
  if (condition && isMatch(condition)) {
428
445
  matchedNames.add(name);
@@ -545,47 +562,35 @@ async function runPublishPlan(context, plan) {
545
562
  const packagePlan = plan.packages.get(pkg.id);
546
563
  if (!packagePlan) return;
547
564
  packagePlan.publishResult = publishResult;
565
+ if (publishResult.type === "skipped") return;
548
566
  for (const plugin of context.plugins) await handlePluginError(plugin, "afterPublish", () => plugin.afterPublish?.call(context, {
549
567
  pkg,
550
568
  plan
551
569
  }));
552
570
  };
553
- for (const id of resolvePublishTargets(plan)) {
571
+ publishLoop: for (const id of resolvePublishTargets(plan)) {
554
572
  const pkg = context.graph.get(id);
555
573
  if (dryRun) {
556
574
  await onPublishResult(pkg, { type: "published" });
557
575
  continue;
558
576
  }
559
- let isSkipped = false;
560
- for (const plugin of context.plugins) if (await handlePluginError(plugin, "willPublish", () => plugin.willPublish?.call(context, { pkg })) === false) {
561
- isSkipped = true;
562
- break;
563
- }
564
- if (isSkipped) {
565
- await onPublishResult(pkg, { type: "skipped" });
566
- continue;
567
- }
568
- let published = false;
577
+ for (const plugin of context.plugins) if (await handlePluginError(plugin, "willPublish", () => plugin.willPublish?.call(context, { pkg })) === false) continue publishLoop;
569
578
  for (const plugin of context.plugins) {
570
579
  const publishResult = await handlePluginError(plugin, "publish", () => plugin.publish?.call(context, {
571
580
  pkg,
572
581
  plan
573
582
  }));
574
583
  if (publishResult) {
575
- published = true;
576
584
  await onPublishResult(pkg, publishResult);
577
- break;
585
+ continue publishLoop;
578
586
  }
579
587
  }
580
- if (!published) await onPublishResult(pkg, {
588
+ await onPublishResult(pkg, {
581
589
  type: "failed",
582
590
  error: `There is no plugin to publish package "${pkg.id}", please make sure the package has a supported provider plugin.`
583
591
  });
584
592
  }
585
- await Promise.all(Array.from(plan.packages, async ([id, packagePlan]) => {
586
- const pkg = context.graph.get(id);
587
- if (!packagePlan.publishResult) await onPublishResult(pkg, { type: "skipped" });
588
- }));
593
+ for (const packagePlan of plan.packages.values()) packagePlan.publishResult ??= { type: "skipped" };
589
594
  for (const plugin of context.plugins) await handlePluginError(plugin, "afterPublishAll", () => plugin.afterPublishAll?.call(context, { plan }));
590
595
  }
591
596
  async function runPreflights(context, plan) {