tegami 0.2.0 → 0.2.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,4 @@
1
- import { O as Draft, S as PublishPlan, g as Tegami, t as Awaitable } from "../types-CurHqnWl.js";
1
+ import { O as Draft, S as PublishPlan, g as Tegami, t as Awaitable } from "../types-DEaKjB3O.js";
2
2
  import { Command } from "commander";
3
3
 
4
4
  //#region src/cli/index.d.ts
package/dist/cli/index.js CHANGED
@@ -1,5 +1,5 @@
1
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-BMlrn-2e.js";
2
+ import { a as renderChangelog, n as generateFromCommits, r as generateReplays, t as changelogFilename } from "../generate-L7ucD7ic.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";
@@ -503,7 +503,11 @@ async function versionPackages(tegami, options) {
503
503
  outro("No versions changed.");
504
504
  return false;
505
505
  }
506
- if (await tegami.publishStatus() === "pending") throw new Error(`Publish lock at ${context.lockPath} is still pending. Publish it before applying a new draft.`);
506
+ if (await tegami.publishStatus() === "pending") {
507
+ note(`Publish lock at ${context.lockPath} is still pending. Publish it before applying a new draft.`);
508
+ outro("Cannot apply.");
509
+ return false;
510
+ }
507
511
  const lines = [];
