@shivaedev/changesets 0.0.0 → 0.1.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/CHANGELOG.md +9 -0
- package/LICENSE +21 -0
- package/README.md +68 -1
- package/dist/applyRelease.d.ts +16 -0
- package/dist/applyRelease.d.ts.map +1 -0
- package/dist/applyRelease.js +55 -0
- package/dist/applyRelease.js.map +1 -0
- package/dist/check.d.ts +6 -0
- package/dist/check.d.ts.map +1 -0
- package/dist/check.js +69 -0
- package/dist/check.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +29 -0
- package/dist/cli.js.map +1 -0
- package/dist/collectChangelog.d.ts +3 -0
- package/dist/collectChangelog.d.ts.map +1 -0
- package/dist/collectChangelog.js +17 -0
- package/dist/collectChangelog.js.map +1 -0
- package/dist/config.d.ts +14 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +4 -0
- package/dist/config.js.map +1 -0
- package/dist/error.d.ts +13 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +15 -0
- package/dist/error.js.map +1 -0
- package/dist/model.d.ts +68 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +22 -0
- package/dist/model.js.map +1 -0
- package/dist/parser.d.ts +8 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +30 -0
- package/dist/parser.js.map +1 -0
- package/dist/planner.d.ts +20 -0
- package/dist/planner.d.ts.map +1 -0
- package/dist/planner.js +71 -0
- package/dist/planner.js.map +1 -0
- package/dist/readHistory.d.ts +27 -0
- package/dist/readHistory.d.ts.map +1 -0
- package/dist/readHistory.js +37 -0
- package/dist/readHistory.js.map +1 -0
- package/dist/sections.d.ts +9 -0
- package/dist/sections.d.ts.map +1 -0
- package/dist/sections.js +36 -0
- package/dist/sections.js.map +1 -0
- package/dist/workspace.d.ts +37 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +87 -0
- package/dist/workspace.js.map +1 -0
- package/docs/north-star.md +7 -0
- package/docs/roadmap.md +16 -0
- package/package.json +109 -4
- package/src/applyRelease.ts +64 -0
- package/src/check.ts +106 -0
- package/src/cli.ts +36 -0
- package/src/collectChangelog.ts +27 -0
- package/src/config.ts +16 -0
- package/src/error.ts +20 -0
- package/src/model.ts +38 -0
- package/src/parser.ts +33 -0
- package/src/planner.ts +73 -0
- package/src/readHistory.ts +38 -0
- package/src/sections.ts +40 -0
- package/src/workspace.ts +109 -0
package/dist/planner.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { attempt, requireThat } from "#error.ts";
|
|
3
|
+
import { parseChangeset } from "#parser.ts";
|
|
4
|
+
import { readWorkspace } from "#workspace.ts";
|
|
5
|
+
const rank = { major: 2, minor: 1, patch: 0 };
|
|
6
|
+
export function publishedDependencies(manifest) {
|
|
7
|
+
return Object.keys({ ...manifest.dependencies, ...manifest.optionalDependencies, ...manifest.peerDependencies });
|
|
8
|
+
}
|
|
9
|
+
function nextVersion(name, version, bump) {
|
|
10
|
+
const match = /^(?<major>0|[1-9]\d*)\.(?<minor>0|[1-9]\d*)\.(?<patch>0|[1-9]\d*)$/u.exec(version);
|
|
11
|
+
requireThat(match !== null, `${name}: use a stable major.minor.patch version before planning a release; found ${version}.`);
|
|
12
|
+
const major = Number(match?.groups?.major);
|
|
13
|
+
const minor = Number(match?.groups?.minor);
|
|
14
|
+
const patch = Number(match?.groups?.patch);
|
|
15
|
+
requireThat(major !== 0 || bump !== "major", `${name}: major is not allowed on a 0.x package; use minor for breaking changes.`);
|
|
16
|
+
if (bump === "major") {
|
|
17
|
+
return `${major + 1}.0.0`;
|
|
18
|
+
}
|
|
19
|
+
return bump === "minor" ? `${major}.${minor + 1}.0` : `${major}.${minor}.${patch + 1}`;
|
|
20
|
+
}
|
|
21
|
+
function requestedBumps(packages, sources) {
|
|
22
|
+
const bumps = new Map();
|
|
23
|
+
for (const source of sources) {
|
|
24
|
+
for (const [name, bump] of Object.entries(parseChangeset(source).packages)) {
|
|
25
|
+
const pkg = packages.find((candidate) => candidate.manifest.name === name);
|
|
26
|
+
requireThat(pkg !== undefined, `${source.name}: unknown package ${name}; fix the name or include its directory in config.packages.`);
|
|
27
|
+
requireThat(!pkg?.manifest.private, `${source.name}: ${name} is private; remove it from release frontmatter.`);
|
|
28
|
+
if (pkg !== undefined) {
|
|
29
|
+
nextVersion(name, pkg.manifest.version, bump);
|
|
30
|
+
}
|
|
31
|
+
const previous = bumps.get(name);
|
|
32
|
+
if (previous === undefined || rank[bump] > rank[previous]) {
|
|
33
|
+
bumps.set(name, bump);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return bumps;
|
|
38
|
+
}
|
|
39
|
+
export function computePlan(packages, sources) {
|
|
40
|
+
const bumps = requestedBumps(packages, sources);
|
|
41
|
+
let changed = true;
|
|
42
|
+
while (changed) {
|
|
43
|
+
changed = false;
|
|
44
|
+
for (const { manifest } of packages) {
|
|
45
|
+
if (!(manifest.private || bumps.has(manifest.name)) && publishedDependencies(manifest).some((name) => bumps.has(name))) {
|
|
46
|
+
bumps.set(manifest.name, "patch");
|
|
47
|
+
changed = true;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const releases = [...bumps]
|
|
52
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
53
|
+
.map(([name, bump]) => {
|
|
54
|
+
const pkg = packages.find((candidate) => candidate.manifest.name === name);
|
|
55
|
+
if (pkg === undefined) {
|
|
56
|
+
throw new Error(`Package ${name} disappeared while planning.`);
|
|
57
|
+
}
|
|
58
|
+
return { bump, directory: pkg.directory, from: pkg.manifest.version, name, to: nextVersion(name, pkg.manifest.version, bump) };
|
|
59
|
+
});
|
|
60
|
+
return { changesets: [...sources].sort((left, right) => left.name.localeCompare(right.name)), releases };
|
|
61
|
+
}
|
|
62
|
+
export function summarizePlan(plan) {
|
|
63
|
+
return plan.releases.length === 0
|
|
64
|
+
? "No pending releases."
|
|
65
|
+
: plan.releases.map((release) => `${release.name}: ${release.from} -> ${release.to} (${release.bump})`).join("\n");
|
|
66
|
+
}
|
|
67
|
+
export const planRelease = Effect.fn("Changesets.planRelease")(function* (root, config = {}) {
|
|
68
|
+
const workspace = yield* readWorkspace(root, config);
|
|
69
|
+
return yield* attempt(() => computePlan(workspace.packages, workspace.changesets));
|
|
70
|
+
});
|
|
71
|
+
//# sourceMappingURL=planner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planner.js","sourceRoot":"","sources":["../src/planner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import type { ChangesetConfig } from "#config.ts";
|
|
3
|
+
import { ChangesetError } from "#error.ts";
|
|
4
|
+
export declare const readHistory: (root: string, config: ChangesetConfig, reference?: string | undefined) => Effect.Effect<{
|
|
5
|
+
changesets: {
|
|
6
|
+
name: string;
|
|
7
|
+
text: string;
|
|
8
|
+
}[];
|
|
9
|
+
packages: import("#model.ts").WorkspacePackage[];
|
|
10
|
+
release: {
|
|
11
|
+
readonly date: string;
|
|
12
|
+
readonly plan: {
|
|
13
|
+
readonly changesets: readonly {
|
|
14
|
+
readonly name: string;
|
|
15
|
+
readonly text: string;
|
|
16
|
+
}[];
|
|
17
|
+
readonly releases: readonly {
|
|
18
|
+
readonly bump: "major" | "minor" | "patch";
|
|
19
|
+
readonly directory: string;
|
|
20
|
+
readonly from: string;
|
|
21
|
+
readonly name: string;
|
|
22
|
+
readonly to: string;
|
|
23
|
+
}[];
|
|
24
|
+
};
|
|
25
|
+
} | undefined;
|
|
26
|
+
}, ChangesetError, never>;
|
|
27
|
+
//# sourceMappingURL=readHistory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readHistory.d.ts","sourceRoot":"","sources":["../src/readHistory.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AACxC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAW,cAAc,EAAE,MAAM,WAAW,CAAC;AAOpD,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;yBA0BtB,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { execFileSync, spawnSync } from "node:child_process";
|
|
2
|
+
import { posix } from "node:path";
|
|
3
|
+
import { Effect, Schema } from "effect";
|
|
4
|
+
import { attempt, ChangesetError } from "#error.ts";
|
|
5
|
+
import { ReleaseManifest } from "#model.ts";
|
|
6
|
+
import { decodePackage, isChangeset, packagePatterns } from "#workspace.ts";
|
|
7
|
+
function git(root, args) {
|
|
8
|
+
return execFileSync("git", ["-C", root, ...args], { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
|
|
9
|
+
}
|
|
10
|
+
export const readHistory = Effect.fn("Changesets.readHistory")(function* (root, config, reference) {
|
|
11
|
+
const base = yield* attempt(() => {
|
|
12
|
+
for (const candidate of reference === undefined ? ["origin/main", "main"] : [reference]) {
|
|
13
|
+
const result = spawnSync("git", ["-C", root, "merge-base", candidate, "HEAD"], { encoding: "utf8" });
|
|
14
|
+
if (result.status === 0) {
|
|
15
|
+
return result.stdout.trim();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
throw new ChangesetError({
|
|
19
|
+
message: `Cannot resolve changeset base ${reference ?? "origin/main or main"}; run git fetch origin main or pass an existing base-ref with full history.`,
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
return yield* attempt(() => {
|
|
23
|
+
const paths = git(root, ["ls-tree", "-r", "--name-only", base]).trim().split("\n");
|
|
24
|
+
function read(path, fallback) {
|
|
25
|
+
return paths.includes(path) ? git(root, ["show", `${base}:${path}`]) : fallback;
|
|
26
|
+
}
|
|
27
|
+
const packages = paths
|
|
28
|
+
.filter((path) => path.endsWith("/package.json") && packagePatterns(config).some((pattern) => posix.matchesGlob(posix.dirname(path), pattern)))
|
|
29
|
+
.map((path) => decodePackage(posix.dirname(path), read(path, ""), read(`${posix.dirname(path)}/CHANGELOG.md`, "# Changelog\n")));
|
|
30
|
+
const changesets = paths
|
|
31
|
+
.filter((path) => path.startsWith(".changeset/") && isChangeset(path.slice(".changeset/".length)))
|
|
32
|
+
.map((path) => ({ name: path.slice(".changeset/".length), text: read(path, "") }));
|
|
33
|
+
const text = read(".changeset/release.json", "");
|
|
34
|
+
return { changesets, packages, release: text === "" ? undefined : Schema.decodeUnknownSync(Schema.fromJsonString(ReleaseManifest))(text) };
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
//# sourceMappingURL=readHistory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readHistory.js","sourceRoot":"","sources":["../src/readHistory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const sections: readonly ["Added", "Changed", "Fixed", "Breaking"];
|
|
2
|
+
export type Section = (typeof sections)[number];
|
|
3
|
+
export interface Entry {
|
|
4
|
+
readonly section: Section;
|
|
5
|
+
readonly text: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function parseBody(name: string, body: string): readonly Entry[];
|
|
8
|
+
export declare function renderEntries(entries: readonly Entry[]): string;
|
|
9
|
+
//# sourceMappingURL=sections.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sections.d.ts","sourceRoot":"","sources":["../src/sections.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,QAAQ,YAAI,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,CAAU,CAAC;AAC3E,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAChD,MAAM,WAAW,KAAK;IACrB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,KAAK,EAAE,CAqBtE;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,SAAS,KAAK,EAAE,GAAG,MAAM,CAO/D"}
|
package/dist/sections.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { requireThat } from "#error.ts";
|
|
2
|
+
export const sections = ["Added", "Changed", "Fixed", "Breaking"];
|
|
3
|
+
export function parseBody(name, body) {
|
|
4
|
+
const entries = [];
|
|
5
|
+
let section;
|
|
6
|
+
for (const line of body.split("\n")) {
|
|
7
|
+
if (line.startsWith("### ")) {
|
|
8
|
+
section = sections.find((value) => line === `### ${value}`);
|
|
9
|
+
requireThat(section !== undefined, `${name}: use ### Added, ### Changed, ### Fixed or ### Breaking.`);
|
|
10
|
+
}
|
|
11
|
+
else if (line.startsWith("- ") && section !== undefined) {
|
|
12
|
+
requireThat(line.slice(2).trim() !== "", `${name}: write text after '- '.`);
|
|
13
|
+
entries.push({ section, text: line });
|
|
14
|
+
}
|
|
15
|
+
else if (line.trim() !== "") {
|
|
16
|
+
const previous = entries.at(-1);
|
|
17
|
+
if (previous === undefined || previous.section !== section || !/^\s+\S/u.test(line)) {
|
|
18
|
+
requireThat(false, `${name}: start each entry with '- ' under a ### section heading.`);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
entries[entries.length - 1] = { ...previous, text: `${previous.text}\n${line}` };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
requireThat(entries.length > 0, `${name}: add at least one release-note entry under a ### section heading.`);
|
|
26
|
+
return entries;
|
|
27
|
+
}
|
|
28
|
+
export function renderEntries(entries) {
|
|
29
|
+
return sections
|
|
30
|
+
.flatMap((section) => {
|
|
31
|
+
const selected = entries.filter((entry) => entry.section === section);
|
|
32
|
+
return selected.length === 0 ? [] : [`### ${section}\n\n${selected.map((entry) => entry.text).join("\n")}\n`];
|
|
33
|
+
})
|
|
34
|
+
.join("\n");
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=sections.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sections.js","sourceRoot":"","sources":["../src/sections.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,CAAU,CAAC;AAO3E,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,IAAY;IACnD,MAAM,OAAO,GAAY,EAAE,CAAC;IAC5B,IAAI,OAA4B,CAAC;IACjC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7B,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,KAAK,OAAO,KAAK,EAAE,CAAC,CAAC;YAC5D,WAAW,CAAC,OAAO,KAAK,SAAS,EAAE,GAAG,IAAI,0DAA0D,CAAC,CAAC;QACvG,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3D,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,GAAG,IAAI,0BAA0B,CAAC,CAAC;YAC5E,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC/B,MAAM,QAAQ,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAChC,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,OAAO,KAAK,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrF,WAAW,CAAC,KAAK,EAAE,GAAG,IAAI,2DAA2D,CAAC,CAAC;YACxF,CAAC;iBAAM,CAAC;gBACP,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,IAAI,KAAK,IAAI,EAAE,EAAE,CAAC;YAClF,CAAC;QACF,CAAC;IACF,CAAC;IACD,WAAW,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,GAAG,IAAI,oEAAoE,CAAC,CAAC;IAC7G,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAyB;IACtD,OAAO,QAAQ;SACb,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QACpB,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC;QACtE,OAAO,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,OAAO,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/G,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Effect, FileSystem } from "effect";
|
|
2
|
+
import type { ChangesetConfig } from "#config.ts";
|
|
3
|
+
import { ChangesetError } from "#error.ts";
|
|
4
|
+
import { type WorkspacePackage } from "#model.ts";
|
|
5
|
+
export declare function packagePatterns(config: ChangesetConfig): readonly string[];
|
|
6
|
+
export declare function decodePackage(directory: string, text: string, changelog: string): WorkspacePackage;
|
|
7
|
+
export declare const readOptional: (path: string, fallback: string) => Effect.Effect<string, import("effect/PlatformError").PlatformError, FileSystem.FileSystem>;
|
|
8
|
+
export declare const loadConfig: (root: string) => Effect.Effect<ChangesetConfig, ChangesetError | import("effect/PlatformError").PlatformError, FileSystem.FileSystem>;
|
|
9
|
+
export declare const readChangesets: (root: string) => Effect.Effect<{
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly text: string;
|
|
12
|
+
}[], import("effect/PlatformError").PlatformError, FileSystem.FileSystem>;
|
|
13
|
+
export declare function isChangeset(name: string): boolean;
|
|
14
|
+
export declare const readWorkspace: (root: string, config: ChangesetConfig) => Effect.Effect<{
|
|
15
|
+
changesets: {
|
|
16
|
+
readonly name: string;
|
|
17
|
+
readonly text: string;
|
|
18
|
+
}[];
|
|
19
|
+
packages: WorkspacePackage[];
|
|
20
|
+
release: {
|
|
21
|
+
readonly date: string;
|
|
22
|
+
readonly plan: {
|
|
23
|
+
readonly changesets: readonly {
|
|
24
|
+
readonly name: string;
|
|
25
|
+
readonly text: string;
|
|
26
|
+
}[];
|
|
27
|
+
readonly releases: readonly {
|
|
28
|
+
readonly bump: "major" | "minor" | "patch";
|
|
29
|
+
readonly directory: string;
|
|
30
|
+
readonly from: string;
|
|
31
|
+
readonly name: string;
|
|
32
|
+
readonly to: string;
|
|
33
|
+
}[];
|
|
34
|
+
};
|
|
35
|
+
} | undefined;
|
|
36
|
+
}, ChangesetError | import("effect/PlatformError").PlatformError, FileSystem.FileSystem>;
|
|
37
|
+
//# sourceMappingURL=workspace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAU,MAAM,QAAQ,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAW,cAAc,EAAe,MAAM,WAAW,CAAC;AACjE,OAAO,EAAiD,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AACjG,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,MAAM,EAAE,CAE1E;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAOlG;AACD,eAAO,MAAM,YAAY,gIAGvB,CAAC;AACH,eAAO,MAAM,UAAU,wIAgCrB,CAAC;AAeH,eAAO,MAAM,cAAc;;;yEAOzB,CAAC;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AACD,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;wFA4BxB,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { pathToFileURL } from "node:url";
|
|
11
|
+
import { Effect, FileSystem, Schema } from "effect";
|
|
12
|
+
import { attempt, ChangesetError, requireThat } from "#error.ts";
|
|
13
|
+
import { PackageManifest, ReleaseManifest } from "#model.ts";
|
|
14
|
+
export function packagePatterns(config) {
|
|
15
|
+
return config.packages ?? ["packages/*", "examples/*"];
|
|
16
|
+
}
|
|
17
|
+
const Json = Schema.Record(Schema.String, Schema.Unknown);
|
|
18
|
+
export function decodePackage(directory, text, changelog) {
|
|
19
|
+
return {
|
|
20
|
+
changelog,
|
|
21
|
+
directory,
|
|
22
|
+
json: Schema.decodeUnknownSync(Schema.fromJsonString(Json))(text),
|
|
23
|
+
manifest: Schema.decodeUnknownSync(Schema.fromJsonString(PackageManifest))(text),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export const readOptional = Effect.fn("Changesets.readOptional")(function* (path, fallback) {
|
|
27
|
+
const fs = yield* FileSystem.FileSystem;
|
|
28
|
+
return (yield* fs.exists(path)) ? yield* fs.readFileString(path) : fallback;
|
|
29
|
+
});
|
|
30
|
+
export const loadConfig = Effect.fn("Changesets.loadConfig")(function* (root) {
|
|
31
|
+
const fs = yield* FileSystem.FileSystem;
|
|
32
|
+
const path = join(root, ".changeset/changesets.config.ts");
|
|
33
|
+
if (!(yield* fs.exists(path))) {
|
|
34
|
+
return {};
|
|
35
|
+
}
|
|
36
|
+
const module = yield* Effect.tryPromise({
|
|
37
|
+
catch: (cause) => new ChangesetError({
|
|
38
|
+
cause,
|
|
39
|
+
message: ".changeset/changesets.config.ts: export default defineConfig({ packages, hooks }); hooks must be typed Effect functions.",
|
|
40
|
+
}),
|
|
41
|
+
try: () => import(__rewriteRelativeImportExtension(pathToFileURL(path).href)),
|
|
42
|
+
});
|
|
43
|
+
yield* attempt(() => {
|
|
44
|
+
requireThat(typeof module.default === "object" && module.default !== null, ".changeset/changesets.config.ts: export a config object with defineConfig.");
|
|
45
|
+
requireThat(module.default.hooks === undefined || (Array.isArray(module.default.hooks) && module.default.hooks.every((hook) => typeof hook === "function")), ".changeset/changesets.config.ts: hooks must be Effect functions, not shell strings.");
|
|
46
|
+
requireThat(module.default.packages === undefined
|
|
47
|
+
|| (Array.isArray(module.default.packages) && module.default.packages.every((pattern) => typeof pattern === "string")), ".changeset/changesets.config.ts: packages must be directory paths or parent/* patterns.");
|
|
48
|
+
});
|
|
49
|
+
return module.default;
|
|
50
|
+
});
|
|
51
|
+
const directories = Effect.fn("Changesets.directories")(function* (root, pattern) {
|
|
52
|
+
const fs = yield* FileSystem.FileSystem;
|
|
53
|
+
yield* attempt(() => requireThat(/^(?:[\w.-]+\/)*[\w.*-]+$/u.test(pattern) && !pattern.split("/").includes("..") && (!pattern.includes("*") || pattern.endsWith("/*")), `Invalid package pattern ${pattern}; use a relative directory or parent/*. `));
|
|
54
|
+
if (!pattern.endsWith("/*")) {
|
|
55
|
+
return [pattern];
|
|
56
|
+
}
|
|
57
|
+
const parent = pattern.slice(0, -2);
|
|
58
|
+
return (yield* fs.exists(join(root, parent))) ? (yield* fs.readDirectory(join(root, parent))).map((name) => `${parent}/${name}`) : [];
|
|
59
|
+
});
|
|
60
|
+
export const readChangesets = Effect.fn("Changesets.readChangesets")(function* (root) {
|
|
61
|
+
const fs = yield* FileSystem.FileSystem;
|
|
62
|
+
const directory = join(root, ".changeset");
|
|
63
|
+
const names = (yield* fs.exists(directory)) ? yield* fs.readDirectory(directory) : [];
|
|
64
|
+
return yield* Effect.forEach(names.filter(isChangeset).sort(), (name) => Effect.map(fs.readFileString(join(directory, name)), (text) => ({ name, text })));
|
|
65
|
+
});
|
|
66
|
+
export function isChangeset(name) {
|
|
67
|
+
return name !== "README.md" && /^[^/\\]+\.md$/u.test(name);
|
|
68
|
+
}
|
|
69
|
+
export const readWorkspace = Effect.fn("Changesets.readWorkspace")(function* (root, config) {
|
|
70
|
+
const fs = yield* FileSystem.FileSystem;
|
|
71
|
+
const paths = [...new Set((yield* Effect.forEach(packagePatterns(config), (pattern) => directories(root, pattern))).flat())].sort();
|
|
72
|
+
const packages = [];
|
|
73
|
+
for (const directory of paths) {
|
|
74
|
+
if (yield* fs.exists(join(root, directory, "package.json"))) {
|
|
75
|
+
const text = yield* fs.readFileString(join(root, directory, "package.json"));
|
|
76
|
+
const changelog = yield* readOptional(join(root, directory, "CHANGELOG.md"), "# Changelog\n");
|
|
77
|
+
packages.push(yield* attempt(() => decodePackage(directory, text, changelog)));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
yield* attempt(() => requireThat(new Set(packages.map((pkg) => pkg.manifest.name)).size === packages.length, "Workspace package names must be unique; fix package.json names."));
|
|
81
|
+
const releaseText = yield* readOptional(join(root, ".changeset/release.json"), "");
|
|
82
|
+
const release = releaseText === ""
|
|
83
|
+
? undefined
|
|
84
|
+
: yield* attempt(() => Schema.decodeUnknownSync(Schema.fromJsonString(ReleaseManifest))(releaseText)).pipe(Effect.mapError((cause) => new ChangesetError({ cause, message: ".changeset/release.json is invalid; restore the manifest generated by changesets apply." })));
|
|
85
|
+
return { changesets: yield* readChangesets(root), packages, release };
|
|
86
|
+
});
|
|
87
|
+
//# sourceMappingURL=workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Reproducible workspace releases
|
|
2
|
+
|
|
3
|
+
A release should preserve what its authors asked for. A changeset names packages, explicit bumps and human release notes. One plan includes the highest requested bumps and every published dependent that must ship with them. Applying that plan produces a diff a maintainer can review without reconstructing intermediate commits.
|
|
4
|
+
|
|
5
|
+
The release manifest preserves filenames and exact source text. Validation reproduces versions and changelog entries from those inputs and protects already released history. Files added after collection stay pending. A squash merge does not discard the evidence needed to validate a release.
|
|
6
|
+
|
|
7
|
+
Explicit intent wins over inference, and preserving history wins over convenient edits. Repository policy stays in typed Effect hooks: starter pins and embedded version constants belong to the repository that owns them. npm publishing, release scheduling and approval policy stay outside this package.
|
package/docs/roadmap.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Roadmap
|
|
2
|
+
|
|
3
|
+
## Built
|
|
4
|
+
|
|
5
|
+
- Flat YAML changeset mappings with explicit package bumps and grouped Markdown release-note sections.
|
|
6
|
+
- Whole-workspace planning with transitive published dependents and the explicit pre-1.0 breaking-change rule.
|
|
7
|
+
- Version and changelog collection, reproducible release manifests and typed Effect hooks.
|
|
8
|
+
- CLI stories over temporary Git workspaces for planning, apply and validation failures.
|
|
9
|
+
|
|
10
|
+
## Next
|
|
11
|
+
|
|
12
|
+
- Adopt this package in the platform repository's authoring and release commands, replacing its package-local fragments.
|
|
13
|
+
|
|
14
|
+
## Open questions
|
|
15
|
+
|
|
16
|
+
- Prerelease and release-channel policy remain outside the stable-version planner.
|
package/package.json
CHANGED
|
@@ -1,10 +1,115 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shivaedev/changesets",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Explicit changesets and reproducible workspace releases with Effect",
|
|
5
|
+
"homepage": "https://github.com/ShivaeDev/platform/tree/main/packages/changesets#readme",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/ShivaeDev/platform/issues"
|
|
8
|
+
},
|
|
6
9
|
"repository": {
|
|
7
10
|
"type": "git",
|
|
8
|
-
"url": "git+https://github.com/ShivaeDev/platform.git"
|
|
11
|
+
"url": "git+https://github.com/ShivaeDev/platform.git",
|
|
12
|
+
"directory": "packages/changesets"
|
|
13
|
+
},
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"sideEffects": false,
|
|
16
|
+
"type": "module",
|
|
17
|
+
"imports": {
|
|
18
|
+
"#test/*": "./src/test-support/*",
|
|
19
|
+
"#*.ts": {
|
|
20
|
+
"source": "./src/*.ts",
|
|
21
|
+
"types": "./dist/*.d.ts",
|
|
22
|
+
"default": "./dist/*.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"exports": {
|
|
26
|
+
"./applyRelease.ts": {
|
|
27
|
+
"types": "./dist/applyRelease.d.ts",
|
|
28
|
+
"source": "./src/applyRelease.ts",
|
|
29
|
+
"import": "./dist/applyRelease.js",
|
|
30
|
+
"default": "./dist/applyRelease.js"
|
|
31
|
+
},
|
|
32
|
+
"./check.ts": {
|
|
33
|
+
"types": "./dist/check.d.ts",
|
|
34
|
+
"source": "./src/check.ts",
|
|
35
|
+
"import": "./dist/check.js",
|
|
36
|
+
"default": "./dist/check.js"
|
|
37
|
+
},
|
|
38
|
+
"./planner.ts": {
|
|
39
|
+
"types": "./dist/planner.d.ts",
|
|
40
|
+
"source": "./src/planner.ts",
|
|
41
|
+
"import": "./dist/planner.js",
|
|
42
|
+
"default": "./dist/planner.js"
|
|
43
|
+
},
|
|
44
|
+
"./config.ts": {
|
|
45
|
+
"types": "./dist/config.d.ts",
|
|
46
|
+
"source": "./src/config.ts",
|
|
47
|
+
"import": "./dist/config.js",
|
|
48
|
+
"default": "./dist/config.js"
|
|
49
|
+
},
|
|
50
|
+
"./parser.ts": {
|
|
51
|
+
"types": "./dist/parser.d.ts",
|
|
52
|
+
"source": "./src/parser.ts",
|
|
53
|
+
"import": "./dist/parser.js",
|
|
54
|
+
"default": "./dist/parser.js"
|
|
55
|
+
},
|
|
56
|
+
"./error.ts": {
|
|
57
|
+
"types": "./dist/error.d.ts",
|
|
58
|
+
"source": "./src/error.ts",
|
|
59
|
+
"import": "./dist/error.js",
|
|
60
|
+
"default": "./dist/error.js"
|
|
61
|
+
},
|
|
62
|
+
"./model.ts": {
|
|
63
|
+
"types": "./dist/model.d.ts",
|
|
64
|
+
"source": "./src/model.ts",
|
|
65
|
+
"import": "./dist/model.js",
|
|
66
|
+
"default": "./dist/model.js"
|
|
67
|
+
},
|
|
68
|
+
"./package.json": "./package.json"
|
|
69
|
+
},
|
|
70
|
+
"bin": {
|
|
71
|
+
"changesets": "./dist/cli.js"
|
|
72
|
+
},
|
|
73
|
+
"files": [
|
|
74
|
+
"dist",
|
|
75
|
+
"src",
|
|
76
|
+
"!src/**/*.test.ts",
|
|
77
|
+
"!src/**/*.spec.ts",
|
|
78
|
+
"!src/**/test-support",
|
|
79
|
+
"docs",
|
|
80
|
+
"CHANGELOG.md",
|
|
81
|
+
"README.md"
|
|
82
|
+
],
|
|
83
|
+
"devDependencies": {
|
|
84
|
+
"@effect/platform-node": "4.0.4",
|
|
85
|
+
"@effect/platform-node-shared": "4.0.4",
|
|
86
|
+
"@effect/vitest": "4.0.4",
|
|
87
|
+
"@shivaedev/effect-test": "0.5.0",
|
|
88
|
+
"@shivaedev/quality": "0.23.0",
|
|
89
|
+
"@shivaedev/test-story": "0.5.0",
|
|
90
|
+
"@types/node": "24.19.2",
|
|
91
|
+
"@typescript/native": "npm:typescript@7.0.2",
|
|
92
|
+
"effect": "4.0.4",
|
|
93
|
+
"happy-dom": "20.14.6",
|
|
94
|
+
"typescript": "npm:@typescript/typescript6@6.0.2",
|
|
95
|
+
"vitest": "5.0.3"
|
|
96
|
+
},
|
|
97
|
+
"peerDependencies": {
|
|
98
|
+
"@effect/platform-node": "4.0.4",
|
|
99
|
+
"@effect/platform-node-shared": "4.0.4",
|
|
100
|
+
"effect": "4.0.4"
|
|
101
|
+
},
|
|
102
|
+
"engines": {
|
|
103
|
+
"node": ">=24"
|
|
104
|
+
},
|
|
105
|
+
"publishConfig": {
|
|
106
|
+
"access": "public",
|
|
107
|
+
"provenance": true
|
|
108
|
+
},
|
|
109
|
+
"scripts": {
|
|
110
|
+
"build": "node --eval \"import('node:fs').then(({ rmSync }) => rmSync('dist', { force: true, recursive: true }))\" && tsc --project tsconfig.build.json",
|
|
111
|
+
"ready": "pnpm typecheck && pnpm test && pnpm build",
|
|
112
|
+
"test": "vitest run",
|
|
113
|
+
"typecheck": "tsc --noEmit"
|
|
9
114
|
}
|
|
10
115
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { Clock, Effect, FileSystem } from "effect";
|
|
3
|
+
import { collectChangelog } from "#collectChangelog.ts";
|
|
4
|
+
import type { ChangesetConfig } from "#config.ts";
|
|
5
|
+
import { attempt, requireThat } from "#error.ts";
|
|
6
|
+
import type { ReleasePlan, WorkspacePackage } from "#model.ts";
|
|
7
|
+
import { computePlan } from "#planner.ts";
|
|
8
|
+
import { readWorkspace } from "#workspace.ts";
|
|
9
|
+
|
|
10
|
+
function updatedPackage(pkg: WorkspacePackage, plan: ReleasePlan, version: string) {
|
|
11
|
+
const json: Record<string, unknown> = { ...pkg.json, version };
|
|
12
|
+
for (const key of ["dependencies", "optionalDependencies", "peerDependencies"] as const) {
|
|
13
|
+
const dependencies = pkg.manifest[key];
|
|
14
|
+
if (dependencies !== undefined) {
|
|
15
|
+
json[key] = Object.fromEntries(
|
|
16
|
+
Object.entries(dependencies).map(([name, range]) => {
|
|
17
|
+
const target = plan.releases.find((release) => release.name === name);
|
|
18
|
+
if (target === undefined || ["workspace:*", "workspace:^", "workspace:~"].includes(range)) {
|
|
19
|
+
return [name, range];
|
|
20
|
+
}
|
|
21
|
+
const match = /^(?<prefix>(?:workspace:)?[~^]?)\d+\.\d+\.\d+$/u.exec(range);
|
|
22
|
+
requireThat(
|
|
23
|
+
match !== null,
|
|
24
|
+
`${pkg.manifest.name}: replace ${name}'s ${range} range with an exact version, ^version, ~version or workspace:* before applying a release.`,
|
|
25
|
+
);
|
|
26
|
+
const prefix = match?.groups?.prefix ?? "";
|
|
27
|
+
return [name, `${prefix}${target.to}`];
|
|
28
|
+
}),
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return `${JSON.stringify(json, null, "\t")}\n`;
|
|
33
|
+
}
|
|
34
|
+
export const applyRelease = Effect.fn("Changesets.applyRelease")(function* (root: string, config: ChangesetConfig = {}) {
|
|
35
|
+
const fs = yield* FileSystem.FileSystem;
|
|
36
|
+
const workspace = yield* readWorkspace(root, config);
|
|
37
|
+
const plan = yield* attempt(() => computePlan(workspace.packages, workspace.changesets));
|
|
38
|
+
if (plan.releases.length === 0) {
|
|
39
|
+
return plan;
|
|
40
|
+
}
|
|
41
|
+
const date = new Date(yield* Clock.currentTimeMillis).toISOString().slice(0, 10);
|
|
42
|
+
const writes = yield* attempt(() =>
|
|
43
|
+
plan.releases.flatMap((release) => {
|
|
44
|
+
const pkg = workspace.packages.find((candidate) => candidate.manifest.name === release.name);
|
|
45
|
+
if (pkg === undefined) {
|
|
46
|
+
throw new Error(`Package ${release.name} disappeared while applying.`);
|
|
47
|
+
}
|
|
48
|
+
return [
|
|
49
|
+
{ path: join(root, release.directory, "package.json"), text: updatedPackage(pkg, plan, release.to) },
|
|
50
|
+
{ path: join(root, release.directory, "CHANGELOG.md"), text: collectChangelog(pkg.changelog, release, plan, date) },
|
|
51
|
+
];
|
|
52
|
+
}),
|
|
53
|
+
);
|
|
54
|
+
const manifest = { date, plan };
|
|
55
|
+
for (const write of writes) {
|
|
56
|
+
yield* fs.writeFileString(write.path, write.text);
|
|
57
|
+
}
|
|
58
|
+
yield* fs.writeFileString(join(root, ".changeset/release.json"), `${JSON.stringify(manifest, null, "\t")}\n`);
|
|
59
|
+
yield* Effect.forEach(plan.changesets, (source) => fs.remove(join(root, ".changeset", source.name)));
|
|
60
|
+
for (const hook of config.hooks ?? []) {
|
|
61
|
+
yield* hook({ plan, root });
|
|
62
|
+
}
|
|
63
|
+
return plan;
|
|
64
|
+
});
|