@savvy-web/silk-effects 2.0.2 → 3.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/api/changelog.js +2 -2
- package/changesets/api/transformer.js +24 -30
- package/changesets/changelog/formatting.js +4 -10
- package/changesets/changelog/getDependencyReleaseLine.js +13 -9
- package/changesets/changelog/getReleaseLine.js +8 -8
- package/changesets/changelog/index.js +1 -1
- package/changesets/index.js +9 -3
- package/changesets/remark/plugins/deduplicate-items.js +11 -9
- package/changesets/remark/plugins/maintenance-note.js +61 -0
- package/changesets/remark/presets.js +1 -1
- package/changesets/services/maintenance-reason.js +66 -0
- package/changesets/services/release-planner.js +104 -58
- package/changesets/vendor/github-info.js +33 -11
- package/index.d.ts +140 -37
- package/package.json +5 -5
- package/schemas/VersioningSchemas.js +1 -1
|
@@ -106,7 +106,7 @@ var Changelog = class {
|
|
|
106
106
|
* Pass `null` to use defaults (no GitHub link resolution).
|
|
107
107
|
* @returns A promise resolving to the formatted markdown string
|
|
108
108
|
*/
|
|
109
|
-
static formatReleaseLine(changeset, versionType, options) {
|
|
109
|
+
static async formatReleaseLine(changeset, versionType, options) {
|
|
110
110
|
return changelogFunctions.getReleaseLine(changeset, versionType, options);
|
|
111
111
|
}
|
|
112
112
|
/**
|
|
@@ -125,7 +125,7 @@ var Changelog = class {
|
|
|
125
125
|
* @returns A promise resolving to the formatted markdown string containing
|
|
126
126
|
* the dependency update table
|
|
127
127
|
*/
|
|
128
|
-
static formatDependencyReleaseLine(changesets, dependenciesUpdated, options) {
|
|
128
|
+
static async formatDependencyReleaseLine(changesets, dependenciesUpdated, options) {
|
|
129
129
|
return changelogFunctions.getDependencyReleaseLine(changesets, dependenciesUpdated, options);
|
|
130
130
|
}
|
|
131
131
|
};
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { IssueLinkRefsPlugin } from "../remark/plugins/issue-link-refs.js";
|
|
4
|
-
import { MergeSectionsPlugin } from "../remark/plugins/merge-sections.js";
|
|
5
|
-
import { NormalizeFormatPlugin } from "../remark/plugins/normalize-format.js";
|
|
6
|
-
import { ReorderSectionsPlugin } from "../remark/plugins/reorder-sections.js";
|
|
1
|
+
import { MaintenanceNotePlugin } from "../remark/plugins/maintenance-note.js";
|
|
2
|
+
import { SilkChangesetTransformPreset } from "../remark/presets.js";
|
|
7
3
|
import remarkGfm from "remark-gfm";
|
|
8
4
|
import remarkParse from "remark-parse";
|
|
9
5
|
import remarkStringify from "remark-stringify";
|
|
@@ -24,23 +20,13 @@ import { readFileSync, writeFileSync } from "node:fs";
|
|
|
24
20
|
* Static class for post-processing CHANGELOG.md files.
|
|
25
21
|
*
|
|
26
22
|
* Implements the third layer of the three-layer pipeline by running
|
|
27
|
-
*
|
|
28
|
-
* and enhance changelog output produced
|
|
23
|
+
* the {@link SilkChangesetTransformPreset} plugins (currently seven) in a
|
|
24
|
+
* fixed order to clean up, normalize, and enhance changelog output produced
|
|
25
|
+
* by the formatter layer.
|
|
29
26
|
*
|
|
30
27
|
* @remarks
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* 1. **MergeSectionsPlugin** -- merges duplicate section headings (e.g., two
|
|
34
|
-
* "Features" sections from separate changesets are combined into one)
|
|
35
|
-
* 2. **ReorderSectionsPlugin** -- reorders sections by category priority
|
|
36
|
-
* (Breaking Changes first, Other last) using the {@link Categories} priority values
|
|
37
|
-
* 3. **DeduplicateItemsPlugin** -- removes duplicate list items within a section
|
|
38
|
-
* 4. **ContributorFootnotesPlugin** -- converts inline contributor mentions
|
|
39
|
-
* into footnote references for cleaner formatting
|
|
40
|
-
* 5. **IssueLinkRefsPlugin** -- converts inline issue/PR links into markdown
|
|
41
|
-
* reference-style links collected at the bottom of the document
|
|
42
|
-
* 6. **NormalizeFormatPlugin** -- applies consistent formatting (spacing,
|
|
43
|
-
* trailing newlines, heading levels)
|
|
28
|
+
* See {@link SilkChangesetTransformPreset} for the ordered plugin list and
|
|
29
|
+
* the rationale behind each plugin's position.
|
|
44
30
|
*
|
|
45
31
|
* The transformer operates on the full CHANGELOG.md content (all versions),
|
|
46
32
|
* not just the latest release block. It is idempotent -- running it multiple
|
|
@@ -100,20 +86,27 @@ var ChangelogTransformer = class ChangelogTransformer {
|
|
|
100
86
|
/* v8 ignore next -- private constructor prevents direct instantiation */
|
|
101
87
|
constructor() {}
|
|
102
88
|
/**
|
|
103
|
-
* Transform CHANGELOG markdown content by running
|
|
89
|
+
* Transform CHANGELOG markdown content by running the
|
|
90
|
+
* {@link SilkChangesetTransformPreset} plugins.
|
|
104
91
|
*
|
|
105
92
|
* @remarks
|
|
106
93
|
* The input is parsed with `remark-parse` and `remark-gfm` (for table
|
|
107
|
-
* support), processed through
|
|
108
|
-
* back to markdown. The operation is synchronous
|
|
94
|
+
* support), processed through every plugin in {@link SilkChangesetTransformPreset}
|
|
95
|
+
* in order, and stringified back to markdown. The operation is synchronous
|
|
96
|
+
* and idempotent.
|
|
109
97
|
*
|
|
110
98
|
* @param content - Raw CHANGELOG markdown string (may contain multiple
|
|
111
99
|
* version blocks, GFM tables, footnotes, and reference links)
|
|
112
|
-
* @
|
|
113
|
-
*
|
|
100
|
+
* @param options - Optional transformation options, including maintenance note configuration
|
|
101
|
+
* @returns The transformed markdown string with dependency tables aggregated,
|
|
102
|
+
* sections merged, reordered, deduplicated, and normalized
|
|
114
103
|
*/
|
|
115
|
-
static transformContent(content) {
|
|
116
|
-
const
|
|
104
|
+
static transformContent(content, options) {
|
|
105
|
+
const processor = unified().use(remarkParse).use(remarkGfm);
|
|
106
|
+
for (const plugin of SilkChangesetTransformPreset) processor.use(plugin);
|
|
107
|
+
if (options?.maintenance) processor.use(MaintenanceNotePlugin, options.maintenance);
|
|
108
|
+
processor.use(remarkStringify);
|
|
109
|
+
const file = processor.processSync(content);
|
|
117
110
|
return String(file);
|
|
118
111
|
}
|
|
119
112
|
/**
|
|
@@ -129,10 +122,11 @@ var ChangelogTransformer = class ChangelogTransformer {
|
|
|
129
122
|
* when invoked without the `--dry-run` or `--check` flags.
|
|
130
123
|
*
|
|
131
124
|
* @param filePath - Absolute or relative path to the CHANGELOG.md file
|
|
125
|
+
* @param options - Optional transformation options, including maintenance note configuration
|
|
132
126
|
*/
|
|
133
|
-
static transformFile(filePath) {
|
|
127
|
+
static transformFile(filePath, options) {
|
|
134
128
|
const content = readFileSync(filePath, "utf-8");
|
|
135
|
-
writeFileSync(filePath, ChangelogTransformer.transformContent(content), "utf-8");
|
|
129
|
+
writeFileSync(filePath, ChangelogTransformer.transformContent(content, options), "utf-8");
|
|
136
130
|
}
|
|
137
131
|
};
|
|
138
132
|
|
|
@@ -26,8 +26,8 @@ const ISSUE_CATEGORIES = [
|
|
|
26
26
|
/**
|
|
27
27
|
* Format a changelog entry into a markdown string with GitHub links.
|
|
28
28
|
*
|
|
29
|
-
* Produces
|
|
30
|
-
*
|
|
29
|
+
* Produces the summary text followed by any issue references, each
|
|
30
|
+
* rendered as GitHub links.
|
|
31
31
|
*
|
|
32
32
|
* @remarks
|
|
33
33
|
* The output does **not** include a leading `- ` list marker — the caller
|
|
@@ -37,13 +37,11 @@ const ISSUE_CATEGORIES = [
|
|
|
37
37
|
*
|
|
38
38
|
* Output format examples:
|
|
39
39
|
*
|
|
40
|
-
*
|
|
40
|
+
* Without issues: `Summary text`
|
|
41
41
|
*
|
|
42
42
|
* With issues: `Summary text` followed by `Closes: [#1](issue-url)`
|
|
43
43
|
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* @param entry - The changelog entry containing commit, summary, and issue data
|
|
44
|
+
* @param entry - The changelog entry containing summary and issue data
|
|
47
45
|
* @param options - Must include `repo` in `owner/repo` format for link generation
|
|
48
46
|
* @returns Formatted markdown string (without leading `- `)
|
|
49
47
|
*
|
|
@@ -51,10 +49,6 @@ const ISSUE_CATEGORIES = [
|
|
|
51
49
|
*/
|
|
52
50
|
function formatChangelogEntry(entry, options) {
|
|
53
51
|
const parts = [];
|
|
54
|
-
if (entry.commit) {
|
|
55
|
-
const shortHash = entry.commit.substring(0, 7);
|
|
56
|
-
parts.push(`[\`${shortHash}\`](https://github.com/${options.repo}/commit/${entry.commit})`);
|
|
57
|
-
}
|
|
58
52
|
parts.push(entry.summary.trim());
|
|
59
53
|
const issueLinks = [];
|
|
60
54
|
for (const { key, label } of ISSUE_CATEGORIES) {
|
|
@@ -15,11 +15,14 @@ import { Effect } from "effect";
|
|
|
15
15
|
* handles the "Updated dependencies" section that Changesets appends
|
|
16
16
|
* when a package's dependencies are bumped as part of a release.
|
|
17
17
|
*
|
|
18
|
-
* The output is a
|
|
19
|
-
* `Dependency`, `Type`,
|
|
20
|
-
* is inferred from the
|
|
21
|
-
*
|
|
22
|
-
* `optionalDependencies`) via
|
|
18
|
+
* The output is a `### Dependencies` h3 heading followed by a GFM
|
|
19
|
+
* (GitHub Flavored Markdown) table with columns: `Dependency`, `Type`,
|
|
20
|
+
* `Action`, `From`, `To`. The dependency type is inferred from the
|
|
21
|
+
* consuming package's `package.json` fields (`dependencies`,
|
|
22
|
+
* `devDependencies`, `peerDependencies`, `optionalDependencies`) via
|
|
23
|
+
* the {@link inferDependencyType} helper. Downstream, the heading is
|
|
24
|
+
* consumed by `AggregateDependencyTablesPlugin`, which locates and
|
|
25
|
+
* merges per-package dependency tables during changelog assembly.
|
|
23
26
|
*
|
|
24
27
|
* ### Dependency type inference
|
|
25
28
|
*
|
|
@@ -85,7 +88,8 @@ function inferDependencyType(dep) {
|
|
|
85
88
|
* The function maps each `ModCompWithPackage` entry to a `DependencyTableRow`,
|
|
86
89
|
* inferring the dependency type from the consuming package's `package.json`,
|
|
87
90
|
* then delegates to `serializeDependencyTableToMarkdown` for GFM table
|
|
88
|
-
* rendering
|
|
91
|
+
* rendering, prefixed with a `### Dependencies` heading. Returns an empty
|
|
92
|
+
* string when no dependencies were updated.
|
|
89
93
|
*
|
|
90
94
|
* The `_changesets` and `_options` parameters are part of the Changesets API
|
|
91
95
|
* contract but are not used in the table format. They are retained for
|
|
@@ -94,19 +98,19 @@ function inferDependencyType(dep) {
|
|
|
94
98
|
* @param _changesets - Changesets that caused the dependency updates (unused in table format)
|
|
95
99
|
* @param dependenciesUpdated - The list of dependencies that were updated, including old/new versions
|
|
96
100
|
* @param _options - Validated configuration options (unused in table format)
|
|
97
|
-
* @returns An `Effect` that resolves to a formatted markdown table string, or empty string if no dependencies were updated
|
|
101
|
+
* @returns An `Effect` that resolves to a `### Dependencies` heading followed by a formatted markdown table string, or empty string if no dependencies were updated
|
|
98
102
|
*/
|
|
99
103
|
function getDependencyReleaseLine(_changesets, dependenciesUpdated, _options) {
|
|
100
104
|
return Effect.gen(function* () {
|
|
101
105
|
if (dependenciesUpdated.length === 0) return "";
|
|
102
106
|
yield* GitHubService;
|
|
103
|
-
return serializeDependencyTableToMarkdown(dependenciesUpdated.map((dep) => ({
|
|
107
|
+
return `### Dependencies\n\n${serializeDependencyTableToMarkdown(dependenciesUpdated.map((dep) => ({
|
|
104
108
|
dependency: dep.name,
|
|
105
109
|
type: inferDependencyType(dep),
|
|
106
110
|
action: "updated",
|
|
107
111
|
from: dep.oldVersion,
|
|
108
112
|
to: dep.newVersion
|
|
109
|
-
})))
|
|
113
|
+
})))}`;
|
|
110
114
|
});
|
|
111
115
|
}
|
|
112
116
|
|
|
@@ -21,7 +21,7 @@ import { Effect, Schema } from "effect";
|
|
|
21
21
|
*
|
|
22
22
|
* 1. **Section-aware changesets** — When the changeset summary contains h2
|
|
23
23
|
* headings (e.g., `## Features`, `## Bug Fixes`), each section is rendered
|
|
24
|
-
* as an h3 heading with
|
|
24
|
+
* as an h3 heading with list items beneath it. This mode
|
|
25
25
|
* produces multi-line output suitable for rich changelogs.
|
|
26
26
|
*
|
|
27
27
|
* 2. **Flat-text changesets** — When the summary is plain text without section
|
|
@@ -31,7 +31,6 @@ import { Effect, Schema } from "effect";
|
|
|
31
31
|
*
|
|
32
32
|
* In both modes, the formatter:
|
|
33
33
|
* - Fetches GitHub metadata (PR number, author) via {@link GitHubService}
|
|
34
|
-
* - Generates shortened commit hash links (`[abc1234](...)`)
|
|
35
34
|
* - Extracts and renders issue references (Closes, Fixes, Refs)
|
|
36
35
|
* - Appends PR and user attribution when available
|
|
37
36
|
*
|
|
@@ -62,7 +61,7 @@ import { Effect, Schema } from "effect";
|
|
|
62
61
|
* `Fixes #N`, and `Refs #N` patterns.
|
|
63
62
|
* 5. **Build attribution** — Format PR link and user credit from GitHub info.
|
|
64
63
|
* 6. **Section-aware output** — If sections were found, render each as an
|
|
65
|
-
* h3 heading with
|
|
64
|
+
* h3 heading with list items.
|
|
66
65
|
* 7. **Flat-text fallback** — Otherwise, produce a single `- entry` line
|
|
67
66
|
* with the resolved category heading.
|
|
68
67
|
*
|
|
@@ -96,14 +95,16 @@ function getReleaseLine(changeset, versionType, options) {
|
|
|
96
95
|
for (const section of parsed.sections) {
|
|
97
96
|
lines.push(`### ${section.category.heading}`);
|
|
98
97
|
lines.push("");
|
|
99
|
-
const commitPrefix = changeset.commit ? `[\`${changeset.commit.substring(0, 7)}\`](https://github.com/${options.repo}/commit/${changeset.commit}) ` : "";
|
|
100
98
|
if (section.content) {
|
|
101
99
|
const contentLines = section.content.split("\n");
|
|
102
100
|
const firstContentLine = contentLines[0];
|
|
103
101
|
if (firstContentLine.startsWith("- ") || firstContentLine.startsWith("* ")) {
|
|
104
|
-
lines.push(
|
|
102
|
+
lines.push(firstContentLine);
|
|
105
103
|
lines.push(...contentLines.slice(1));
|
|
106
|
-
} else
|
|
104
|
+
} else {
|
|
105
|
+
lines.push(`- ${firstContentLine}`);
|
|
106
|
+
lines.push(...contentLines.slice(1).map((line) => line.length > 0 ? ` ${line}` : line));
|
|
107
|
+
}
|
|
107
108
|
}
|
|
108
109
|
lines.push("");
|
|
109
110
|
}
|
|
@@ -112,8 +113,7 @@ function getReleaseLine(changeset, versionType, options) {
|
|
|
112
113
|
return `- ${formatChangelogEntry({
|
|
113
114
|
type: resolveCommitType(commitMsg.type ?? versionType, commitMsg.scope, commitMsg.breaking).heading,
|
|
114
115
|
summary: changeset.summary,
|
|
115
|
-
issues: issueRefs
|
|
116
|
-
...changeset.commit ? { commit: changeset.commit } : {}
|
|
116
|
+
issues: issueRefs
|
|
117
117
|
}, { repo: options.repo })}${attribution}`;
|
|
118
118
|
});
|
|
119
119
|
}
|
|
@@ -40,7 +40,7 @@ import { Effect, Layer } from "effect";
|
|
|
40
40
|
* config is decoded through `ChangesetOptionsSchema`.
|
|
41
41
|
* 2. **Release line formatting** — each changeset is formatted by
|
|
42
42
|
* `getReleaseLine`, which resolves GitHub metadata, parses sections,
|
|
43
|
-
* and produces structured markdown with
|
|
43
|
+
* and produces structured markdown with attribution.
|
|
44
44
|
* 3. **Dependency table formatting** — bulk dependency updates are
|
|
45
45
|
* formatted by `getDependencyReleaseLine` into a markdown table.
|
|
46
46
|
*
|
package/changesets/index.js
CHANGED
|
@@ -19,12 +19,15 @@ import { HeadingHierarchyRule } from "./remark/rules/heading-hierarchy.js";
|
|
|
19
19
|
import { RequiredSectionsRule } from "./remark/rules/required-sections.js";
|
|
20
20
|
import { UncategorizedContentRule } from "./remark/rules/uncategorized-content.js";
|
|
21
21
|
import { ChangesetLinter } from "./api/linter.js";
|
|
22
|
+
import { MaintenanceNotePlugin } from "./remark/plugins/maintenance-note.js";
|
|
23
|
+
import { AggregateDependencyTablesPlugin } from "./remark/plugins/aggregate-dependency-tables.js";
|
|
22
24
|
import { ContributorFootnotesPlugin } from "./remark/plugins/contributor-footnotes.js";
|
|
23
25
|
import { DeduplicateItemsPlugin } from "./remark/plugins/deduplicate-items.js";
|
|
24
26
|
import { IssueLinkRefsPlugin } from "./remark/plugins/issue-link-refs.js";
|
|
25
27
|
import { MergeSectionsPlugin } from "./remark/plugins/merge-sections.js";
|
|
26
28
|
import { NormalizeFormatPlugin } from "./remark/plugins/normalize-format.js";
|
|
27
29
|
import { ReorderSectionsPlugin } from "./remark/plugins/reorder-sections.js";
|
|
30
|
+
import { SilkChangesetPreset, SilkChangesetTransformPreset } from "./remark/presets.js";
|
|
28
31
|
import { ChangelogTransformer } from "./api/transformer.js";
|
|
29
32
|
import { ClassificationReasonSchema, ClassificationSchema, ConfigInspector, ConfigInspectorBase, ConfigInspectorLive, InspectedConfigSchema, ResolvedPackageScopeSchema, ResolvedVersionFileSchema, makeConfigInspectorTest } from "./services/config-inspector.js";
|
|
30
33
|
import { BranchAnalysisSchema, BranchAnalyzer, BranchAnalyzerBase, BranchAnalyzerLive, BranchFileEntrySchema, FileStatusSchema, makeBranchAnalyzerTest } from "./services/branch-analyzer.js";
|
|
@@ -33,6 +36,7 @@ import { computeWorkspaceDependencyDiffs } from "./utils/dep-diff.js";
|
|
|
33
36
|
import { gitMergeBase } from "./utils/git.js";
|
|
34
37
|
import { listPublishablePackageNames } from "./utils/publishability.js";
|
|
35
38
|
import { DepsRegen, DepsRegenBase, DepsRegenDefault, DepsRegenLive, isPureDependencyChangeset } from "./services/deps-regen.js";
|
|
39
|
+
import { MaintenanceReasonSchema, MaintenanceTriggerSchema, deriveMaintenanceReason } from "./services/maintenance-reason.js";
|
|
36
40
|
import { VersionFiles } from "./utils/version-files.js";
|
|
37
41
|
import { ReleasePlanner, ReleasePlannerBase, ReleasePlannerLive, makeReleasePlannerTest } from "./services/release-planner.js";
|
|
38
42
|
import { SectionCategorySchema } from "./categories/types.js";
|
|
@@ -45,8 +49,6 @@ import { HeadingHierarchyRule as HeadingHierarchyRule$1 } from "./markdownlint/r
|
|
|
45
49
|
import { RequiredSectionsRule as RequiredSectionsRule$1 } from "./markdownlint/rules/required-sections.js";
|
|
46
50
|
import { UncategorizedContentRule as UncategorizedContentRule$1 } from "./markdownlint/rules/uncategorized-content.js";
|
|
47
51
|
import SilkChangesetsRules from "./markdownlint/index.js";
|
|
48
|
-
import { AggregateDependencyTablesPlugin } from "./remark/plugins/aggregate-dependency-tables.js";
|
|
49
|
-
import { SilkChangesetPreset, SilkChangesetTransformPreset } from "./remark/presets.js";
|
|
50
52
|
|
|
51
53
|
//#region src/changesets/index.ts
|
|
52
54
|
var changesets_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -113,6 +115,9 @@ var changesets_exports = /* @__PURE__ */ __exportAll({
|
|
|
113
115
|
JsonPathSchema: () => JsonPathSchema,
|
|
114
116
|
LegacyVersionFileConfigSchema: () => LegacyVersionFileConfigSchema,
|
|
115
117
|
LegacyVersionFilesSchema: () => LegacyVersionFilesSchema,
|
|
118
|
+
MaintenanceNotePlugin: () => MaintenanceNotePlugin,
|
|
119
|
+
MaintenanceReasonSchema: () => MaintenanceReasonSchema,
|
|
120
|
+
MaintenanceTriggerSchema: () => MaintenanceTriggerSchema,
|
|
116
121
|
MarkdownLive: () => MarkdownLive,
|
|
117
122
|
MarkdownParseError: () => MarkdownParseError,
|
|
118
123
|
MarkdownParseErrorBase: () => MarkdownParseErrorBase,
|
|
@@ -159,6 +164,7 @@ var changesets_exports = /* @__PURE__ */ __exportAll({
|
|
|
159
164
|
VersionTypeSchema: () => VersionTypeSchema,
|
|
160
165
|
changelogFunctions: () => changelogFunctions,
|
|
161
166
|
computeWorkspaceDependencyDiffs: () => computeWorkspaceDependencyDiffs,
|
|
167
|
+
deriveMaintenanceReason: () => deriveMaintenanceReason,
|
|
162
168
|
gitMergeBase: () => gitMergeBase,
|
|
163
169
|
isPureDependencyChangeset: () => isPureDependencyChangeset,
|
|
164
170
|
listPublishablePackageNames: () => listPublishablePackageNames,
|
|
@@ -170,4 +176,4 @@ var changesets_exports = /* @__PURE__ */ __exportAll({
|
|
|
170
176
|
});
|
|
171
177
|
|
|
172
178
|
//#endregion
|
|
173
|
-
export { AggregateDependencyTablesPlugin, AppliedReleaseEntrySchema, AppliedReleaseSchema, BranchAnalysisSchema, BranchAnalyzer, BranchAnalyzerBase, BranchAnalyzerLive, BranchFileEntrySchema, BumpTypeSchema, Categories, Changelog, ChangelogService, ChangelogServiceBase, ChangelogTransformer, ChangesetIOError, ChangesetIOErrorBase, ChangesetLinter, ChangesetOptionsSchema, ChangesetPreviewSchema, ChangesetSchema, ChangesetSummarySchema, ChangesetValidationError, ChangesetValidationErrorBase, ClassificationReasonSchema, ClassificationSchema, CommitHashSchema, ConfigInspector, ConfigInspectorBase, ConfigInspectorLive, ConfigurationError, ConfigurationErrorBase, ContentStructureRule, ContributorFootnotesPlugin, DeduplicateItemsPlugin, DependencyActionSchema, DependencyTable, DependencyTableFormatRule, DependencyTableRowSchema, DependencyTableSchema, DependencyTableTypeSchema, DependencyTypeSchema, DependencyUpdateSchema, DepsRegen, DepsRegenBase, DepsRegenDefault, DepsRegenLive, FileStatusSchema, GitError, GitErrorBase, GitHubApiError, GitHubApiErrorBase, GitHubInfoSchema, GitHubLive, GitHubService, GitHubServiceBase, GlobSchema, HeadingHierarchyRule, InspectedConfigSchema, IssueLinkRefsPlugin, IssueNumberSchema, JsonPathSchema, LegacyVersionFileConfigSchema, LegacyVersionFilesSchema, MarkdownLive, MarkdownParseError, MarkdownParseErrorBase, MarkdownService, MarkdownServiceBase, ContentStructureRule$1 as MarkdownlintContentStructureRule, DependencyTableFormatRule$1 as MarkdownlintDependencyTableFormatRule, HeadingHierarchyRule$1 as MarkdownlintHeadingHierarchyRule, RequiredSectionsRule$1 as MarkdownlintRequiredSectionsRule, UncategorizedContentRule$1 as MarkdownlintUncategorizedContentRule, MergeSectionsPlugin, NonEmptyString, NormalizeFormatPlugin, PackageScopeSchema, PackagesRecordSchema, PendingChangesetSchema, PositiveInteger, PreviewReleaseSchema, ReleasePlanError, ReleasePlanErrorBase, ReleasePlanner, ReleasePlannerBase, ReleasePlannerLive, ReorderSectionsPlugin, RepoSchema, RequiredSectionsRule, ResolvedPackageScopeSchema, ResolvedVersionFileSchema, SectionCategorySchema, SilkChangesetPreset, SilkChangesetTransformPreset, SilkChangesetsRules, UncategorizedContentRule, UrlOrMarkdownLinkSchema, UsernameSchema, VERSION_RE, VersionFileConfigSchema, VersionFileError, VersionFileErrorBase, VersionFileUpdateRecordSchema, VersionFiles, VersionFilesSchema, VersionOrEmptySchema, VersionTypeSchema, changelogFunctions, changesets_exports, computeWorkspaceDependencyDiffs, gitMergeBase, isPureDependencyChangeset, listPublishablePackageNames, makeBranchAnalyzerTest, makeConfigInspectorTest, makeGitHubTest, makeReleasePlannerTest, serializeDependencyTableToMarkdown };
|
|
179
|
+
export { AggregateDependencyTablesPlugin, AppliedReleaseEntrySchema, AppliedReleaseSchema, BranchAnalysisSchema, BranchAnalyzer, BranchAnalyzerBase, BranchAnalyzerLive, BranchFileEntrySchema, BumpTypeSchema, Categories, Changelog, ChangelogService, ChangelogServiceBase, ChangelogTransformer, ChangesetIOError, ChangesetIOErrorBase, ChangesetLinter, ChangesetOptionsSchema, ChangesetPreviewSchema, ChangesetSchema, ChangesetSummarySchema, ChangesetValidationError, ChangesetValidationErrorBase, ClassificationReasonSchema, ClassificationSchema, CommitHashSchema, ConfigInspector, ConfigInspectorBase, ConfigInspectorLive, ConfigurationError, ConfigurationErrorBase, ContentStructureRule, ContributorFootnotesPlugin, DeduplicateItemsPlugin, DependencyActionSchema, DependencyTable, DependencyTableFormatRule, DependencyTableRowSchema, DependencyTableSchema, DependencyTableTypeSchema, DependencyTypeSchema, DependencyUpdateSchema, DepsRegen, DepsRegenBase, DepsRegenDefault, DepsRegenLive, FileStatusSchema, GitError, GitErrorBase, GitHubApiError, GitHubApiErrorBase, GitHubInfoSchema, GitHubLive, GitHubService, GitHubServiceBase, GlobSchema, HeadingHierarchyRule, InspectedConfigSchema, IssueLinkRefsPlugin, IssueNumberSchema, JsonPathSchema, LegacyVersionFileConfigSchema, LegacyVersionFilesSchema, MaintenanceNotePlugin, MaintenanceReasonSchema, MaintenanceTriggerSchema, MarkdownLive, MarkdownParseError, MarkdownParseErrorBase, MarkdownService, MarkdownServiceBase, ContentStructureRule$1 as MarkdownlintContentStructureRule, DependencyTableFormatRule$1 as MarkdownlintDependencyTableFormatRule, HeadingHierarchyRule$1 as MarkdownlintHeadingHierarchyRule, RequiredSectionsRule$1 as MarkdownlintRequiredSectionsRule, UncategorizedContentRule$1 as MarkdownlintUncategorizedContentRule, MergeSectionsPlugin, NonEmptyString, NormalizeFormatPlugin, PackageScopeSchema, PackagesRecordSchema, PendingChangesetSchema, PositiveInteger, PreviewReleaseSchema, ReleasePlanError, ReleasePlanErrorBase, ReleasePlanner, ReleasePlannerBase, ReleasePlannerLive, ReorderSectionsPlugin, RepoSchema, RequiredSectionsRule, ResolvedPackageScopeSchema, ResolvedVersionFileSchema, SectionCategorySchema, SilkChangesetPreset, SilkChangesetTransformPreset, SilkChangesetsRules, UncategorizedContentRule, UrlOrMarkdownLinkSchema, UsernameSchema, VERSION_RE, VersionFileConfigSchema, VersionFileError, VersionFileErrorBase, VersionFileUpdateRecordSchema, VersionFiles, VersionFilesSchema, VersionOrEmptySchema, VersionTypeSchema, changelogFunctions, changesets_exports, computeWorkspaceDependencyDiffs, deriveMaintenanceReason, gitMergeBase, isPureDependencyChangeset, listPublishablePackageNames, makeBranchAnalyzerTest, makeConfigInspectorTest, makeGitHubTest, makeReleasePlannerTest, serializeDependencyTableToMarkdown };
|
|
@@ -7,16 +7,18 @@ const DeduplicateItemsPlugin = () => {
|
|
|
7
7
|
const blocks = getVersionBlocks(tree);
|
|
8
8
|
for (const block of blocks) {
|
|
9
9
|
const sections = getBlockSections(tree, block);
|
|
10
|
-
for (const section of sections)
|
|
11
|
-
if (node.type !== "list") continue;
|
|
12
|
-
const list = node;
|
|
10
|
+
for (const section of sections) {
|
|
13
11
|
const seen = /* @__PURE__ */ new Set();
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
for (const node of section.contentNodes) {
|
|
13
|
+
if (node.type !== "list") continue;
|
|
14
|
+
const list = node;
|
|
15
|
+
list.children = list.children.filter((item) => {
|
|
16
|
+
const text = toString(item);
|
|
17
|
+
if (seen.has(text)) return false;
|
|
18
|
+
seen.add(text);
|
|
19
|
+
return true;
|
|
20
|
+
});
|
|
21
|
+
}
|
|
20
22
|
}
|
|
21
23
|
}
|
|
22
24
|
tree.children = tree.children.filter((node) => {
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { getHeadingText, getVersionBlocks } from "../../utils/version-blocks.js";
|
|
2
|
+
|
|
3
|
+
//#region src/changesets/remark/plugins/maintenance-note.ts
|
|
4
|
+
function buildNoteChildren(reason) {
|
|
5
|
+
if (reason.kind === "unspecified" || reason.triggers.length === 0) return [{
|
|
6
|
+
type: "text",
|
|
7
|
+
value: "Version-only release to keep workspace versions consistent; no changes to this package."
|
|
8
|
+
}];
|
|
9
|
+
const label = reason.kind === "fixed" ? "fixed version group" : "linked version group";
|
|
10
|
+
const children = [{
|
|
11
|
+
type: "text",
|
|
12
|
+
value: "Released in lockstep with "
|
|
13
|
+
}];
|
|
14
|
+
reason.triggers.forEach((trigger, index) => {
|
|
15
|
+
if (index > 0) children.push({
|
|
16
|
+
type: "text",
|
|
17
|
+
value: ", "
|
|
18
|
+
});
|
|
19
|
+
children.push({
|
|
20
|
+
type: "inlineCode",
|
|
21
|
+
value: `${trigger.name}@${trigger.version}`
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
children.push({
|
|
25
|
+
type: "text",
|
|
26
|
+
value: ` (${label}).`
|
|
27
|
+
});
|
|
28
|
+
return children;
|
|
29
|
+
}
|
|
30
|
+
const MaintenanceNotePlugin = (options) => {
|
|
31
|
+
return (tree) => {
|
|
32
|
+
const block = getVersionBlocks(tree).find((b) => getHeadingText(tree.children[b.headingIndex]) === options.version);
|
|
33
|
+
if (!block) return;
|
|
34
|
+
if (block.endIndex > block.startIndex) return;
|
|
35
|
+
const heading = {
|
|
36
|
+
type: "heading",
|
|
37
|
+
depth: 3,
|
|
38
|
+
children: [{
|
|
39
|
+
type: "text",
|
|
40
|
+
value: "Maintenance"
|
|
41
|
+
}]
|
|
42
|
+
};
|
|
43
|
+
const list = {
|
|
44
|
+
type: "list",
|
|
45
|
+
ordered: false,
|
|
46
|
+
spread: false,
|
|
47
|
+
children: [{
|
|
48
|
+
type: "listItem",
|
|
49
|
+
spread: false,
|
|
50
|
+
children: [{
|
|
51
|
+
type: "paragraph",
|
|
52
|
+
children: buildNoteChildren(options.reason)
|
|
53
|
+
}]
|
|
54
|
+
}]
|
|
55
|
+
};
|
|
56
|
+
tree.children.splice(block.startIndex, 0, heading, list);
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
61
|
+
export { MaintenanceNotePlugin };
|
|
@@ -3,13 +3,13 @@ import { DependencyTableFormatRule } from "./rules/dependency-table-format.js";
|
|
|
3
3
|
import { HeadingHierarchyRule } from "./rules/heading-hierarchy.js";
|
|
4
4
|
import { RequiredSectionsRule } from "./rules/required-sections.js";
|
|
5
5
|
import { UncategorizedContentRule } from "./rules/uncategorized-content.js";
|
|
6
|
+
import { AggregateDependencyTablesPlugin } from "./plugins/aggregate-dependency-tables.js";
|
|
6
7
|
import { ContributorFootnotesPlugin } from "./plugins/contributor-footnotes.js";
|
|
7
8
|
import { DeduplicateItemsPlugin } from "./plugins/deduplicate-items.js";
|
|
8
9
|
import { IssueLinkRefsPlugin } from "./plugins/issue-link-refs.js";
|
|
9
10
|
import { MergeSectionsPlugin } from "./plugins/merge-sections.js";
|
|
10
11
|
import { NormalizeFormatPlugin } from "./plugins/normalize-format.js";
|
|
11
12
|
import { ReorderSectionsPlugin } from "./plugins/reorder-sections.js";
|
|
12
|
-
import { AggregateDependencyTablesPlugin } from "./plugins/aggregate-dependency-tables.js";
|
|
13
13
|
|
|
14
14
|
//#region src/changesets/remark/presets.ts
|
|
15
15
|
/**
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { ChangesetConfig } from "../../services/ChangesetConfig.js";
|
|
2
|
+
import { Schema } from "effect";
|
|
3
|
+
|
|
4
|
+
//#region src/changesets/services/maintenance-reason.ts
|
|
5
|
+
/**
|
|
6
|
+
* A group co-member whose own changesets forced this release.
|
|
7
|
+
*
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
const MaintenanceTriggerSchema = Schema.Struct({
|
|
11
|
+
/** Package name of the triggering co-member. */
|
|
12
|
+
name: Schema.String,
|
|
13
|
+
/** The co-member's new version in the same release plan. */
|
|
14
|
+
version: Schema.String
|
|
15
|
+
});
|
|
16
|
+
/**
|
|
17
|
+
* Why a package is releasing with no changesets of its own.
|
|
18
|
+
*
|
|
19
|
+
* @public
|
|
20
|
+
*/
|
|
21
|
+
const MaintenanceReasonSchema = Schema.Struct({
|
|
22
|
+
/** Coupling that forced the release; `"unspecified"` when undetermined. */
|
|
23
|
+
kind: Schema.Literal("fixed", "linked", "unspecified"),
|
|
24
|
+
/** Triggering co-members; empty for `"unspecified"`. */
|
|
25
|
+
triggers: Schema.Array(MaintenanceTriggerSchema)
|
|
26
|
+
});
|
|
27
|
+
/**
|
|
28
|
+
* Derive the {@link MaintenanceReason} for a release, or `undefined` when the
|
|
29
|
+
* release has its own changesets (not a maintenance release).
|
|
30
|
+
*
|
|
31
|
+
* @param release - The release to classify.
|
|
32
|
+
* @param plan - The full release plan (source of group co-members).
|
|
33
|
+
* @param config - Resolved changesets config (`fixed` / `linked` groups).
|
|
34
|
+
* @returns The reason, or `undefined` for releases with their own changesets.
|
|
35
|
+
*
|
|
36
|
+
* @remarks
|
|
37
|
+
* Group entries are matched with {@link ChangesetConfig.matches} — exact names
|
|
38
|
+
* and trailing `"@scope/*"` prefixes only, a subset of the micromatch globs
|
|
39
|
+
* changesets accepts. A group entry using richer glob syntax (e.g. `"pkg-*"`)
|
|
40
|
+
* will not match here; the release then degrades gracefully to the
|
|
41
|
+
* `"unspecified"` fallback sentence instead of naming its triggers.
|
|
42
|
+
*
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
function deriveMaintenanceReason(release, plan, config) {
|
|
46
|
+
if (release.changesets.length > 0) return void 0;
|
|
47
|
+
const groupKinds = [["fixed", config.fixed], ["linked", config.linked]];
|
|
48
|
+
for (const [kind, groups] of groupKinds) for (const group of groups) {
|
|
49
|
+
if (!group.some((pattern) => ChangesetConfig.matches(release.name, pattern))) continue;
|
|
50
|
+
const triggers = plan.releases.filter((r) => r.name !== release.name && r.changesets.length > 0 && group.some((pattern) => ChangesetConfig.matches(r.name, pattern))).map((r) => ({
|
|
51
|
+
name: r.name,
|
|
52
|
+
version: r.newVersion
|
|
53
|
+
}));
|
|
54
|
+
if (triggers.length > 0) return {
|
|
55
|
+
kind,
|
|
56
|
+
triggers
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
kind: "unspecified",
|
|
61
|
+
triggers: []
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
//#endregion
|
|
66
|
+
export { MaintenanceReasonSchema, MaintenanceTriggerSchema, deriveMaintenanceReason };
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { ReleasePlanError } from "../errors.js";
|
|
2
2
|
import { ChangelogTransformer } from "../api/transformer.js";
|
|
3
3
|
import { ConfigInspector } from "./config-inspector.js";
|
|
4
|
+
import { deriveMaintenanceReason } from "./maintenance-reason.js";
|
|
4
5
|
import { VersionFiles } from "../utils/version-files.js";
|
|
5
6
|
import { Context, Effect, Layer } from "effect";
|
|
6
|
-
import { isAbsolute, join, relative } from "node:path";
|
|
7
|
+
import { dirname, isAbsolute, join, relative } from "node:path";
|
|
7
8
|
import { FileSystem } from "@effect/platform";
|
|
8
|
-
import applyReleasePlan from "@changesets/apply-release-plan";
|
|
9
|
-
import {
|
|
10
|
-
import getReleasePlan from "@changesets/get-release-plan";
|
|
9
|
+
import { applyReleasePlan } from "@changesets/apply-release-plan";
|
|
10
|
+
import { readConfig } from "@changesets/config";
|
|
11
|
+
import { getReleasePlan } from "@changesets/get-release-plan";
|
|
11
12
|
import { getPackages } from "@manypkg/get-packages";
|
|
12
13
|
|
|
13
14
|
//#region src/changesets/services/release-planner.ts
|
|
@@ -23,37 +24,21 @@ import { getPackages } from "@manypkg/get-packages";
|
|
|
23
24
|
* (e.g. `getChangelogEntry`) is re-implemented.
|
|
24
25
|
*
|
|
25
26
|
*/
|
|
26
|
-
const
|
|
27
|
-
"yarn",
|
|
28
|
-
"bolt",
|
|
29
|
-
"pnpm",
|
|
30
|
-
"lerna",
|
|
31
|
-
"root"
|
|
32
|
-
]);
|
|
27
|
+
const errMsg = (e) => e instanceof Error ? e.message : String(e);
|
|
33
28
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* the engine never reads `tool` at runtime, only `root.dir`), and
|
|
39
|
-
* `rootDir`/`rootPackage` fold back into `root`.
|
|
29
|
+
* Read the changesets config, surfacing non-throwing `readConfig` errors as a
|
|
30
|
+
* thrown `Error` so callers inside `Effect.tryPromise` land on the existing
|
|
31
|
+
* `ReleasePlanError` mapping. Warnings are returned alongside the config so
|
|
32
|
+
* the caller can log them via the Effect runtime rather than console output.
|
|
40
33
|
*/
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
if (
|
|
34
|
+
async function loadConfig(root, packages) {
|
|
35
|
+
const configResult = await readConfig(root, packages);
|
|
36
|
+
if (configResult.config === void 0) throw new Error(`Invalid changeset config:\n${configResult.errors.join("\n")}`);
|
|
44
37
|
return {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
dir: rootPackage.dir,
|
|
48
|
-
packageJson: rootPackage.packageJson
|
|
49
|
-
},
|
|
50
|
-
packages: packages.map((p) => ({
|
|
51
|
-
dir: p.dir,
|
|
52
|
-
packageJson: p.packageJson
|
|
53
|
-
}))
|
|
38
|
+
config: configResult.config,
|
|
39
|
+
warnings: configResult.warnings
|
|
54
40
|
};
|
|
55
|
-
}
|
|
56
|
-
const errMsg = (e) => e instanceof Error ? e.message : String(e);
|
|
41
|
+
}
|
|
57
42
|
const _tag = Context.Tag("ReleasePlanner");
|
|
58
43
|
/**
|
|
59
44
|
* Base class for {@link ReleasePlanner}.
|
|
@@ -74,7 +59,7 @@ function makeShape(inspector, fs) {
|
|
|
74
59
|
})
|
|
75
60
|
});
|
|
76
61
|
const preview = (root) => previewEffect(root, fs);
|
|
77
|
-
const apply = (root, options) => applyEffect(root, options?.dryRun ?? false, inspector, fs);
|
|
62
|
+
const apply = (root, options) => applyEffect(root, options?.dryRun ?? false, options?.changelogModules, inspector, fs);
|
|
78
63
|
return {
|
|
79
64
|
plan,
|
|
80
65
|
preview,
|
|
@@ -114,6 +99,16 @@ function extractVersionBlock(changelog, version) {
|
|
|
114
99
|
}
|
|
115
100
|
return lines.slice(start, end).join("\n").trim();
|
|
116
101
|
}
|
|
102
|
+
/** Maintenance reasons for every changeset-less release in the plan, keyed by package name. */
|
|
103
|
+
function maintenanceReasons(plan, config) {
|
|
104
|
+
const reasons = /* @__PURE__ */ new Map();
|
|
105
|
+
for (const r of plan.releases) {
|
|
106
|
+
if (r.type === "none") continue;
|
|
107
|
+
const reason = deriveMaintenanceReason(r, plan, config);
|
|
108
|
+
if (reason) reasons.set(r.name, reason);
|
|
109
|
+
}
|
|
110
|
+
return reasons;
|
|
111
|
+
}
|
|
117
112
|
/**
|
|
118
113
|
* Render a non-destructive preview by redirecting every write into a
|
|
119
114
|
* scope-managed temp directory (cleaned up automatically when the scope
|
|
@@ -122,19 +117,26 @@ function extractVersionBlock(changelog, version) {
|
|
|
122
117
|
function previewEffect(root, fs) {
|
|
123
118
|
const program = Effect.gen(function* () {
|
|
124
119
|
const [plan, packages] = yield* Effect.tryPromise({
|
|
125
|
-
try: () => Promise.all([getReleasePlan(root),
|
|
120
|
+
try: () => Promise.all([getReleasePlan(root), getPackages(root)]),
|
|
126
121
|
catch: (e) => new ReleasePlanError({
|
|
127
122
|
phase: "preview",
|
|
128
123
|
reason: errMsg(e)
|
|
129
124
|
})
|
|
130
125
|
});
|
|
131
|
-
|
|
132
|
-
|
|
126
|
+
if (!packages.rootPackage) return yield* Effect.fail(new ReleasePlanError({
|
|
127
|
+
phase: "preview",
|
|
128
|
+
reason: `Workspace root has no package.json: ${root}`
|
|
129
|
+
}));
|
|
130
|
+
const rootPackage = packages.rootPackage;
|
|
131
|
+
const { config, warnings } = yield* Effect.tryPromise({
|
|
132
|
+
try: () => loadConfig(root, packages),
|
|
133
133
|
catch: (e) => new ReleasePlanError({
|
|
134
134
|
phase: "preview",
|
|
135
135
|
reason: errMsg(e)
|
|
136
136
|
})
|
|
137
137
|
});
|
|
138
|
+
yield* Effect.forEach(warnings, (w) => Effect.logWarning(w));
|
|
139
|
+
const reasonByName = maintenanceReasons(plan, config);
|
|
138
140
|
const preMode = plan.preState ? plan.preState.mode : null;
|
|
139
141
|
const changesets = plan.changesets.map((cs) => ({
|
|
140
142
|
id: cs.id,
|
|
@@ -152,7 +154,7 @@ function previewEffect(root, fs) {
|
|
|
152
154
|
};
|
|
153
155
|
const tempRoot = yield* fs.makeTempDirectoryScoped({ prefix: "silk-preview-" });
|
|
154
156
|
const mapDir = (dir) => {
|
|
155
|
-
const rel = relative(packages.
|
|
157
|
+
const rel = relative(packages.rootDir, dir);
|
|
156
158
|
if (rel.startsWith("..") || isAbsolute(rel)) return Effect.fail(new ReleasePlanError({
|
|
157
159
|
phase: "preview",
|
|
158
160
|
reason: `Package directory is outside the workspace root: ${dir}`
|
|
@@ -162,13 +164,12 @@ function previewEffect(root, fs) {
|
|
|
162
164
|
const tempDirs = yield* Effect.forEach(packages.packages, (p) => mapDir(p.dir));
|
|
163
165
|
const tempPackages = {
|
|
164
166
|
tool: packages.tool,
|
|
165
|
-
|
|
166
|
-
|
|
167
|
+
rootDir: tempRoot,
|
|
168
|
+
rootPackage: {
|
|
167
169
|
dir: tempRoot,
|
|
168
|
-
packageJson: structuredClone(
|
|
170
|
+
packageJson: structuredClone(rootPackage.packageJson)
|
|
169
171
|
},
|
|
170
172
|
packages: packages.packages.map((p, i) => ({
|
|
171
|
-
...p,
|
|
172
173
|
dir: tempDirs[i],
|
|
173
174
|
packageJson: structuredClone(p.packageJson)
|
|
174
175
|
}))
|
|
@@ -185,7 +186,7 @@ function previewEffect(root, fs) {
|
|
|
185
186
|
const realCl = join(p.dir, "CHANGELOG.md");
|
|
186
187
|
if (yield* fs.exists(realCl)) yield* fs.copyFile(realCl, join(tDir, "CHANGELOG.md"));
|
|
187
188
|
}
|
|
188
|
-
const rootCl = join(packages.
|
|
189
|
+
const rootCl = join(packages.rootDir, "CHANGELOG.md");
|
|
189
190
|
if (yield* fs.exists(rootCl)) yield* fs.copyFile(rootCl, join(tempRoot, "CHANGELOG.md"));
|
|
190
191
|
yield* Effect.tryPromise({
|
|
191
192
|
try: () => applyReleasePlan(plan, tempPackages, config, void 0, root),
|
|
@@ -196,15 +197,19 @@ function previewEffect(root, fs) {
|
|
|
196
197
|
});
|
|
197
198
|
const dirByName = /* @__PURE__ */ new Map();
|
|
198
199
|
for (const p of tempPackages.packages) dirByName.set(p.packageJson.name, p.dir);
|
|
199
|
-
if (tempPackages.
|
|
200
|
+
if (tempPackages.rootPackage?.packageJson.name) dirByName.set(tempPackages.rootPackage.packageJson.name, tempRoot);
|
|
200
201
|
const releases = [];
|
|
201
202
|
for (const r of releasesToRender) {
|
|
202
203
|
const dir = dirByName.get(r.name);
|
|
203
204
|
if (!dir) continue;
|
|
204
205
|
const clPath = join(dir, "CHANGELOG.md");
|
|
205
206
|
if (!(yield* fs.exists(clPath))) continue;
|
|
207
|
+
const reason = reasonByName.get(r.name);
|
|
206
208
|
yield* Effect.try({
|
|
207
|
-
try: () => ChangelogTransformer.transformFile(clPath
|
|
209
|
+
try: () => ChangelogTransformer.transformFile(clPath, reason ? { maintenance: {
|
|
210
|
+
version: r.newVersion,
|
|
211
|
+
reason
|
|
212
|
+
} } : void 0),
|
|
208
213
|
catch: (e) => new ReleasePlanError({
|
|
209
214
|
phase: "preview",
|
|
210
215
|
reason: errMsg(e)
|
|
@@ -235,15 +240,17 @@ function previewEffect(root, fs) {
|
|
|
235
240
|
function diskVersion(workspaceDir, fallback, fs) {
|
|
236
241
|
return fs.readFileString(join(workspaceDir, "package.json")).pipe(Effect.flatMap((raw) => Effect.try(() => JSON.parse(raw).version ?? fallback)), Effect.orElseSucceed(() => fallback));
|
|
237
242
|
}
|
|
238
|
-
function applyEffect(root, dryRun, inspector, fs) {
|
|
243
|
+
function applyEffect(root, dryRun, changelogModules, inspector, fs) {
|
|
239
244
|
return Effect.gen(function* () {
|
|
240
|
-
const { plan, packages, config } = yield* Effect.tryPromise({
|
|
245
|
+
const { plan, packages, config, warnings } = yield* Effect.tryPromise({
|
|
241
246
|
try: async () => {
|
|
242
|
-
const [plan, packages] = await Promise.all([getReleasePlan(root),
|
|
247
|
+
const [plan, packages] = await Promise.all([getReleasePlan(root), getPackages(root)]);
|
|
248
|
+
const { config, warnings } = await loadConfig(root, packages);
|
|
243
249
|
return {
|
|
244
250
|
plan,
|
|
245
251
|
packages,
|
|
246
|
-
config
|
|
252
|
+
config,
|
|
253
|
+
warnings
|
|
247
254
|
};
|
|
248
255
|
},
|
|
249
256
|
catch: (e) => new ReleasePlanError({
|
|
@@ -251,6 +258,29 @@ function applyEffect(root, dryRun, inspector, fs) {
|
|
|
251
258
|
reason: errMsg(e)
|
|
252
259
|
})
|
|
253
260
|
});
|
|
261
|
+
yield* Effect.forEach(warnings, (w) => Effect.logWarning(w));
|
|
262
|
+
let engineConfig = config;
|
|
263
|
+
if (changelogModules) {
|
|
264
|
+
engineConfig = {
|
|
265
|
+
...config,
|
|
266
|
+
format: false
|
|
267
|
+
};
|
|
268
|
+
if (Array.isArray(config.changelog)) {
|
|
269
|
+
const configuredId = config.changelog[0];
|
|
270
|
+
const mapped = changelogModules[configuredId];
|
|
271
|
+
if (mapped === void 0) {
|
|
272
|
+
const supported = Object.keys(changelogModules).join(", ");
|
|
273
|
+
return yield* Effect.fail(new ReleasePlanError({
|
|
274
|
+
phase: "apply",
|
|
275
|
+
reason: `changelog id "${configuredId}" is not in changelogModules (supported: ${supported})`
|
|
276
|
+
}));
|
|
277
|
+
}
|
|
278
|
+
engineConfig = {
|
|
279
|
+
...engineConfig,
|
|
280
|
+
changelog: [mapped, config.changelog[1]]
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
}
|
|
254
284
|
const releases = plan.releases.filter((r) => r.type !== "none").map((r) => ({
|
|
255
285
|
name: r.name,
|
|
256
286
|
type: r.type,
|
|
@@ -258,17 +288,33 @@ function applyEffect(root, dryRun, inspector, fs) {
|
|
|
258
288
|
newVersion: r.newVersion
|
|
259
289
|
}));
|
|
260
290
|
let touchedFiles = [];
|
|
261
|
-
if (!dryRun)
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
291
|
+
if (!dryRun) {
|
|
292
|
+
const reasonByName = maintenanceReasons(plan, config);
|
|
293
|
+
const versionByPkgName = new Map(plan.releases.map((r) => [r.name, r.newVersion]));
|
|
294
|
+
const nameByDir = /* @__PURE__ */ new Map();
|
|
295
|
+
for (const p of packages.packages) nameByDir.set(p.dir, p.packageJson.name);
|
|
296
|
+
if (packages.rootPackage?.packageJson.name) nameByDir.set(packages.rootDir, packages.rootPackage.packageJson.name);
|
|
297
|
+
touchedFiles = yield* Effect.tryPromise({
|
|
298
|
+
try: async () => {
|
|
299
|
+
const touched = await applyReleasePlan(plan, packages, engineConfig);
|
|
300
|
+
for (const f of touched) {
|
|
301
|
+
if (!f.endsWith("CHANGELOG.md")) continue;
|
|
302
|
+
const pkgName = nameByDir.get(dirname(f));
|
|
303
|
+
const reason = pkgName ? reasonByName.get(pkgName) : void 0;
|
|
304
|
+
const newVersion = pkgName ? versionByPkgName.get(pkgName) : void 0;
|
|
305
|
+
ChangelogTransformer.transformFile(f, reason && newVersion ? { maintenance: {
|
|
306
|
+
version: newVersion,
|
|
307
|
+
reason
|
|
308
|
+
} } : void 0);
|
|
309
|
+
}
|
|
310
|
+
return touched;
|
|
311
|
+
},
|
|
312
|
+
catch: (e) => new ReleasePlanError({
|
|
313
|
+
phase: "apply",
|
|
314
|
+
reason: errMsg(e)
|
|
315
|
+
})
|
|
316
|
+
});
|
|
317
|
+
}
|
|
272
318
|
const newVersionByName = new Map(plan.releases.map((r) => [r.name, r.newVersion]));
|
|
273
319
|
const inspected = yield* inspector.inspect(root).pipe(Effect.catchAll((error) => Effect.logWarning(`Skipping versionFiles update: ${errMsg(error)}`).pipe(Effect.as(null))));
|
|
274
320
|
let versionFileUpdates = [];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GitHubApiError } from "../errors.js";
|
|
2
2
|
import { Effect } from "effect";
|
|
3
|
-
import {
|
|
3
|
+
import { getCommitInfo } from "@changesets/get-github-info";
|
|
4
4
|
|
|
5
5
|
//#region src/changesets/vendor/github-info.ts
|
|
6
6
|
/**
|
|
@@ -9,8 +9,14 @@ import { getInfo } from "@changesets/get-github-info";
|
|
|
9
9
|
* @remarks
|
|
10
10
|
* Bridges the `\@changesets/get-github-info` package (which returns
|
|
11
11
|
* promises) into the Effect ecosystem. The {@link getGitHubInfo}
|
|
12
|
-
* function wraps the upstream `
|
|
13
|
-
*
|
|
12
|
+
* function wraps the upstream `getCommitInfo()` call in `Effect.tryPromise`,
|
|
13
|
+
* adapting its structured `CommitInfo | undefined` return back to the
|
|
14
|
+
* legacy {@link GitHubCommitInfo} shape and mapping failures (including a
|
|
15
|
+
* `not found` result) to {@link GitHubApiError}.
|
|
16
|
+
*
|
|
17
|
+
* The upstream v1 package added a `.env` fallback: it reads
|
|
18
|
+
* `GITHUB_TOKEN` from `process.env` directly when no token is otherwise
|
|
19
|
+
* configured, so the caller does not need to plumb one through.
|
|
14
20
|
*
|
|
15
21
|
* The {@link GitHubCommitInfo} type is the only item from this module
|
|
16
22
|
* that is part of the public API (re-exported from the package root).
|
|
@@ -24,9 +30,13 @@ import { getInfo } from "@changesets/get-github-info";
|
|
|
24
30
|
* Fetch GitHub info for a commit, wrapped in Effect.
|
|
25
31
|
*
|
|
26
32
|
* @remarks
|
|
27
|
-
* Calls the upstream `
|
|
28
|
-
* within `Effect.tryPromise
|
|
29
|
-
* to
|
|
33
|
+
* Calls the upstream `getCommitInfo()` from `\@changesets/get-github-info`
|
|
34
|
+
* within `Effect.tryPromise`, adapting its structured `CommitInfo`
|
|
35
|
+
* return to the legacy {@link GitHubCommitInfo} shape. An `undefined`
|
|
36
|
+
* result (commit or repo not found) is treated as a thrown error so it
|
|
37
|
+
* is mapped to the same {@link GitHubApiError} failure channel. Any
|
|
38
|
+
* thrown error is caught and mapped to a {@link GitHubApiError} with
|
|
39
|
+
* the operation set to `"getCommitInfo"`.
|
|
30
40
|
*
|
|
31
41
|
* Requires a `GITHUB_TOKEN` environment variable to be set for
|
|
32
42
|
* authenticated API access (the upstream library reads it directly).
|
|
@@ -39,13 +49,25 @@ import { getInfo } from "@changesets/get-github-info";
|
|
|
39
49
|
*/
|
|
40
50
|
function getGitHubInfo(params) {
|
|
41
51
|
return Effect.tryPromise({
|
|
42
|
-
try: () =>
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
52
|
+
try: async () => {
|
|
53
|
+
const info = await getCommitInfo({
|
|
54
|
+
commit: params.commit,
|
|
55
|
+
repo: params.repo
|
|
56
|
+
});
|
|
57
|
+
if (info === void 0) throw new Error(`commit ${params.commit} not found in ${params.repo}`);
|
|
58
|
+
return {
|
|
59
|
+
user: info.author?.login ?? null,
|
|
60
|
+
pull: info.pull?.number ?? null,
|
|
61
|
+
links: {
|
|
62
|
+
commit: info.commit.markdownLink,
|
|
63
|
+
pull: info.pull?.markdownLink ?? null,
|
|
64
|
+
user: info.author?.markdownLink ?? null
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
},
|
|
46
68
|
/* v8 ignore next 5 -- error mapping tested via GitHubService test layer */
|
|
47
69
|
catch: (error) => new GitHubApiError({
|
|
48
|
-
operation: "
|
|
70
|
+
operation: "getCommitInfo",
|
|
49
71
|
reason: error instanceof Error ? error.message : String(error)
|
|
50
72
|
})
|
|
51
73
|
});
|
package/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Context, Data, Effect, Equal, Hash, Layer, Option, Schema, Stream } from "effect";
|
|
2
|
+
import { Plugin } from "unified";
|
|
2
3
|
import { Command, CommandExecutor, FileSystem, Path } from "@effect/platform";
|
|
3
4
|
import { PackageManagerDetector, PointInTimeReadError, PointInTimeWorkspace, PublishConfig, PublishTarget, PublishabilityDetector, TopologicalSorter, WorkspaceDiscovery, WorkspaceDiscoveryError, WorkspacePackage, WorkspaceRoot, WorkspaceStateSnapshot } from "workspaces-effect";
|
|
4
|
-
import { Plugin } from "unified";
|
|
5
5
|
import { PlatformError } from "@effect/platform/Error";
|
|
6
6
|
|
|
7
7
|
//#region \0rolldown/runtime.js
|
|
@@ -284,7 +284,9 @@ declare class Categories {
|
|
|
284
284
|
static isValidHeading(heading: string): boolean;
|
|
285
285
|
}
|
|
286
286
|
//#endregion
|
|
287
|
-
//#region ../../node_modules/.pnpm/@changesets+types@
|
|
287
|
+
//#region ../../node_modules/.pnpm/@changesets+types@7.0.0-next.6/node_modules/@changesets/types/dist/index.d.mts
|
|
288
|
+
//#region src/index.d.ts
|
|
289
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
288
290
|
type VersionType$1 = "major" | "minor" | "patch" | "none";
|
|
289
291
|
type AccessType = "public" | "restricted";
|
|
290
292
|
type Release = {
|
|
@@ -333,8 +335,43 @@ type PackageJSON = {
|
|
|
333
335
|
access?: AccessType;
|
|
334
336
|
directory?: string;
|
|
335
337
|
registry?: string;
|
|
338
|
+
[registry: `${string}:registry`]: string;
|
|
339
|
+
};
|
|
340
|
+
};
|
|
341
|
+
type PackageGroup = ReadonlyArray<string>;
|
|
342
|
+
type Fixed = ReadonlyArray<PackageGroup>;
|
|
343
|
+
type Linked = ReadonlyArray<PackageGroup>;
|
|
344
|
+
interface PrivatePackages {
|
|
345
|
+
version: boolean;
|
|
346
|
+
tag: boolean;
|
|
347
|
+
}
|
|
348
|
+
type Config = {
|
|
349
|
+
changelog: false | readonly [string, null | Record<string, unknown>];
|
|
350
|
+
commit: false | readonly [string, null | Record<string, unknown>];
|
|
351
|
+
fixed: Fixed;
|
|
352
|
+
linked: Linked;
|
|
353
|
+
access: AccessType;
|
|
354
|
+
baseBranch: string;
|
|
355
|
+
changedFilePatterns: readonly string[];
|
|
356
|
+
/**
|
|
357
|
+
* The formatter to use to format changesets and changelogs. Set `false` to disable formatting.
|
|
358
|
+
* The default value of `"auto"` will auto-detect the formatter based on the project's configuration files.
|
|
359
|
+
*/
|
|
360
|
+
format: "auto" | "prettier" | "oxfmt" | "deno" | "dprint" | false; /** Features enabled for Private packages */
|
|
361
|
+
privatePackages: PrivatePackages; /** The minimum bump type to trigger automatic update of internal dependencies that are part of the same release */
|
|
362
|
+
updateInternalDependencies: "patch" | "minor";
|
|
363
|
+
ignore: ReadonlyArray<string>; /** This is supposed to be used with pnpm's `link-workspace-packages: false` and Berry's `enableTransparentWorkspaces: false` */
|
|
364
|
+
bumpVersionsWithWorkspaceProtocolOnly?: boolean;
|
|
365
|
+
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: Required<ExperimentalOptions>;
|
|
366
|
+
snapshot: {
|
|
367
|
+
useCalculatedVersion: boolean;
|
|
368
|
+
prereleaseTemplate: string | null;
|
|
336
369
|
};
|
|
337
370
|
};
|
|
371
|
+
type ExperimentalOptions = {
|
|
372
|
+
onlyUpdatePeerDependentsWhenOutOfRange?: boolean;
|
|
373
|
+
updateInternalDependents?: "always" | "out-of-range";
|
|
374
|
+
};
|
|
338
375
|
type NewChangesetWithCommit = NewChangeset & {
|
|
339
376
|
commit?: string;
|
|
340
377
|
};
|
|
@@ -342,8 +379,8 @@ type ModCompWithPackage = ComprehensiveRelease & {
|
|
|
342
379
|
packageJson: PackageJSON;
|
|
343
380
|
dir: string;
|
|
344
381
|
};
|
|
345
|
-
type GetReleaseLine = (changeset: NewChangesetWithCommit, type: VersionType$1, changelogOpts: null | Record<string,
|
|
346
|
-
type GetDependencyReleaseLine = (changesets: NewChangesetWithCommit[], dependenciesUpdated: ModCompWithPackage[], changelogOpts:
|
|
382
|
+
type GetReleaseLine = (changeset: NewChangesetWithCommit, type: VersionType$1, changelogOpts: null | Record<string, unknown>) => MaybePromise<string>;
|
|
383
|
+
type GetDependencyReleaseLine = (changesets: NewChangesetWithCommit[], dependenciesUpdated: ModCompWithPackage[], changelogOpts: null | Record<string, unknown>) => MaybePromise<string>;
|
|
347
384
|
type ChangelogFunctions = {
|
|
348
385
|
getReleaseLine: GetReleaseLine;
|
|
349
386
|
getDependencyReleaseLine: GetDependencyReleaseLine;
|
|
@@ -351,9 +388,6 @@ type ChangelogFunctions = {
|
|
|
351
388
|
type PreState = {
|
|
352
389
|
mode: "pre" | "exit";
|
|
353
390
|
tag: string;
|
|
354
|
-
initialVersions: {
|
|
355
|
-
[pkgName: string]: string;
|
|
356
|
-
};
|
|
357
391
|
changesets: string[];
|
|
358
392
|
};
|
|
359
393
|
//#endregion
|
|
@@ -2056,37 +2090,95 @@ declare class ChangesetLinter {
|
|
|
2056
2090
|
static validate(dir: string): LintMessage[];
|
|
2057
2091
|
}
|
|
2058
2092
|
//#endregion
|
|
2059
|
-
//#region src/changesets/
|
|
2093
|
+
//#region src/changesets/services/maintenance-reason.d.ts
|
|
2094
|
+
/**
|
|
2095
|
+
* A group co-member whose own changesets forced this release.
|
|
2096
|
+
*
|
|
2097
|
+
* @public
|
|
2098
|
+
*/
|
|
2099
|
+
declare const MaintenanceTriggerSchema: Schema.Struct<{
|
|
2100
|
+
/** Package name of the triggering co-member. */name: typeof Schema.String; /** The co-member's new version in the same release plan. */
|
|
2101
|
+
version: typeof Schema.String;
|
|
2102
|
+
}>;
|
|
2060
2103
|
/**
|
|
2061
|
-
*
|
|
2104
|
+
* A group co-member whose own changesets forced this release.
|
|
2062
2105
|
*
|
|
2063
|
-
*
|
|
2064
|
-
|
|
2065
|
-
|
|
2106
|
+
* @public
|
|
2107
|
+
*/
|
|
2108
|
+
type MaintenanceTrigger = typeof MaintenanceTriggerSchema.Type;
|
|
2109
|
+
/**
|
|
2110
|
+
* Why a package is releasing with no changesets of its own.
|
|
2066
2111
|
*
|
|
2067
|
-
* @
|
|
2112
|
+
* @public
|
|
2068
2113
|
*/
|
|
2114
|
+
declare const MaintenanceReasonSchema: Schema.Struct<{
|
|
2115
|
+
/** Coupling that forced the release; `"unspecified"` when undetermined. */kind: Schema.Literal<["fixed", "linked", "unspecified"]>; /** Triggering co-members; empty for `"unspecified"`. */
|
|
2116
|
+
triggers: Schema.Array$<Schema.Struct<{
|
|
2117
|
+
/** Package name of the triggering co-member. */name: typeof Schema.String; /** The co-member's new version in the same release plan. */
|
|
2118
|
+
version: typeof Schema.String;
|
|
2119
|
+
}>>;
|
|
2120
|
+
}>;
|
|
2121
|
+
/**
|
|
2122
|
+
* Why a package is releasing with no changesets of its own.
|
|
2123
|
+
*
|
|
2124
|
+
* @public
|
|
2125
|
+
*/
|
|
2126
|
+
type MaintenanceReason = typeof MaintenanceReasonSchema.Type;
|
|
2127
|
+
/**
|
|
2128
|
+
* Derive the {@link MaintenanceReason} for a release, or `undefined` when the
|
|
2129
|
+
* release has its own changesets (not a maintenance release).
|
|
2130
|
+
*
|
|
2131
|
+
* @param release - The release to classify.
|
|
2132
|
+
* @param plan - The full release plan (source of group co-members).
|
|
2133
|
+
* @param config - Resolved changesets config (`fixed` / `linked` groups).
|
|
2134
|
+
* @returns The reason, or `undefined` for releases with their own changesets.
|
|
2135
|
+
*
|
|
2136
|
+
* @remarks
|
|
2137
|
+
* Group entries are matched with {@link ChangesetConfig.matches} — exact names
|
|
2138
|
+
* and trailing `"@scope/*"` prefixes only, a subset of the micromatch globs
|
|
2139
|
+
* changesets accepts. A group entry using richer glob syntax (e.g. `"pkg-*"`)
|
|
2140
|
+
* will not match here; the release then degrades gracefully to the
|
|
2141
|
+
* `"unspecified"` fallback sentence instead of naming its triggers.
|
|
2142
|
+
*
|
|
2143
|
+
* @public
|
|
2144
|
+
*/
|
|
2145
|
+
declare function deriveMaintenanceReason(release: ComprehensiveRelease, plan: ReleasePlan, config: Config): MaintenanceReason | undefined;
|
|
2146
|
+
//#endregion
|
|
2147
|
+
//#region src/changesets/remark/plugins/maintenance-note.d.ts
|
|
2148
|
+
/**
|
|
2149
|
+
* Options for {@link MaintenanceNotePlugin}.
|
|
2150
|
+
*
|
|
2151
|
+
* @public
|
|
2152
|
+
*/
|
|
2153
|
+
interface MaintenanceNoteOptions {
|
|
2154
|
+
/** Version heading text to target (e.g. `"2.3.1"`). */
|
|
2155
|
+
readonly version: string;
|
|
2156
|
+
/** Why the package released with no changesets of its own. */
|
|
2157
|
+
readonly reason: MaintenanceReason;
|
|
2158
|
+
}
|
|
2159
|
+
declare const MaintenanceNotePlugin: Plugin<[MaintenanceNoteOptions], Root>;
|
|
2160
|
+
//#endregion
|
|
2161
|
+
//#region src/changesets/api/transformer.d.ts
|
|
2162
|
+
/**
|
|
2163
|
+
* Optional per-file behavior for {@link ChangelogTransformer}.
|
|
2164
|
+
*
|
|
2165
|
+
* @public
|
|
2166
|
+
*/
|
|
2167
|
+
interface TransformOptions {
|
|
2168
|
+
/** Insert a Maintenance note into this version block when it ends up empty. */
|
|
2169
|
+
readonly maintenance?: MaintenanceNoteOptions;
|
|
2170
|
+
}
|
|
2069
2171
|
/**
|
|
2070
2172
|
* Static class for post-processing CHANGELOG.md files.
|
|
2071
2173
|
*
|
|
2072
2174
|
* Implements the third layer of the three-layer pipeline by running
|
|
2073
|
-
*
|
|
2074
|
-
* and enhance changelog output produced
|
|
2175
|
+
* the {@link SilkChangesetTransformPreset} plugins (currently seven) in a
|
|
2176
|
+
* fixed order to clean up, normalize, and enhance changelog output produced
|
|
2177
|
+
* by the formatter layer.
|
|
2075
2178
|
*
|
|
2076
2179
|
* @remarks
|
|
2077
|
-
*
|
|
2078
|
-
*
|
|
2079
|
-
* 1. **MergeSectionsPlugin** -- merges duplicate section headings (e.g., two
|
|
2080
|
-
* "Features" sections from separate changesets are combined into one)
|
|
2081
|
-
* 2. **ReorderSectionsPlugin** -- reorders sections by category priority
|
|
2082
|
-
* (Breaking Changes first, Other last) using the {@link Categories} priority values
|
|
2083
|
-
* 3. **DeduplicateItemsPlugin** -- removes duplicate list items within a section
|
|
2084
|
-
* 4. **ContributorFootnotesPlugin** -- converts inline contributor mentions
|
|
2085
|
-
* into footnote references for cleaner formatting
|
|
2086
|
-
* 5. **IssueLinkRefsPlugin** -- converts inline issue/PR links into markdown
|
|
2087
|
-
* reference-style links collected at the bottom of the document
|
|
2088
|
-
* 6. **NormalizeFormatPlugin** -- applies consistent formatting (spacing,
|
|
2089
|
-
* trailing newlines, heading levels)
|
|
2180
|
+
* See {@link SilkChangesetTransformPreset} for the ordered plugin list and
|
|
2181
|
+
* the rationale behind each plugin's position.
|
|
2090
2182
|
*
|
|
2091
2183
|
* The transformer operates on the full CHANGELOG.md content (all versions),
|
|
2092
2184
|
* not just the latest release block. It is idempotent -- running it multiple
|
|
@@ -2145,19 +2237,22 @@ declare class ChangesetLinter {
|
|
|
2145
2237
|
declare class ChangelogTransformer {
|
|
2146
2238
|
private constructor();
|
|
2147
2239
|
/**
|
|
2148
|
-
* Transform CHANGELOG markdown content by running
|
|
2240
|
+
* Transform CHANGELOG markdown content by running the
|
|
2241
|
+
* {@link SilkChangesetTransformPreset} plugins.
|
|
2149
2242
|
*
|
|
2150
2243
|
* @remarks
|
|
2151
2244
|
* The input is parsed with `remark-parse` and `remark-gfm` (for table
|
|
2152
|
-
* support), processed through
|
|
2153
|
-
* back to markdown. The operation is synchronous
|
|
2245
|
+
* support), processed through every plugin in {@link SilkChangesetTransformPreset}
|
|
2246
|
+
* in order, and stringified back to markdown. The operation is synchronous
|
|
2247
|
+
* and idempotent.
|
|
2154
2248
|
*
|
|
2155
2249
|
* @param content - Raw CHANGELOG markdown string (may contain multiple
|
|
2156
2250
|
* version blocks, GFM tables, footnotes, and reference links)
|
|
2157
|
-
* @
|
|
2158
|
-
*
|
|
2251
|
+
* @param options - Optional transformation options, including maintenance note configuration
|
|
2252
|
+
* @returns The transformed markdown string with dependency tables aggregated,
|
|
2253
|
+
* sections merged, reordered, deduplicated, and normalized
|
|
2159
2254
|
*/
|
|
2160
|
-
static transformContent(content: string): string;
|
|
2255
|
+
static transformContent(content: string, options?: TransformOptions): string;
|
|
2161
2256
|
/**
|
|
2162
2257
|
* Transform a CHANGELOG file in-place.
|
|
2163
2258
|
*
|
|
@@ -2171,8 +2266,9 @@ declare class ChangelogTransformer {
|
|
|
2171
2266
|
* when invoked without the `--dry-run` or `--check` flags.
|
|
2172
2267
|
*
|
|
2173
2268
|
* @param filePath - Absolute or relative path to the CHANGELOG.md file
|
|
2269
|
+
* @param options - Optional transformation options, including maintenance note configuration
|
|
2174
2270
|
*/
|
|
2175
|
-
static transformFile(filePath: string): void;
|
|
2271
|
+
static transformFile(filePath: string, options?: TransformOptions): void;
|
|
2176
2272
|
}
|
|
2177
2273
|
//#endregion
|
|
2178
2274
|
//#region src/changesets/changelog/index.d.ts
|
|
@@ -2604,7 +2700,7 @@ declare class ChangesetConfigError extends ChangesetConfigError_base<{
|
|
|
2604
2700
|
//#endregion
|
|
2605
2701
|
//#region src/schemas/VersioningSchemas.d.ts
|
|
2606
2702
|
/**
|
|
2607
|
-
* Standard changesets configuration matching the `@changesets/config@
|
|
2703
|
+
* Standard changesets configuration matching the `@changesets/config@4.0.0-next.6` spec.
|
|
2608
2704
|
*
|
|
2609
2705
|
* @remarks
|
|
2610
2706
|
* Represents the parsed `.changeset/config.json` file. All fields are optional
|
|
@@ -3868,6 +3964,13 @@ interface ReleasePlannerShape {
|
|
|
3868
3964
|
/** Natively apply the release (destructive unless `dryRun`). */
|
|
3869
3965
|
readonly apply: (root: string, options?: {
|
|
3870
3966
|
readonly dryRun?: boolean;
|
|
3967
|
+
/**
|
|
3968
|
+
* Map configured changelog ids to absolute module paths. When set,
|
|
3969
|
+
* `config.changelog[0]` must be a key of this map (rewritten before the
|
|
3970
|
+
* engine call; unmapped ids fail) and the engine's `format` integration
|
|
3971
|
+
* is disabled — callers in no-`node_modules` contexts own formatting.
|
|
3972
|
+
*/
|
|
3973
|
+
readonly changelogModules?: Readonly<Record<string, string>>;
|
|
3871
3974
|
}) => Effect.Effect<AppliedRelease, ReleasePlanError>;
|
|
3872
3975
|
}
|
|
3873
3976
|
/**
|
|
@@ -5477,7 +5580,7 @@ declare const RequiredSectionsRule: import("unified-lint-rule").Plugin<Root, unk
|
|
|
5477
5580
|
//#region src/changesets/remark/rules/uncategorized-content.d.ts
|
|
5478
5581
|
declare const UncategorizedContentRule: import("unified-lint-rule").Plugin<Root, unknown>;
|
|
5479
5582
|
declare namespace index_d_exports {
|
|
5480
|
-
export { AggregateDependencyTablesPlugin, AppliedRelease, AppliedReleaseEntrySchema, AppliedReleaseSchema, BranchAnalysis, BranchAnalysisSchema, BranchAnalyzer, BranchAnalyzerBase, BranchAnalyzerLive, BranchAnalyzerShape, BranchFileEntry, BranchFileEntrySchema, BumpType, BumpTypeSchema, Categories, Changelog, ChangelogService, ChangelogServiceBase, ChangelogServiceShape, ChangelogTransformer, Changeset, ChangesetIOError, ChangesetIOErrorBase, ChangesetLinter, ChangesetOptions, ChangesetOptionsSchema, ChangesetPreview, ChangesetPreviewSchema, ChangesetSchema, ChangesetSummarySchema, ChangesetValidationError, ChangesetValidationErrorBase, Classification, ClassificationReason, ClassificationReasonSchema, ClassificationSchema, CommitHashSchema, ConfigInspector, ConfigInspectorBase, ConfigInspectorLive, ConfigInspectorShape, ConfigurationError, ConfigurationErrorBase, ContentStructureRule, ContributorFootnotesPlugin, DeduplicateItemsPlugin, DependencyAction, DependencyActionSchema, DependencyTable, DependencyTableFormatRule, DependencyTableRow, DependencyTableRowSchema, DependencyTableSchema, DependencyTableType, DependencyTableTypeSchema, DependencyType, DependencyTypeSchema, DependencyUpdate, DependencyUpdateSchema, DepsRegen, DepsRegenBase, DepsRegenDefault, DepsRegenLive, DepsRegenOptions, DepsRegenShape, FileStatus, FileStatusSchema, GitError, GitErrorBase, GitHubApiError, GitHubApiErrorBase, GitHubCommitInfo, GitHubInfo, GitHubInfoSchema, GitHubLive, GitHubService, GitHubServiceBase, GitHubServiceShape, GlobSchema, HeadingHierarchyRule, InspectedConfig, InspectedConfigSchema, IssueLinkRefsPlugin, IssueNumberSchema, JsonPathSchema, LegacyVersionFileConfig, LegacyVersionFileConfigSchema, LegacyVersionFilesSchema, LintMessage, MarkdownLive, MarkdownParseError, MarkdownParseErrorBase, MarkdownService, MarkdownServiceBase, MarkdownServiceShape, ContentStructureRule$1 as MarkdownlintContentStructureRule, DependencyTableFormatRule$1 as MarkdownlintDependencyTableFormatRule, HeadingHierarchyRule$1 as MarkdownlintHeadingHierarchyRule, RequiredSectionsRule$1 as MarkdownlintRequiredSectionsRule, UncategorizedContentRule$1 as MarkdownlintUncategorizedContentRule, MergeSectionsPlugin, NonEmptyString, NormalizeFormatPlugin, PackageScope, PackageScopeSchema, PackagesRecordSchema, PendingChangeset, PendingChangesetSchema, PositiveInteger, PreviewRelease, PreviewReleaseSchema, RegenPlan, RegenResult, ReleasePlanError, ReleasePlanErrorBase, ReleasePlanner, ReleasePlannerBase, ReleasePlannerLive, ReleasePlannerShape, ReorderSectionsPlugin, RepoSchema, RequiredSectionsRule, ResolvedPackageScope, ResolvedPackageScopeSchema, ResolvedVersionFile, ResolvedVersionFileSchema, SectionCategory, SectionCategorySchema, SilkChangesetPreset, SilkChangesetTransformPreset, SilkChangesetsRules, UncategorizedContentRule, UrlOrMarkdownLinkSchema, UsernameSchema, VERSION_RE, VersionFileConfig, VersionFileConfigSchema, VersionFileError, VersionFileErrorBase, VersionFileUpdate, VersionFileUpdateRecordSchema, VersionFiles, VersionFilesSchema, VersionOrEmptySchema, VersionType, VersionTypeSchema, WorkspaceDependencyDiff, WorkspaceVersion, changelogFunctions, computeWorkspaceDependencyDiffs, gitMergeBase, isPureDependencyChangeset, listPublishablePackageNames, makeBranchAnalyzerTest, makeConfigInspectorTest, makeGitHubTest, makeReleasePlannerTest, serializeDependencyTableToMarkdown };
|
|
5583
|
+
export { AggregateDependencyTablesPlugin, AppliedRelease, AppliedReleaseEntrySchema, AppliedReleaseSchema, BranchAnalysis, BranchAnalysisSchema, BranchAnalyzer, BranchAnalyzerBase, BranchAnalyzerLive, BranchAnalyzerShape, BranchFileEntry, BranchFileEntrySchema, BumpType, BumpTypeSchema, Categories, Changelog, ChangelogService, ChangelogServiceBase, ChangelogServiceShape, ChangelogTransformer, Changeset, ChangesetIOError, ChangesetIOErrorBase, ChangesetLinter, ChangesetOptions, ChangesetOptionsSchema, ChangesetPreview, ChangesetPreviewSchema, ChangesetSchema, ChangesetSummarySchema, ChangesetValidationError, ChangesetValidationErrorBase, Classification, ClassificationReason, ClassificationReasonSchema, ClassificationSchema, CommitHashSchema, ConfigInspector, ConfigInspectorBase, ConfigInspectorLive, ConfigInspectorShape, ConfigurationError, ConfigurationErrorBase, ContentStructureRule, ContributorFootnotesPlugin, DeduplicateItemsPlugin, DependencyAction, DependencyActionSchema, DependencyTable, DependencyTableFormatRule, DependencyTableRow, DependencyTableRowSchema, DependencyTableSchema, DependencyTableType, DependencyTableTypeSchema, DependencyType, DependencyTypeSchema, DependencyUpdate, DependencyUpdateSchema, DepsRegen, DepsRegenBase, DepsRegenDefault, DepsRegenLive, DepsRegenOptions, DepsRegenShape, FileStatus, FileStatusSchema, GitError, GitErrorBase, GitHubApiError, GitHubApiErrorBase, GitHubCommitInfo, GitHubInfo, GitHubInfoSchema, GitHubLive, GitHubService, GitHubServiceBase, GitHubServiceShape, GlobSchema, HeadingHierarchyRule, InspectedConfig, InspectedConfigSchema, IssueLinkRefsPlugin, IssueNumberSchema, JsonPathSchema, LegacyVersionFileConfig, LegacyVersionFileConfigSchema, LegacyVersionFilesSchema, LintMessage, MaintenanceNoteOptions, MaintenanceNotePlugin, MaintenanceReason, MaintenanceReasonSchema, MaintenanceTrigger, MaintenanceTriggerSchema, MarkdownLive, MarkdownParseError, MarkdownParseErrorBase, MarkdownService, MarkdownServiceBase, MarkdownServiceShape, ContentStructureRule$1 as MarkdownlintContentStructureRule, DependencyTableFormatRule$1 as MarkdownlintDependencyTableFormatRule, HeadingHierarchyRule$1 as MarkdownlintHeadingHierarchyRule, RequiredSectionsRule$1 as MarkdownlintRequiredSectionsRule, UncategorizedContentRule$1 as MarkdownlintUncategorizedContentRule, MergeSectionsPlugin, NonEmptyString, NormalizeFormatPlugin, PackageScope, PackageScopeSchema, PackagesRecordSchema, PendingChangeset, PendingChangesetSchema, PositiveInteger, PreviewRelease, PreviewReleaseSchema, RegenPlan, RegenResult, ReleasePlanError, ReleasePlanErrorBase, ReleasePlanner, ReleasePlannerBase, ReleasePlannerLive, ReleasePlannerShape, ReorderSectionsPlugin, RepoSchema, RequiredSectionsRule, ResolvedPackageScope, ResolvedPackageScopeSchema, ResolvedVersionFile, ResolvedVersionFileSchema, SectionCategory, SectionCategorySchema, SilkChangesetPreset, SilkChangesetTransformPreset, SilkChangesetsRules, TransformOptions, UncategorizedContentRule, UrlOrMarkdownLinkSchema, UsernameSchema, VERSION_RE, VersionFileConfig, VersionFileConfigSchema, VersionFileError, VersionFileErrorBase, VersionFileUpdate, VersionFileUpdateRecordSchema, VersionFiles, VersionFilesSchema, VersionOrEmptySchema, VersionType, VersionTypeSchema, WorkspaceDependencyDiff, WorkspaceVersion, changelogFunctions, computeWorkspaceDependencyDiffs, deriveMaintenanceReason, gitMergeBase, isPureDependencyChangeset, listPublishablePackageNames, makeBranchAnalyzerTest, makeConfigInspectorTest, makeGitHubTest, makeReleasePlannerTest, serializeDependencyTableToMarkdown };
|
|
5481
5584
|
}
|
|
5482
5585
|
//#endregion
|
|
5483
5586
|
//#region src/commitlint/config/schema.d.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@savvy-web/silk-effects",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Shared Effect library for Silk Suite conventions",
|
|
6
6
|
"homepage": "https://github.com/savvy-web/systems/tree/main/packages/silk-effects",
|
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
"./package.json": "./package.json"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@changesets/apply-release-plan": "^
|
|
32
|
-
"@changesets/config": "^
|
|
33
|
-
"@changesets/get-github-info": "^0.
|
|
34
|
-
"@changesets/get-release-plan": "^
|
|
31
|
+
"@changesets/apply-release-plan": "^8.0.0-next.7",
|
|
32
|
+
"@changesets/config": "^4.0.0-next.6",
|
|
33
|
+
"@changesets/get-github-info": "^1.0.0-next.3",
|
|
34
|
+
"@changesets/get-release-plan": "^5.0.0-next.7",
|
|
35
35
|
"@manypkg/get-packages": "^3.1.0",
|
|
36
36
|
"jsonc-effect": "^0.3.0",
|
|
37
37
|
"mdast-util-heading-range": "^4.0.0",
|
|
@@ -30,7 +30,7 @@ const SnapshotConfig = Schema.Struct({
|
|
|
30
30
|
prereleaseTemplate: Schema.optional(Schema.String)
|
|
31
31
|
});
|
|
32
32
|
/**
|
|
33
|
-
* Standard changesets configuration matching the `@changesets/config@
|
|
33
|
+
* Standard changesets configuration matching the `@changesets/config@4.0.0-next.6` spec.
|
|
34
34
|
*
|
|
35
35
|
* @remarks
|
|
36
36
|
* Represents the parsed `.changeset/config.json` file. All fields are optional
|