@savvy-web/silk-effects 3.3.0 → 4.0.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.
- package/changesets/changelog/getReleaseLine.js +1 -1
- package/changesets/constants.js +0 -18
- package/changesets/index.js +10 -24
- package/changesets/schemas/changeset.js +8 -4
- package/changesets/schemas/dependency-table.js +15 -4
- package/changesets/schemas/git.js +7 -2
- package/changesets/schemas/github.js +4 -4
- package/changesets/schemas/options.js +3 -3
- package/changesets/schemas/package-scope.js +2 -5
- package/changesets/schemas/primitives.js +2 -2
- package/changesets/schemas/release-plan.js +12 -8
- package/changesets/schemas/version-files.js +4 -4
- package/changesets/services/branch-analyzer.js +60 -191
- package/changesets/services/changelog.js +2 -15
- package/changesets/services/config-inspector.js +109 -75
- package/changesets/services/deps-regen.js +58 -32
- package/changesets/services/github.js +3 -16
- package/changesets/services/maintenance-reason.js +5 -1
- package/changesets/services/markdown.js +3 -16
- package/changesets/services/release-planner.js +4 -13
- package/changesets/utils/commit-parser.js +0 -18
- package/changesets/utils/dep-diff.js +0 -27
- package/changesets/utils/git.js +15 -50
- package/changesets/utils/issue-refs.js +0 -13
- package/changesets/utils/logger.js +0 -13
- package/changesets/utils/markdown-link.js +0 -14
- package/changesets/utils/publishability.js +11 -24
- package/changesets/utils/strip-frontmatter.js +0 -19
- package/changesets/utils/version-files.js +85 -51
- package/commitlint/config/schema.js +9 -5
- package/commitlint/detection/scopes.js +2 -7
- package/commitlint/formatter/messages.js +0 -5
- package/commitlint/hook/diagnostics/branch.js +12 -12
- package/commitlint/hook/diagnostics/open-issues.js +13 -7
- package/commitlint/hook/diagnostics/signing.js +30 -37
- package/commitlint/hook/envelope.js +2 -8
- package/commitlint/hook/silence-logger.js +14 -12
- package/index.d.ts +899 -934
- package/lint/cli/templates/markdownlint.gen.js +0 -9
- package/lint/handlers/PnpmWorkspace.js +26 -12
- package/lint/utils/Filter.js +0 -13
- package/lint/utils/Workspace.js +10 -6
- package/package.json +11 -10
- package/repos/index.js +3 -5
- package/repos/schemas/manifest.js +7 -13
- package/repos/schemas/reports.js +5 -1
- package/repos/services/config-store.js +6 -10
- package/repos/services/manager.js +52 -112
- package/schemas/CommentStyle.js +1 -1
- package/schemas/ResolvedTool.js +52 -17
- package/schemas/SectionBlock.js +1 -1
- package/schemas/SectionDefinition.js +2 -2
- package/schemas/TagStrategySchemas.js +1 -1
- package/schemas/ToolDefinition.js +1 -1
- package/schemas/ToolResults.js +1 -1
- package/schemas/VersioningSchemas.js +28 -9
- package/schemas/WorkspaceAnalysisSchemas.js +27 -17
- package/services/BiomeSchemaSync.js +7 -8
- package/services/ChangesetConfig.js +2 -2
- package/services/ChangesetConfigReader.js +7 -8
- package/services/ConfigDiscovery.js +5 -6
- package/services/ManagedSection.js +3 -4
- package/services/SilkPublishability.js +38 -15
- package/services/SilkWorkspaceAnalyzer.js +7 -9
- package/services/TagStrategy.js +3 -3
- package/services/ToolDiscovery.js +22 -21
- package/services/VersioningStrategy.js +2 -2
- package/tsdoc-metadata.json +1 -1
- package/turbo/schemas/DryRun.js +8 -14
- package/turbo/schemas/results.js +8 -8
- package/turbo/services/TurboInspector.js +30 -23
- package/utils/ToolCommand.js +38 -12
|
@@ -7,24 +7,24 @@ import { ConfigInspector, ConfigInspectorLive } from "./config-inspector.js";
|
|
|
7
7
|
import { computeWorkspaceDependencyDiffs } from "../utils/dep-diff.js";
|
|
8
8
|
import { gitListChangesetFilesAtRef, gitMergeBase } from "../utils/git.js";
|
|
9
9
|
import { listPublishablePackageNames } from "../utils/publishability.js";
|
|
10
|
-
import { Context, Effect, Layer, Option } from "effect";
|
|
10
|
+
import { Context, Effect, FileSystem, Layer, Option } from "effect";
|
|
11
11
|
import { basename, join, resolve } from "node:path";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
12
|
+
import { Git } from "@effected/git";
|
|
13
|
+
import { PublishabilityDetector, WorkspaceDiscovery, WorkspaceSnapshots, Workspaces } from "@effected/workspaces";
|
|
14
14
|
|
|
15
15
|
//#region src/changesets/services/deps-regen.ts
|
|
16
16
|
/**
|
|
17
17
|
* `Changesets.DepsRegen` service — lift the `deps regen` / `deps detect`
|
|
18
|
-
* orchestration out of the CLI into a `Context.
|
|
18
|
+
* orchestration out of the CLI into a `Context.Service` with a
|
|
19
19
|
* `plan()` / `execute()` split.
|
|
20
20
|
*
|
|
21
21
|
* @remarks
|
|
22
22
|
* `plan()` computes the cumulative dependency diff (merge-base → working
|
|
23
23
|
* tree by default, or between two explicit refs) by snapshotting both
|
|
24
|
-
* sides through `
|
|
25
|
-
* `workspace:` specifiers against each ref's own
|
|
26
|
-
* versions before diffing. It drops `devDependency`
|
|
27
|
-
* `includeDevDeps`), and returns a complete {@link RegenPlan}
|
|
24
|
+
* sides through `@effected/workspaces`' `WorkspaceSnapshots`, which
|
|
25
|
+
* resolves `catalog:` / `workspace:` specifiers against each ref's own
|
|
26
|
+
* catalogs and package versions before diffing. It drops `devDependency`
|
|
27
|
+
* rows (unless `includeDevDeps`), and returns a complete {@link RegenPlan}
|
|
28
28
|
* (target filenames + stale-changeset deletes) WITHOUT touching the
|
|
29
29
|
* filesystem. `execute()` applies a plan — writing the fresh changesets
|
|
30
30
|
* first, then deleting the stale pure-dependency ones (so an interrupted
|
|
@@ -176,7 +176,7 @@ function isPureDependencyChangeset(content) {
|
|
|
176
176
|
* unreadable `.changeset` dir must not silently masquerade as "no
|
|
177
177
|
* changesets".
|
|
178
178
|
*/
|
|
179
|
-
const listChangesetFiles = (fs, changesetDir) => fs.readDirectory(changesetDir).pipe(Effect.map((names) => names.filter((f) => f.endsWith(".md") && f !== "README.md").map((f) => join(changesetDir, f))), Effect.
|
|
179
|
+
const listChangesetFiles = (fs, changesetDir) => fs.readDirectory(changesetDir).pipe(Effect.map((names) => names.filter((f) => f.endsWith(".md") && f !== "README.md").map((f) => join(changesetDir, f))), Effect.catch((e) => e._tag === "PlatformError" && e.reason._tag === "NotFound" ? Effect.succeed([]) : Effect.fail(new ChangesetIOError({
|
|
180
180
|
path: changesetDir,
|
|
181
181
|
operation: "list",
|
|
182
182
|
reason: String(e)
|
|
@@ -225,11 +225,6 @@ const findMixedDependencyChangesets = (fs, changesetDir) => Effect.gen(function*
|
|
|
225
225
|
function renderChangesetContent(diff) {
|
|
226
226
|
return `${`---\n"${diff.package}": patch\n---`}\n\n## Dependencies\n\n${serializeDependencyTableToMarkdown([...diff.rows])}\n`;
|
|
227
227
|
}
|
|
228
|
-
const _tag = Context.Tag("Changesets/DepsRegen");
|
|
229
|
-
/**
|
|
230
|
-
* @internal
|
|
231
|
-
*/
|
|
232
|
-
const DepsRegenBase = _tag();
|
|
233
228
|
/**
|
|
234
229
|
* Effect service tag for {@link DepsRegenShape}.
|
|
235
230
|
*
|
|
@@ -247,13 +242,13 @@ const DepsRegenBase = _tag();
|
|
|
247
242
|
*
|
|
248
243
|
* @public
|
|
249
244
|
*/
|
|
250
|
-
var DepsRegen = class extends
|
|
245
|
+
var DepsRegen = class extends Context.Service()("Changesets/DepsRegen") {};
|
|
251
246
|
/**
|
|
252
247
|
* Build a {@link DepsRegenShape} that closes over already-resolved service
|
|
253
248
|
* implementations, keeping the public `plan`/`execute` signatures
|
|
254
249
|
* requirement-free (`R = never`).
|
|
255
250
|
*/
|
|
256
|
-
function makeShape(
|
|
251
|
+
function makeShape(snapshots, inspector, discovery, detector, config, fs, provideGit) {
|
|
257
252
|
const provideDetector = Layer.succeed(PublishabilityDetector, detector);
|
|
258
253
|
const fileExists = (p) => fs.exists(p).pipe(Effect.orElseSucceed(() => false));
|
|
259
254
|
const plan = (options) => Effect.gen(function* () {
|
|
@@ -265,12 +260,12 @@ function makeShape(pit, inspector, discovery, detector, config, fs) {
|
|
|
265
260
|
if (!fromRef) {
|
|
266
261
|
let baseBranch = options.base;
|
|
267
262
|
if (!baseBranch) baseBranch = (yield* inspector.inspect(resolvedCwd).pipe(Effect.catchTag("ConfigurationError", () => Effect.succeed({ baseBranch: "main" })))).baseBranch;
|
|
268
|
-
fromRef = yield* gitMergeBase(resolvedCwd, baseBranch);
|
|
263
|
+
fromRef = yield* gitMergeBase(resolvedCwd, baseBranch).pipe(Effect.provide(provideGit));
|
|
269
264
|
}
|
|
270
|
-
const rawDiffs = computeWorkspaceDependencyDiffs(yield*
|
|
265
|
+
const rawDiffs = computeWorkspaceDependencyDiffs(yield* snapshots.at(fromRef), options.to ? yield* snapshots.at(options.to) : yield* snapshots.worktree());
|
|
271
266
|
const explicitTargets = /* @__PURE__ */ new Set([...options.packages ?? [], ...options.package ? [options.package] : []]);
|
|
272
267
|
const excluded = new Set(options.exclude ?? []);
|
|
273
|
-
const livePackages = yield* discovery.listPackages(
|
|
268
|
+
const livePackages = yield* discovery.listPackages();
|
|
274
269
|
const publishable = yield* listPublishablePackageNames(livePackages, resolvedCwd).pipe(Effect.provide(provideDetector));
|
|
275
270
|
const versionPrivate = yield* config.versionPrivate(resolvedCwd);
|
|
276
271
|
const inScope = /* @__PURE__ */ new Set();
|
|
@@ -298,7 +293,7 @@ function makeShape(pit, inspector, discovery, detector, config, fs) {
|
|
|
298
293
|
const existingPure = yield* findPureDependencyChangesets(fs, changesetDir);
|
|
299
294
|
const skippedMixed = yield* findMixedDependencyChangesets(fs, changesetDir);
|
|
300
295
|
const rewrittenPackages = new Set(resolved.map((d) => d.package));
|
|
301
|
-
const atMergeBase = yield* gitListChangesetFilesAtRef(resolvedCwd, fromRef);
|
|
296
|
+
const atMergeBase = yield* gitListChangesetFilesAtRef(resolvedCwd, fromRef).pipe(Effect.provide(provideGit));
|
|
302
297
|
const authoredOnBranch = (file) => !atMergeBase.has(basename(file));
|
|
303
298
|
const toDelete = existingPure.filter((p) => inScopeFor(p.package) && rewrittenPackages.has(p.package) && authoredOnBranch(p.file));
|
|
304
299
|
const chosenFilenames = /* @__PURE__ */ new Set();
|
|
@@ -343,8 +338,9 @@ function makeShape(pit, inspector, discovery, detector, config, fs) {
|
|
|
343
338
|
/**
|
|
344
339
|
* Live layer for {@link DepsRegen}.
|
|
345
340
|
*
|
|
346
|
-
* Requires `
|
|
347
|
-
* `PublishabilityDetector` (all from
|
|
341
|
+
* Requires `WorkspaceSnapshots`, `WorkspaceDiscovery`,
|
|
342
|
+
* `PublishabilityDetector` (all from `@effected/workspaces`),
|
|
343
|
+
* `Git` (from `@effected/git`, backing merge-base resolution),
|
|
348
344
|
* {@link ConfigInspector}, {@link ChangesetConfig}, and
|
|
349
345
|
* `FileSystem.FileSystem` (resolved once at construction and closed over by
|
|
350
346
|
* the shape, keeping `plan`/`execute` themselves requirement-free).
|
|
@@ -352,17 +348,47 @@ function makeShape(pit, inspector, discovery, detector, config, fs) {
|
|
|
352
348
|
* @public
|
|
353
349
|
*/
|
|
354
350
|
const DepsRegenLive = Layer.effect(DepsRegen, Effect.gen(function* () {
|
|
355
|
-
|
|
351
|
+
const snapshots = yield* WorkspaceSnapshots;
|
|
352
|
+
const inspector = yield* ConfigInspector;
|
|
353
|
+
const discovery = yield* WorkspaceDiscovery;
|
|
354
|
+
const detector = yield* PublishabilityDetector;
|
|
355
|
+
const config = yield* ChangesetConfig;
|
|
356
|
+
const fs = yield* FileSystem.FileSystem;
|
|
357
|
+
const git = yield* Git;
|
|
358
|
+
return makeShape(snapshots, inspector, discovery, detector, config, fs, Layer.succeed(Git, git));
|
|
356
359
|
}));
|
|
357
|
-
const WorkspaceGraph = Layer.mergeAll(WorkspaceRootLive, WorkspaceDiscoveryLive.pipe(Layer.provide(WorkspaceRootLive)));
|
|
358
360
|
const ConfigGraph = ChangesetConfigLive.pipe(Layer.provide(ChangesetConfigReaderLive));
|
|
359
361
|
/**
|
|
362
|
+
* Build the batteries-included {@link DepsRegen} layer over a
|
|
363
|
+
* `@effected/workspaces` kit graph bound to `options.cwd`.
|
|
364
|
+
*
|
|
365
|
+
* @remarks
|
|
366
|
+
* The kit's root-consuming services (`WorkspaceDiscovery`,
|
|
367
|
+
* `WorkspaceSnapshots`, `WorkspaceRoot`) resolve their workspace root from
|
|
368
|
+
* the layer they were built with — single-root by design. {@link DepsRegenDefault}
|
|
369
|
+
* is this builder bound with no options (root from `process.cwd()`, read
|
|
370
|
+
* lazily); pass an explicit `cwd` when planning against a different root
|
|
371
|
+
* (fixtures, multi-repo hosts).
|
|
372
|
+
*
|
|
373
|
+
* `Workspaces.layerWithGit` mints a fresh layer reference per call, so the
|
|
374
|
+
* graph is bound ONCE per builder call and shared across every internal
|
|
375
|
+
* branch — layer memoization by reference constructs each kit service
|
|
376
|
+
* exactly once.
|
|
377
|
+
*
|
|
378
|
+
* @public
|
|
379
|
+
*/
|
|
380
|
+
function makeDepsRegenDefault(options) {
|
|
381
|
+
const kitGraph = Workspaces.layerWithGit(options);
|
|
382
|
+
return DepsRegenLive.pipe(Layer.provide(ConfigInspectorLive.pipe(Layer.provide(Layer.mergeAll(ChangesetConfigReaderLive, kitGraph)))), Layer.provide(PublishabilityDetectorAdaptiveLive.pipe(Layer.provide(Layer.mergeAll(ConfigGraph, kitGraph)))), Layer.provide(ConfigGraph), Layer.provide(kitGraph));
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
360
385
|
* Batteries-included {@link DepsRegen} layer: silk's opinionated default
|
|
361
|
-
* composition of the full dependency graph
|
|
362
|
-
*
|
|
363
|
-
*
|
|
386
|
+
* composition of the full dependency graph, root-bound to `process.cwd()`
|
|
387
|
+
* (see {@link makeDepsRegenDefault} for an explicit root). Only the platform
|
|
388
|
+
* services remain — note that `WorkspaceSnapshots` reads git history, so
|
|
389
|
+
* this layer genuinely requires `ChildProcessSpawner` in addition to
|
|
364
390
|
* `FileSystem`/`Path`: provide a git-capable platform layer
|
|
365
|
-
* (`
|
|
391
|
+
* (`NodeServices.layer`), not a bare filesystem-only layer.
|
|
366
392
|
*
|
|
367
393
|
* Gating uses silk's adaptive publishability detector
|
|
368
394
|
* ({@link PublishabilityDetectorAdaptiveLive}), so the default semantics
|
|
@@ -373,16 +399,16 @@ const ConfigGraph = ChangesetConfigLive.pipe(Layer.provide(ChangesetConfigReader
|
|
|
373
399
|
*
|
|
374
400
|
* @example
|
|
375
401
|
* ```typescript
|
|
376
|
-
* import {
|
|
402
|
+
* import { NodeServices } from "@effect/platform-node";
|
|
377
403
|
* import { Layer } from "effect";
|
|
378
404
|
* import { Changesets } from "@savvy-web/silk-effects";
|
|
379
405
|
*
|
|
380
|
-
* const depsRegen = Changesets.DepsRegenDefault.pipe(Layer.provide(
|
|
406
|
+
* const depsRegen = Changesets.DepsRegenDefault.pipe(Layer.provide(NodeServices.layer));
|
|
381
407
|
* ```
|
|
382
408
|
*
|
|
383
409
|
* @public
|
|
384
410
|
*/
|
|
385
|
-
const DepsRegenDefault =
|
|
411
|
+
const DepsRegenDefault = makeDepsRegenDefault();
|
|
386
412
|
|
|
387
413
|
//#endregion
|
|
388
|
-
export { DepsRegen,
|
|
414
|
+
export { DepsRegen, DepsRegenDefault, DepsRegenLive, isPureDependencyChangeset, makeDepsRegenDefault };
|
|
@@ -23,18 +23,6 @@ import { Context, Effect, Layer } from "effect";
|
|
|
23
23
|
* @see {@link GitHubLive} for the production layer
|
|
24
24
|
* @see {@link makeGitHubTest} for constructing test layers
|
|
25
25
|
*/
|
|
26
|
-
const _tag = Context.Tag("GitHubService");
|
|
27
|
-
/**
|
|
28
|
-
* Base class for GitHubService.
|
|
29
|
-
*
|
|
30
|
-
* @privateRemarks
|
|
31
|
-
* This export is required for api-extractor documentation generation.
|
|
32
|
-
* Effect's Context.Tag creates an anonymous base class that must be
|
|
33
|
-
* explicitly exported to avoid "forgotten export" warnings. Do not delete.
|
|
34
|
-
*
|
|
35
|
-
* @internal
|
|
36
|
-
*/
|
|
37
|
-
const GitHubServiceBase = _tag();
|
|
38
26
|
/**
|
|
39
27
|
* Effect service tag for GitHub API operations.
|
|
40
28
|
*
|
|
@@ -43,7 +31,7 @@ const GitHubServiceBase = _tag();
|
|
|
43
31
|
* service instance.
|
|
44
32
|
*
|
|
45
33
|
* @remarks
|
|
46
|
-
* This tag follows the standard Effect `Context.
|
|
34
|
+
* This tag follows the standard Effect `Context.Service` pattern. Two layers
|
|
47
35
|
* are provided out of the box:
|
|
48
36
|
*
|
|
49
37
|
* - {@link GitHubLive} — production layer backed by the GitHub REST API
|
|
@@ -90,11 +78,10 @@ const GitHubServiceBase = _tag();
|
|
|
90
78
|
* @see {@link GitHubServiceShape} for the service interface
|
|
91
79
|
* @see {@link GitHubLive} for the production layer
|
|
92
80
|
* @see {@link makeGitHubTest} for creating test layers
|
|
93
|
-
* @see {@link GitHubServiceBase} for the api-extractor base class
|
|
94
81
|
*
|
|
95
82
|
* @public
|
|
96
83
|
*/
|
|
97
|
-
var GitHubService = class extends
|
|
84
|
+
var GitHubService = class extends Context.Service()("GitHubService") {};
|
|
98
85
|
/**
|
|
99
86
|
* Production layer for {@link GitHubService}.
|
|
100
87
|
*
|
|
@@ -175,4 +162,4 @@ function makeGitHubTest(responses) {
|
|
|
175
162
|
}
|
|
176
163
|
|
|
177
164
|
//#endregion
|
|
178
|
-
export { GitHubLive, GitHubService,
|
|
165
|
+
export { GitHubLive, GitHubService, makeGitHubTest };
|
|
@@ -20,7 +20,11 @@ const MaintenanceTriggerSchema = Schema.Struct({
|
|
|
20
20
|
*/
|
|
21
21
|
const MaintenanceReasonSchema = Schema.Struct({
|
|
22
22
|
/** Coupling that forced the release; `"unspecified"` when undetermined. */
|
|
23
|
-
kind: Schema.
|
|
23
|
+
kind: Schema.Literals([
|
|
24
|
+
"fixed",
|
|
25
|
+
"linked",
|
|
26
|
+
"unspecified"
|
|
27
|
+
]),
|
|
24
28
|
/** Triggering co-members; empty for `"unspecified"`. */
|
|
25
29
|
triggers: Schema.Array(MaintenanceTriggerSchema)
|
|
26
30
|
});
|
|
@@ -22,18 +22,6 @@ import { Context, Effect, Layer } from "effect";
|
|
|
22
22
|
* @see {@link MarkdownServiceShape} for the service interface
|
|
23
23
|
* @see {@link MarkdownLive} for the production layer
|
|
24
24
|
*/
|
|
25
|
-
const _tag = Context.Tag("MarkdownService");
|
|
26
|
-
/**
|
|
27
|
-
* Base class for MarkdownService.
|
|
28
|
-
*
|
|
29
|
-
* @privateRemarks
|
|
30
|
-
* This export is required for api-extractor documentation generation.
|
|
31
|
-
* Effect's Context.Tag creates an anonymous base class that must be
|
|
32
|
-
* explicitly exported to avoid "forgotten export" warnings. Do not delete.
|
|
33
|
-
*
|
|
34
|
-
* @internal
|
|
35
|
-
*/
|
|
36
|
-
const MarkdownServiceBase = _tag();
|
|
37
25
|
/**
|
|
38
26
|
* Effect service tag for markdown parsing and stringification.
|
|
39
27
|
*
|
|
@@ -42,7 +30,7 @@ const MarkdownServiceBase = _tag();
|
|
|
42
30
|
* service instance.
|
|
43
31
|
*
|
|
44
32
|
* @remarks
|
|
45
|
-
* This tag follows the standard Effect `Context.
|
|
33
|
+
* This tag follows the standard Effect `Context.Service` pattern. The
|
|
46
34
|
* {@link MarkdownLive} layer provides the default implementation backed by
|
|
47
35
|
* the remark/unified pipeline. For testing, you can supply a custom layer
|
|
48
36
|
* via `Layer.succeed(MarkdownService, { parse: ..., stringify: ... })`.
|
|
@@ -64,11 +52,10 @@ const MarkdownServiceBase = _tag();
|
|
|
64
52
|
*
|
|
65
53
|
* @see {@link MarkdownServiceShape} for the service interface
|
|
66
54
|
* @see {@link MarkdownLive} for the production layer
|
|
67
|
-
* @see {@link MarkdownServiceBase} for the api-extractor base class
|
|
68
55
|
*
|
|
69
56
|
* @public
|
|
70
57
|
*/
|
|
71
|
-
var MarkdownService = class extends
|
|
58
|
+
var MarkdownService = class extends Context.Service()("MarkdownService") {};
|
|
72
59
|
/**
|
|
73
60
|
* Production layer for {@link MarkdownService}.
|
|
74
61
|
*
|
|
@@ -103,4 +90,4 @@ const MarkdownLive = Layer.succeed(MarkdownService, {
|
|
|
103
90
|
});
|
|
104
91
|
|
|
105
92
|
//#endregion
|
|
106
|
-
export { MarkdownLive, MarkdownService
|
|
93
|
+
export { MarkdownLive, MarkdownService };
|
|
@@ -3,9 +3,8 @@ import { ChangelogTransformer } from "../api/transformer.js";
|
|
|
3
3
|
import { ConfigInspector } from "./config-inspector.js";
|
|
4
4
|
import { deriveMaintenanceReason } from "./maintenance-reason.js";
|
|
5
5
|
import { VersionFiles } from "../utils/version-files.js";
|
|
6
|
-
import { Context, Effect, Layer } from "effect";
|
|
6
|
+
import { Context, Effect, FileSystem, Layer } from "effect";
|
|
7
7
|
import { dirname, isAbsolute, join, relative } from "node:path";
|
|
8
|
-
import { FileSystem } from "@effect/platform";
|
|
9
8
|
import { applyReleasePlan } from "@changesets/apply-release-plan";
|
|
10
9
|
import { readConfig } from "@changesets/config";
|
|
11
10
|
import { getReleasePlan } from "@changesets/get-release-plan";
|
|
@@ -39,16 +38,8 @@ async function loadConfig(root, packages) {
|
|
|
39
38
|
warnings: configResult.warnings
|
|
40
39
|
};
|
|
41
40
|
}
|
|
42
|
-
const _tag = Context.Tag("ReleasePlanner");
|
|
43
|
-
/**
|
|
44
|
-
* Base class for {@link ReleasePlanner}.
|
|
45
|
-
*
|
|
46
|
-
* @privateRemarks Required export for api-extractor (anonymous Context.Tag base). Do not delete.
|
|
47
|
-
* @internal
|
|
48
|
-
*/
|
|
49
|
-
const ReleasePlannerBase = _tag();
|
|
50
41
|
/** Effect service tag for the release planner. @public */
|
|
51
|
-
var ReleasePlanner = class extends
|
|
42
|
+
var ReleasePlanner = class extends Context.Service()("ReleasePlanner") {};
|
|
52
43
|
/** Build the service shape over a resolved {@link ConfigInspector} and {@link FileSystem.FileSystem}. */
|
|
53
44
|
function makeShape(inspector, fs) {
|
|
54
45
|
const plan = (root) => Effect.tryPromise({
|
|
@@ -316,7 +307,7 @@ function applyEffect(root, dryRun, changelogModules, inspector, fs) {
|
|
|
316
307
|
});
|
|
317
308
|
}
|
|
318
309
|
const newVersionByName = new Map(plan.releases.map((r) => [r.name, r.newVersion]));
|
|
319
|
-
const inspected = yield* inspector.inspect(root).pipe(Effect.
|
|
310
|
+
const inspected = yield* inspector.inspect(root).pipe(Effect.catch((error) => Effect.logWarning(`Skipping versionFiles update: ${errMsg(error)}`).pipe(Effect.as(null))));
|
|
320
311
|
let versionFileUpdates = [];
|
|
321
312
|
if (inspected) {
|
|
322
313
|
const candidates = inspected.packages.filter((p) => p.versionFiles.length > 0);
|
|
@@ -346,4 +337,4 @@ function applyEffect(root, dryRun, changelogModules, inspector, fs) {
|
|
|
346
337
|
}
|
|
347
338
|
|
|
348
339
|
//#endregion
|
|
349
|
-
export { ReleasePlanner,
|
|
340
|
+
export { ReleasePlanner, ReleasePlannerLive, extractVersionBlock, makeReleasePlannerTest };
|
|
@@ -1,23 +1,5 @@
|
|
|
1
1
|
//#region src/changesets/utils/commit-parser.ts
|
|
2
2
|
/**
|
|
3
|
-
* Conventional commit message parsing.
|
|
4
|
-
*
|
|
5
|
-
* Implements a parser for the
|
|
6
|
-
* {@link https://www.conventionalcommits.org/ | Conventional Commits}
|
|
7
|
-
* specification, extracting type, scope, breaking-change indicator,
|
|
8
|
-
* description, and body from commit messages.
|
|
9
|
-
*
|
|
10
|
-
* @remarks
|
|
11
|
-
* The parser uses a single regex pass for the first line, then splits
|
|
12
|
-
* remaining lines to extract the body. Non-conventional messages are
|
|
13
|
-
* returned with only the `description` field populated (set to the
|
|
14
|
-
* full message text).
|
|
15
|
-
*
|
|
16
|
-
* @see {@link Changelog} for the public API that consumes parsed commits
|
|
17
|
-
*
|
|
18
|
-
* @internal
|
|
19
|
-
*/
|
|
20
|
-
/**
|
|
21
3
|
* Matches conventional commit format: `type(scope)!: description`.
|
|
22
4
|
*
|
|
23
5
|
* Capture groups:
|
|
@@ -2,33 +2,6 @@ import { sortDependencyRows } from "./dependency-table.js";
|
|
|
2
2
|
import { Option } from "effect";
|
|
3
3
|
|
|
4
4
|
//#region src/changesets/utils/dep-diff.ts
|
|
5
|
-
/**
|
|
6
|
-
* Compute per-workspace-package dependency-table rows from two
|
|
7
|
-
* {@link WorkspaceStateSnapshot}s, resolving `catalog:` / `workspace:`
|
|
8
|
-
* specifiers against each side's own catalogs and package versions BEFORE
|
|
9
|
-
* comparing.
|
|
10
|
-
*
|
|
11
|
-
* @remarks
|
|
12
|
-
* Operates on declared dependencies only (the `dependencies` /
|
|
13
|
-
* `devDependencies` / `peerDependencies` / `optionalDependencies` fields
|
|
14
|
-
* of each workspace's `package.json`). Lockfile-only movements
|
|
15
|
-
* (resolved versions changing while declared ranges stay put) are
|
|
16
|
-
* intentionally excluded — those happen on every `pnpm install` and
|
|
17
|
-
* would generate constant noise.
|
|
18
|
-
*
|
|
19
|
-
* Each side carries its own catalogs and package versions, so a specifier
|
|
20
|
-
* is resolved against the snapshot it belongs to: `catalog:silk` resolves
|
|
21
|
-
* to that ref's `silk` catalog entry, `workspace:*` to that ref's target
|
|
22
|
-
* package version. A row is emitted iff the two RESOLVED values differ (or
|
|
23
|
-
* the dependency was added/removed) — a package that merely adopted a
|
|
24
|
-
* `catalog:` specifier without changing the concrete version produces NO
|
|
25
|
-
* row. When a side cannot resolve a specifier (no matching catalog entry,
|
|
26
|
-
* plain range, etc.) it falls back to the raw specifier string.
|
|
27
|
-
*
|
|
28
|
-
* @see {@link DependencyTableRow} for the row schema
|
|
29
|
-
* @see {@link WorkspaceStateSnapshot} for the input shape
|
|
30
|
-
*
|
|
31
|
-
*/
|
|
32
5
|
/** The em-dash sentinel (U+2014) used for added ("from") / removed ("to") cells. */
|
|
33
6
|
const EM_DASH = "—";
|
|
34
7
|
const DEP_TYPE_MAP = [
|
package/changesets/utils/git.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { GitError } from "../errors.js";
|
|
2
2
|
import { Effect } from "effect";
|
|
3
3
|
import { basename } from "node:path";
|
|
4
|
-
import {
|
|
4
|
+
import { Git } from "@effected/git";
|
|
5
5
|
|
|
6
6
|
//#region src/changesets/utils/git.ts
|
|
7
7
|
/**
|
|
8
8
|
* Git helpers for the changesets deps regen/detect orchestration.
|
|
9
9
|
*
|
|
10
10
|
* @remarks
|
|
11
|
-
* `
|
|
12
|
-
* dependency diff
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* `WorkspaceSnapshots` (from `@effected/workspaces`) reads both sides of a
|
|
12
|
+
* dependency diff. The one git operation it does not cover is resolving the
|
|
13
|
+
* default `--from` ref — the merge-base with the base branch — which is
|
|
14
|
+
* delegated to `@effected/git`'s `Git` service (spawning through
|
|
15
|
+
* `ChildProcessSpawner`, provided at the app edge).
|
|
15
16
|
*
|
|
16
17
|
* @internal
|
|
17
18
|
*/
|
|
@@ -22,34 +23,17 @@ import { execFileSync } from "node:child_process";
|
|
|
22
23
|
* @internal
|
|
23
24
|
*/
|
|
24
25
|
function gitMergeBase(cwd, base) {
|
|
25
|
-
return Effect.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
base,
|
|
29
|
-
"HEAD"
|
|
30
|
-
], {
|
|
26
|
+
return Effect.gen(function* () {
|
|
27
|
+
return yield* (yield* Git).mergeBase(cwd, base, "HEAD").pipe(Effect.mapError((error) => new GitError({
|
|
28
|
+
command: `git merge-base ${base} HEAD`,
|
|
31
29
|
cwd,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"ignore",
|
|
35
|
-
"pipe",
|
|
36
|
-
"pipe"
|
|
37
|
-
]
|
|
38
|
-
}).trim(),
|
|
39
|
-
catch: (error) => {
|
|
40
|
-
const stderr = error.stderr;
|
|
41
|
-
const text = typeof stderr === "string" ? stderr : stderr?.toString() ?? "";
|
|
42
|
-
return new GitError({
|
|
43
|
-
command: `git merge-base ${base} HEAD`,
|
|
44
|
-
cwd,
|
|
45
|
-
reason: text.trim() || (error.message ?? String(error))
|
|
46
|
-
});
|
|
47
|
-
}
|
|
30
|
+
reason: error.message
|
|
31
|
+
})));
|
|
48
32
|
});
|
|
49
33
|
}
|
|
50
34
|
/**
|
|
51
35
|
* List the basenames of `.changeset/*.md` files tracked at `ref` (e.g. the
|
|
52
|
-
* merge base), via `git ls-tree -r
|
|
36
|
+
* merge base), via `git ls-tree -r`. Used by `DepsRegen.plan()`
|
|
53
37
|
* to protect changesets authored by already-merged PRs from being deleted by
|
|
54
38
|
* an unrelated branch's regen run (#258).
|
|
55
39
|
*
|
|
@@ -65,28 +49,9 @@ function gitMergeBase(cwd, base) {
|
|
|
65
49
|
* @internal
|
|
66
50
|
*/
|
|
67
51
|
function gitListChangesetFilesAtRef(cwd, ref) {
|
|
68
|
-
return Effect.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
"ls-tree",
|
|
72
|
-
"-r",
|
|
73
|
-
"--name-only",
|
|
74
|
-
ref,
|
|
75
|
-
"--",
|
|
76
|
-
".changeset"
|
|
77
|
-
], {
|
|
78
|
-
cwd,
|
|
79
|
-
encoding: "utf8",
|
|
80
|
-
stdio: [
|
|
81
|
-
"ignore",
|
|
82
|
-
"pipe",
|
|
83
|
-
"pipe"
|
|
84
|
-
]
|
|
85
|
-
});
|
|
86
|
-
return new Set(out.split(/\r?\n/).filter((line) => line.trim().length > 0).map((path) => basename(path)));
|
|
87
|
-
} catch {
|
|
88
|
-
return /* @__PURE__ */ new Set();
|
|
89
|
-
}
|
|
52
|
+
return Effect.gen(function* () {
|
|
53
|
+
const entries = yield* (yield* Git).lsTree(cwd, ref, { pathspec: [".changeset"] }).pipe(Effect.catch(() => Effect.succeed([])));
|
|
54
|
+
return new Set(entries.filter((entry) => entry.path.trim().length > 0).map((entry) => basename(entry.path)));
|
|
90
55
|
});
|
|
91
56
|
}
|
|
92
57
|
|
|
@@ -1,18 +1,5 @@
|
|
|
1
1
|
//#region src/changesets/utils/issue-refs.ts
|
|
2
2
|
/**
|
|
3
|
-
* GitHub issue reference parsing from commit messages.
|
|
4
|
-
*
|
|
5
|
-
* @remarks
|
|
6
|
-
* Extracts categorized issue references (`Closes`, `Fixes`, `Refs`) from
|
|
7
|
-
* commit message bodies. Supports multiple formats including with/without
|
|
8
|
-
* colons, singular/plural keywords, and comma-separated issue lists.
|
|
9
|
-
* Input is truncated to 10,000 characters to prevent ReDoS on adversarial input.
|
|
10
|
-
*
|
|
11
|
-
* @see {@link Changelog} for the public API that consumes issue references
|
|
12
|
-
*
|
|
13
|
-
* @internal
|
|
14
|
-
*/
|
|
15
|
-
/**
|
|
16
3
|
* Matches "closes #123" or "close: #456, #789" patterns (case-insensitive).
|
|
17
4
|
*
|
|
18
5
|
* Capture group `[1]` contains the comma-separated issue number list.
|
|
@@ -1,18 +1,5 @@
|
|
|
1
1
|
//#region src/changesets/utils/logger.ts
|
|
2
2
|
/**
|
|
3
|
-
* Simple logging utility for changelog generation.
|
|
4
|
-
*
|
|
5
|
-
* @remarks
|
|
6
|
-
* Provides environment-aware warning output:
|
|
7
|
-
* - **GitHub Actions**: emits `::warning::` annotations that surface in
|
|
8
|
-
* the Actions UI
|
|
9
|
-
* - **Local development**: falls back to `console.warn`
|
|
10
|
-
* - **Test environment**: suppressed entirely when `process.env.VITEST`
|
|
11
|
-
* is set, preventing noisy test output
|
|
12
|
-
*
|
|
13
|
-
* @internal
|
|
14
|
-
*/
|
|
15
|
-
/**
|
|
16
3
|
* Log a warning message.
|
|
17
4
|
*
|
|
18
5
|
* @remarks
|
|
@@ -1,19 +1,5 @@
|
|
|
1
1
|
//#region src/changesets/utils/markdown-link.ts
|
|
2
2
|
/**
|
|
3
|
-
* Markdown link extraction utilities.
|
|
4
|
-
*
|
|
5
|
-
* @remarks
|
|
6
|
-
* Handles the inconsistency where `\@changesets/get-github-info` sometimes
|
|
7
|
-
* returns markdown-formatted links (e.g., `[#17](https://...)`) instead
|
|
8
|
-
* of plain URLs. Provides a regex pattern and extraction function to
|
|
9
|
-
* normalize these values.
|
|
10
|
-
*
|
|
11
|
-
* @see {@link Changelog} for the public API that uses link extraction
|
|
12
|
-
* during changelog generation
|
|
13
|
-
*
|
|
14
|
-
* @internal
|
|
15
|
-
*/
|
|
16
|
-
/**
|
|
17
3
|
* Pattern matching markdown link format: `[text](url)`.
|
|
18
4
|
*
|
|
19
5
|
* Capture groups:
|
|
@@ -1,47 +1,34 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
|
-
import { PublishabilityDetector } from "workspaces
|
|
2
|
+
import { PublishabilityDetector } from "@effected/workspaces";
|
|
3
3
|
|
|
4
4
|
//#region src/changesets/utils/publishability.ts
|
|
5
5
|
/**
|
|
6
|
-
* Publishability helpers for the changeset CLI commands.
|
|
7
|
-
*
|
|
8
|
-
* @remarks
|
|
9
|
-
* Provides `listPublishablePackageNames`, a convenience wrapper around
|
|
10
|
-
* {@link SilkPublishability} that returns a `Set<string>` of
|
|
11
|
-
* publishable package names. Used by the `deps detect` and `deps regen`
|
|
12
|
-
* commands to filter out workspace packages whose dependency changes
|
|
13
|
-
* would never reach a release.
|
|
14
|
-
*
|
|
15
|
-
*/
|
|
16
|
-
/**
|
|
17
6
|
* Compute the set of currently-publishable workspace package names.
|
|
18
7
|
*
|
|
19
8
|
* @remarks
|
|
20
9
|
* Uses the currently-active {@link SilkPublishability} — wire the
|
|
21
10
|
* {@link SilkPublishabilityDetectorLive} layer to get silk semantics.
|
|
22
11
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* `.changeset
|
|
26
|
-
* `
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* package resolve to "not publishable". Mirrors
|
|
31
|
-
* {@link SilkPublishability.listPublishable}, which takes the same
|
|
12
|
+
* The kit's `PublishabilityDetector.detect` contract no longer receives the
|
|
13
|
+
* workspace root — the ignore/mode-aware `PublishabilityDetectorAdaptiveLive`
|
|
14
|
+
* derives the `.changeset/config.json` root per package from the package's
|
|
15
|
+
* own discovery coordinates (`pkg.path` ascended by `pkg.relativePath`).
|
|
16
|
+
* The `root` parameter is retained for signature stability
|
|
17
|
+
* but is no longer consulted. Mirrors
|
|
18
|
+
* {@link SilkPublishability.listPublishable}, which keeps the same inert
|
|
32
19
|
* single-root parameter for the same reason.
|
|
33
20
|
*
|
|
34
21
|
* @param packages - The workspace packages to evaluate
|
|
35
|
-
* @param
|
|
22
|
+
* @param _root - Retained for signature stability; no longer consulted
|
|
36
23
|
* @returns An Effect yielding a `Set` of publishable package names
|
|
37
24
|
*
|
|
38
25
|
* @public
|
|
39
26
|
*/
|
|
40
|
-
function listPublishablePackageNames(packages,
|
|
27
|
+
function listPublishablePackageNames(packages, _root) {
|
|
41
28
|
return Effect.gen(function* () {
|
|
42
29
|
const detector = yield* PublishabilityDetector;
|
|
43
30
|
const names = /* @__PURE__ */ new Set();
|
|
44
|
-
for (const pkg of packages) if ((yield* detector.detect(pkg
|
|
31
|
+
for (const pkg of packages) if ((yield* detector.detect(pkg)).length > 0) names.add(pkg.name);
|
|
45
32
|
return names;
|
|
46
33
|
});
|
|
47
34
|
}
|
|
@@ -1,24 +1,5 @@
|
|
|
1
1
|
//#region src/changesets/utils/strip-frontmatter.ts
|
|
2
2
|
/**
|
|
3
|
-
* Utility for stripping YAML frontmatter from changeset files.
|
|
4
|
-
*
|
|
5
|
-
* @remarks
|
|
6
|
-
* Changeset `.md` files produced by `\@changesets/cli` contain YAML
|
|
7
|
-
* frontmatter (delimited by `---`) specifying which packages are
|
|
8
|
-
* affected and their version bump types. This frontmatter must be
|
|
9
|
-
* removed before remark-lint processing, as remark-parse does not
|
|
10
|
-
* handle YAML frontmatter natively without `remark-frontmatter`.
|
|
11
|
-
*
|
|
12
|
-
* The regex used is non-greedy (`[\s\S]*?`) to match only the first
|
|
13
|
-
* frontmatter block and avoid stripping content after a second `---`
|
|
14
|
-
* delimiter that might appear in the document body.
|
|
15
|
-
*
|
|
16
|
-
* @see {@link ChangesetLinter} for the public API that uses frontmatter
|
|
17
|
-
* stripping during changeset validation
|
|
18
|
-
*
|
|
19
|
-
* @internal
|
|
20
|
-
*/
|
|
21
|
-
/**
|
|
22
3
|
* Strip leading YAML frontmatter from a markdown string.
|
|
23
4
|
*
|
|
24
5
|
* Removes the `---\n...\n---\n` block at the start of the content.
|