508
512
  for (const pkg of context.graph.getPackages()) {
509
513
  const plan = draft.getPackageDraft(pkg.id);
@@ -1,6 +1,6 @@
1
1
  import { a as maxBump, t as bumpDepth } from "./semver-C4vJ4SK8.js";
2
2
  import { n as execFailure } from "./error-DNy8R5ue.js";
3
- import { t as bumpTypeSchema } from "./schemas-B7N6EE2k.js";
3
+ import { t as bumpTypeSchema } from "./schemas-BdUlXfSu.js";
4
4
  import { x } from "tinyexec";
5
5
  import * as semver from "semver";
6
6
  import z from "zod";
@@ -1,4 +1,4 @@
1
- import { r as LogGenerator } from "../types-CurHqnWl.js";
1
+ import { r as LogGenerator } from "../types-DEaKjB3O.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 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-CurHqnWl.js";
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";
2
2
  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,5 +1,5 @@
1
1
  import { a as maxBump } from "./semver-C4vJ4SK8.js";
2
- import { i as changelogFrontmatterSchema, n as generateFromCommits } from "./generate-BMlrn-2e.js";
2
+ import { i as changelogFrontmatterSchema, n as generateFromCommits } from "./generate-L7ucD7ic.js";
3
3
  import { r as handlePluginError } from "./error-DNy8R5ue.js";
4
4
  import { t as PackageGraph } from "./graph-DrzluXw8.js";
5
5
  import { cargo } from "./providers/cargo.js";
@@ -526,7 +526,7 @@ function resolvePublishTargets(plan) {
526
526
  const ordered = [];
527
527
  function scan(id, stack = /* @__PURE__ */ new Set()) {
528
528
  const preflight = plan.packages.get(id)?.preflight;
529
- if (!preflight || preflight.publish === false) return;
529
+ if (!preflight || !preflight.publish) return;
530
530
  if (stack.has(id)) throw new Error(`circular reference of deps: ${[...stack, id].join(" -> ")}`);
531
531
  if (ordered.includes(id)) return;
532
532
  if (preflight.wait) {
@@ -591,14 +591,15 @@ async function runPublishPlan(context, plan) {
591
591
  async function runPreflights(context, plan) {
592
592
  const promises = [];
593
593
  const runPreflight = async (pkg) => {
594
- const out = {};
594
+ const out = { publish: true };
595
595
  for (const plugin of context.plugins) {
596
596
  const res = await handlePluginError(plugin, "publishPreflight", () => plugin.publishPreflight?.call(context, {
597
597
  pkg,
598
598
  plan
599
599
  }));
600
- if (res?.publish !== void 0) out.publish = res.publish;
601
- if (res?.wait) {
600
+ if (res === void 0) continue;
601
+ out.publish = res.publish;
602
+ if (res.wait) {
602
603
  out.wait ??= [];
603
604
  out.wait.push(...res.wait);
604
605
  }
@@ -620,7 +621,7 @@ async function runPreflights(context, plan) {
620
621
  async function publishPlanStatus(plan, context) {
621
622
  for (const pkg of plan.packages.values()) {
622
623
  if (!pkg.preflight) throw new Error("Should perform preflight before checking plan status.");
623
- if (pkg.preflight.publish ?? true) return "pending";
624
+ if (pkg.preflight.publish) return "pending";
624
625
  }
625
626
  try {
626
627
  await Promise.all(context.plugins.map(async (plugin) => {
@@ -1,4 +1,4 @@
1
- import { s as TegamiPlugin } from "../types-CurHqnWl.js";
1
+ import { s as TegamiPlugin } from "../types-DEaKjB3O.js";
2
2
 
3
3
  //#region src/plugins/git.d.ts
4
4
  interface GitPluginOptions {
@@ -9,11 +9,11 @@ import { x } from "tinyexec";
9
9
  */
10
10
  function git(options = {}) {
11
11
  const { createTags = true, pushTags = isCI() } = options;
12
- function getPendingTags(plan) {
12
+ function getPendingTags(plan, filterPackage) {
13
13
  const pendingTags = /* @__PURE__ */ new Set();
14
14
  if ((plan.options.dryRun ?? false) || !createTags) return pendingTags;
15
15
  for (const pkg of plan.packages.values()) {
16
- if (pkg.publishResult.type !== "published") continue;
16
+ if (filterPackage && !filterPackage(pkg)) continue;
17
17
  const tag = pkg.git?.tag;
18
18
  if (tag) pendingTags.add(tag);
19
19
  }
@@ -50,7 +50,7 @@ function git(options = {}) {
50
50
  }
51
51
  },
52
52
  async resolvePlanStatus({ plan }) {
53
- const pendingTags = getPendingTags(plan);
53
+ const pendingTags = getPendingTags(plan, (pkg) => pkg.preflight.publish);
54
54
  if (pendingTags.size === 0) return;
55
55
  try {
56
56
  await Promise.all(Array.from(pendingTags, async (tag) => {
@@ -64,7 +64,7 @@ function git(options = {}) {
64
64
  async afterPublishAll({ plan }) {
65
65
  const { cwd } = this;
66
66
  const createdTags = [];
67
- const pendingTags = getPendingTags(plan);
67
+ const pendingTags = getPendingTags(plan, (pkg) => pkg.publishResult.type === "published");
68
68
  if (pendingTags.size === 0) return;
69
69
  await Promise.all(Array.from(pendingTags, async (tag) => {
70
70
  if (await gitTagExists(cwd, tag)) return;
@@ -1,4 +1,4 @@
1
- import { D as WorkspacePackage, O as Draft, S as PublishPlan, s as TegamiPlugin, t as Awaitable, w as TegamiContext } from "../types-CurHqnWl.js";
1
+ import { D as WorkspacePackage, O as Draft, S as PublishPlan, s as TegamiPlugin, t as Awaitable, w as TegamiContext } from "../types-DEaKjB3O.js";
2
2
  import { GitPluginOptions } from "./git.js";
3
3
 
4
4
  //#region src/plugins/github.d.ts
@@ -61,9 +61,10 @@ function github(options = {}) {
61
61
  async resolvePlanStatus({ plan }) {
62
62
  const { repo, token } = this.github;
63
63
  if (!repo || !token || releaseOptions === false) return;
64
- const tags = groupPackagesByTag(this, plan);
64
+ const requiredTags = /* @__PURE__ */ new Set();
65
+ for (const pkg of plan.packages.values()) if (pkg.preflight.publish && pkg.git) requiredTags.add(pkg.git.tag);
65
66
  try {
66
- await Promise.all(Array.from(tags.keys(), async (tag) => {
67
+ await Promise.all(Array.from(requiredTags, async (tag) => {
67
68
  if (!await releaseExistsByTag(repo, tag, token)) throw "pending";
68
69
  }));
69
70
  } catch (e) {
@@ -75,10 +76,17 @@ function github(options = {}) {
75
76
  const { repo, token } = this.github;
76
77
  if (!repo || !token || releaseOptions === false) return;
77
78
  const { eager = false, create, createGrouped } = releaseOptions === true ? {} : releaseOptions;
78
- if (!eager) {
79
- for (const pkg of plan.packages.values()) if (pkg.publishResult.type === "failed") return;
79
+ const groups = /* @__PURE__ */ new Map();
80
+ for (const [id, packagePlan] of plan.packages) {
81
+ const pkg = this.graph.get(id);
82
+ if (!eager && packagePlan.publishResult.type === "failed") return;
83
+ const tag = packagePlan.git?.tag;
84
+ if (!tag) continue;
85
+ const group = groups.get(tag);
86
+ if (group) group.push(pkg);
87
+ else groups.set(tag, [pkg]);
80
88
  }
81
- await Promise.all(Array.from(groupPackagesByTag(this, plan), async ([tag, packages]) => {
89
+ await Promise.all(Array.from(groups, async ([tag, packages]) => {
82
90
  let hasFailed = false;
83
91
  let hasPublished = false;
84
92
  for (const member of packages) switch (plan.packages.get(member.id).publishResult.type) {
@@ -198,18 +206,6 @@ function github(options = {}) {
198
206
  }
199
207
  }];
200
208
  }
201
- function groupPackagesByTag({ graph }, plan) {
202
- const groups = /* @__PURE__ */ new Map();
203
- for (const [id, packagePlan] of plan.packages) {
204
- const pkg = graph.get(id);
205
- const tag = packagePlan.git?.tag;
206
- if (!tag) continue;
207
- const group = groups.get(tag);
208
- if (group) group.push(pkg);
209
- else groups.set(tag, [pkg]);
210
- }
211
- return groups;
212
- }
213
209
  async function hasGitChanges(cwd) {
214
210
  return (await x("git", ["status", "--porcelain"], { nodeOptions: { cwd } })).stdout.trim().length > 0;
215
211
  }
@@ -1,2 +1,2 @@
1
- import { d as cargo, l as CargoPackage, u as CargoPluginOptions } from "../types-CurHqnWl.js";
1
+ import { d as cargo, l as CargoPackage, u as CargoPluginOptions } from "../types-DEaKjB3O.js";
2
2
  export { CargoPackage, CargoPluginOptions, cargo };
@@ -1,2 +1,2 @@
1
- import { f as NpmPackage, m as npm, p as NpmPluginOptions } from "../types-CurHqnWl.js";
1
+ import { f as NpmPackage, m as npm, p as NpmPluginOptions } from "../types-DEaKjB3O.js";
2
2
  export { NpmPackage, NpmPluginOptions, npm };
@@ -1,5 +1,5 @@
1
1
  import { i as isNodeError, n as execFailure } from "../error-DNy8R5ue.js";
2
- import { n as packageManifestSchema, r as pnpmWorkspaceSchema } from "../schemas-B7N6EE2k.js";
2
+ import { n as packageManifestSchema, r as pnpmWorkspaceSchema } from "../schemas-BdUlXfSu.js";
3
3
  import { n as WorkspacePackage } from "../graph-DrzluXw8.js";
4
4
  import { readFile, writeFile } from "node:fs/promises";
5
5
  import path from "node:path";
@@ -112,13 +112,7 @@ function npm({ client: defaultClient, onBreakPeerDep = "set", updateLockFile = t
112
112
  },
113
113
  async publishPreflight({ pkg }) {
114
114
  if (!(pkg instanceof NpmPackage)) return;
115
- if (pkg.manifest.private === true) return { publish: false };
116
- const registry = pkg.manifest.publishConfig?.registry;
117
- const base = (registry ?? "https://registry.npmjs.org").replace(/\/$/, "");
118
- const response = await fetch(`${base}/${pkg.name}/${pkg.version}`, { headers: { Accept: "application/json" } });
119
- if (response.status === 404) return { publish: true };
120
- if (!response.ok) throw new Error(`Unable to validate ${pkg.name}@${pkg.version} against the npm registry${registry ? ` "${registry}"` : ""}.`);
121
- return { publish: false };
115
+ return { publish: pkg.manifest.private !== true && !await isPackagePublished(pkg) };
122
116
  },
123
117
  initPublishLock({ lock, draft }) {
124
118
  for (const [id, pkg] of draft.getPackageDrafts()) {
@@ -141,42 +135,7 @@ function npm({ client: defaultClient, onBreakPeerDep = "set", updateLockFile = t
141
135
  },
142
136
  async publish({ pkg, plan }) {
143
137
  if (!(pkg instanceof NpmPackage)) return;
144
- const distTag = plan.packages.get(pkg.id).npm?.distTag;
145
- if (client === "bun") {
146
- const tarballPath = path.resolve(pkg.path, "pkg.tgz");
147
- const packResult = await x("bun", [
148
- "pm",
149
- "pack",
150
- "--filename",
151
- tarballPath
152
- ], { nodeOptions: { cwd: pkg.path } });
153
- if (packResult.exitCode !== 0) return {
154
- type: "failed",
155
- error: execFailure(`Failed to pack ${pkg.name}@${pkg.version}.`, packResult).message
156
- };
157
- const publishArgs = ["publish", tarballPath];
158
- if (distTag) publishArgs.push("--tag", distTag);
159
- const publishResult = await x("npm", publishArgs, { nodeOptions: { cwd: pkg.path } });
160
- if (publishResult.exitCode !== 0) return {
161
- type: "failed",
162
- error: execFailure(`Failed to publish ${pkg.name}@${pkg.version}${distTag ? ` with dist-tag "${distTag}"` : ""}.`, publishResult).message
163
- };
164
- return { type: "published" };
165
- }
166
- let command;
167
- const args = ["publish"];
168
- if (distTag) args.push("--tag", distTag);
169
- if (client === "pnpm") {
170
- command = "pnpm";
171
- args.push("--no-git-checks");
172
- } else if (client === "yarn") command = "yarn";
173
- else command = "npm";
174
- const result = await x(command, args, { nodeOptions: { cwd: pkg.path } });
175
- if (result.exitCode !== 0) return {
176
- type: "failed",
177
- error: execFailure(`Failed to publish ${pkg.name}@${pkg.version}${distTag ? ` with dist-tag "${distTag}"` : ""}.`, result).message
178
- };
179
- return { type: "published" };
138
+ return publish(client, pkg, plan.packages.get(pkg.id)?.npm?.distTag);
180
139
  },
181
140
  initDraft(plan) {
182
141
  if (!active) return;
@@ -275,6 +234,64 @@ function depsPolicy(context, getBumpDepType) {
275
234
  }
276
235
  };
277
236
  }
237
+ async function publish(client, pkg, distTag) {
238
+ if (client === "bun") {
239
+ for (const script of [
240
+ "prepublishOnly",
241
+ "prepack",
242
+ "prepare"
243
+ ]) {
244
+ if (!pkg.manifest.scripts?.[script]) continue;
245
+ const result = await x("bun", ["run", script], { nodeOptions: { cwd: pkg.path } });
246
+ if (result.exitCode === 0) continue;
247
+ return {
248
+ type: "failed",
249
+ error: execFailure(`Failed to run ${script} script for ${pkg.name}@${pkg.version}.`, result).message
250
+ };
251
+ }
252
+ const tarballPath = path.resolve(pkg.path, "pkg.tgz");
253
+ const packResult = await x("bun", [
254
+ "pm",
255
+ "pack",
256
+ "--filename",
257
+ tarballPath
258
+ ], { nodeOptions: { cwd: pkg.path } });
259
+ if (packResult.exitCode !== 0) return {
260
+ type: "failed",
261
+ error: execFailure(`Failed to pack ${pkg.name}@${pkg.version}.`, packResult).message
262
+ };
263
+ const publishArgs = ["publish", tarballPath];
264
+ if (distTag) publishArgs.push("--tag", distTag);
265
+ const publishResult = await x("npm", publishArgs, { nodeOptions: { cwd: pkg.path } });
266
+ if (publishResult.exitCode !== 0) return {
267
+ type: "failed",
268
+ error: execFailure(`Failed to publish ${pkg.name}@${pkg.version}${distTag ? ` with dist-tag "${distTag}"` : ""}.`, publishResult).message
269
+ };
270
+ return { type: "published" };
271
+ }
272
+ let command;
273
+ const args = ["publish"];
274
+ if (distTag) args.push("--tag", distTag);
275
+ if (client === "pnpm") {
276
+ command = "pnpm";
277
+ args.push("--no-git-checks");
278
+ } else if (client === "yarn") command = "yarn";
279
+ else command = "npm";
280
+ const result = await x(command, args, { nodeOptions: { cwd: pkg.path } });
281
+ if (result.exitCode !== 0) return {
282
+ type: "failed",
283
+ error: execFailure(`Failed to publish ${pkg.name}@${pkg.version}${distTag ? ` with dist-tag "${distTag}"` : ""}.`, result).message
284
+ };
285
+ return { type: "published" };
286
+ }
287
+ async function isPackagePublished(pkg) {
288
+ const registry = pkg.manifest.publishConfig?.registry ?? "https://registry.npmjs.org";
289
+ const base = registry.replace(/\/$/, "");
290
+ const response = await fetch(`${base}/${pkg.name}/${pkg.version}`, { headers: { Accept: "application/json" } });
291
+ if (response.status === 404) return false;
292
+ if (!response.ok) throw new Error(`Unable to validate ${pkg.name}@${pkg.version} against the npm registry${registry ? ` "${registry}"` : ""}.`);
293
+ return true;
294
+ }
278
295
  async function discoverNpmPackages(cwd, add) {
279
296
  let patterns;
280
297
  const rootManifest = await readManifest(cwd).catch(() => void 0);
@@ -16,6 +16,7 @@ const packageManifestSchema = z$1.looseObject({
16
16
  registry: z$1.string().optional(),
17
17
  tag: z$1.string().optional()
18
18
  }).optional(),
19
+ scripts: z$1.record(z$1.string(), z$1.string()).optional(),
19
20
  workspaces: z$1.array(z$1.string()).optional(),
20
21
  dependencies: stringRecordSchema.optional(),
21
22
  devDependencies: stringRecordSchema.optional(),
@@ -285,6 +285,7 @@ declare const packageManifestSchema: z$1.ZodObject<{
285
285
  registry: z$1.ZodOptional<z$1.ZodString>;
286
286
  tag: z$1.ZodOptional<z$1.ZodString>;
287
287
  }, z$1.core.$loose>>;
288
+ scripts: z$1.ZodOptional<z$1.ZodRecord<z$1.ZodString, z$1.ZodString>>;
288
289
  workspaces: z$1.ZodOptional<z$1.ZodArray<z$1.ZodString>>;
289
290
  dependencies: z$1.ZodOptional<z$1.ZodRecord<z$1.ZodString, z$1.ZodString>>;
290
291
  devDependencies: z$1.ZodOptional<z$1.ZodRecord<z$1.ZodString, z$1.ZodString>>;
@@ -512,8 +513,8 @@ interface TegamiPlugin {
512
513
  }
513
514
  type Awaitable<T> = T | Promise<T>;
514
515
  interface PublishPreflight {
515
- /** if the package should be published, default to `true`. */
516
- publish?: boolean;
516
+ /** if the package should be published. */
517
+ publish: boolean;
517
518
  /**
518
519
  * Package ids that must be published before this one, this will automatically disallow circular dependency.
519
520
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tegami",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Utility for package versioning & publish",
5
5
  "license": "MIT",
6
6
  "author": "Fuma Nama",