diff --git a/.changeset/config.json b/.changeset/config.json index e64346c9e..e46d39589 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -1,8 +1,5 @@ { - "changelog": [ - "@changesets/changelog-github", - { "repo": "changesets/changesets" } - ], + "changelog": "@abizzle/changesets-cli/changelog", "baseBranch": "main", "commit": false, "access": "public", diff --git a/.changeset/forty-trains-accept.md b/.changeset/forty-trains-accept.md new file mode 100644 index 000000000..34b668bda --- /dev/null +++ b/.changeset/forty-trains-accept.md @@ -0,0 +1,26 @@ +--- +"@abizzle/changesets-assemble-release-plan": minor +"@abizzle/changesets-apply-release-plan": minor +"@abizzle/changesets-changelog-github": minor +"@abizzle/changesets-changelog-git": minor +"@abizzle/changesets-config": minor +"@abizzle/changesets-types": minor +--- + +Add support for single changelog fixed package groups. + +Optionally supply an object as a fixed package group entry like so: + +```json +{ + "fixed": [ + { + "group": ["@changesets/button", "@changesets/theme"], + "changelog": "CHANGELOG.md", + "name": "UI Packages" + } + ] +} +``` + +This will create/update a single changelog at `/CHANGELOG.md` with changelog entries for `@changesets/button` and `@changesets/theme` under the title "UI Packages". diff --git a/.changeset/good-flies-do.md b/.changeset/good-flies-do.md new file mode 100644 index 000000000..5c87bab6a --- /dev/null +++ b/.changeset/good-flies-do.md @@ -0,0 +1,6 @@ +--- +"@abizzle/changesets-types": minor +"@abizzle/changesets-apply-release-plan": patch +--- + +Fix logic to write a single changelog entry for fixed groups diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 000000000..da7e93837 --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,33 @@ +{ + "mode": "pre", + "tag": "next", + "initialVersions": { + "@abizzle/changesets-apply-release-plan": "6.1.3", + "@abizzle/changesets-assemble-release-plan": "5.2.3", + "@abizzle/changesets-changelog-git": "0.1.14", + "@abizzle/changesets-changelog-github": "0.4.8", + "@abizzle/changesets-cli": "2.26.0", + "@abizzle/changesets-config": "2.3.0", + "@changesets/errors": "0.1.4", + "@changesets/get-dependents-graph": "1.3.5", + "@changesets/get-github-info": "0.5.2", + "@abizzle/changesets-get-release-plan": "3.0.16", + "@changesets/get-version-range-type": "0.3.2", + "get-workspaces": "1.0.10", + "@changesets/git": "2.0.0", + "@changesets/logger": "0.0.5", + "@changesets/parse": "0.3.16", + "@changesets/pre": "1.0.14", + "@changesets/read": "0.5.9", + "@changesets/release-utils": "0.1.12", + "@abizzle/changesets-types": "5.2.1", + "@changesets/write": "0.2.3", + "@changesets/test-utils": "0.0.5" + }, + "changesets": [ + "forty-trains-accept", + "good-flies-do", + "shy-singers-turn", + "strange-jars-nail" + ] +} diff --git a/.changeset/shy-singers-turn.md b/.changeset/shy-singers-turn.md new file mode 100644 index 000000000..14bfc03d7 --- /dev/null +++ b/.changeset/shy-singers-turn.md @@ -0,0 +1,9 @@ +--- +"@abizzle/changesets-assemble-release-plan": patch +"@abizzle/changesets-apply-release-plan": patch +"@abizzle/changesets-get-release-plan": patch +"@abizzle/changesets-types": patch +"@abizzle/changesets-cli": patch +--- + +Fixes dist files diff --git a/.changeset/strange-jars-nail.md b/.changeset/strange-jars-nail.md new file mode 100644 index 000000000..f0fdda3a7 --- /dev/null +++ b/.changeset/strange-jars-nail.md @@ -0,0 +1,8 @@ +--- +"@abizzle/changesets-assemble-release-plan": major +"@abizzle/changesets-apply-release-plan": major +"@abizzle/changesets-types": major +"@abizzle/changesets-cli": minor +--- + +Fixes single changelog fixed groups. diff --git a/docs/config-file-options.md b/docs/config-file-options.md index 75c893563..c0b73f898 100644 --- a/docs/config-file-options.md +++ b/docs/config-file-options.md @@ -72,7 +72,7 @@ These restrictions exist to ensure your repository or published code do not end > NOTE: you can also provide glob expressions to match the packages, according to the [micromatch](https://www.npmjs.com/package/micromatch) format. -## `fixed` (array of arrays of package names) +## `fixed` (array of either arrays of package names or objects with `group` (array of package names), `changelog` (filepath relative to project root), and `name` properties) This option can be used to declare that packages should be version-bumped and published together. As an example, if you have a `@changesets/button` component and a `@changesets/theme` component and you want to make sure that when one gets bumped to `1.1.0`, the other is also bumped to `1.1.0` regardless if it has any change or not. To achieve this you would have the config: @@ -82,6 +82,20 @@ This option can be used to declare that packages should be version-bumped and pu } ``` +If you want to produce/update a single changelog for the group, you would have a config like so: + +```json +{ + "fixed": [ + { + "group": ["@changesets/button", "@changesets/theme"], + "changelog": "CHANGELOG.md", + "name": "UI Packages" + } + ] +} +``` + If you want to use this option, you should read the documentation on [fixed packages](./fixed-packages.md) to fully understand the implementation and implications. ## `linked` (array of arrays of package names) diff --git a/docs/fixed-packages.md b/docs/fixed-packages.md index d33354977..6101cebf9 100644 --- a/docs/fixed-packages.md +++ b/docs/fixed-packages.md @@ -47,3 +47,49 @@ For example: It will match all packages starting with `pkg-`. **The glob expressions must be defined according to the [micromatch](https://www.npmjs.com/package/micromatch) format.** + +## Single Changelog Group + +If you want to produce a single changelog for a fixed package group, use an object in your configuration like so: + +```json +{ + "fixed": [ + { + "group": ["pkg-a", "pkg-b", "pkg-c"], + "changelog": "CHANGELOG.md", + "name": "My Stuff" + } + ] +} +``` + +For example, if I have a changeset with a patch for pkg-a, a second changeset with a minor for pkg-b, and third changeset with a major for pkg-a and pkg-c and I do a release, the resulting changelog will be: + +``` +# My Stuff + +## 2.0.0 + +### Major Changes + +- [1234567] **(pkg-a, pkg-c)** Lorem ipsum. + +### Minor Changes + +- [2345678] **(pkg-b)** Blah blah. + +### Patch Changes + +- [3456789] **(pkg-a)** Something something. +``` + +Should I have another changeset that mixes packages and version types, such as a changeset for a patch for pkg-a and a major for pkg-b, the highest version type will win, resulting in a changelog entry like: + +``` +## 3.0.0 + +### Major Changes + +- [4567890] **(pkg-a, pkg-b)** Lorem ipsum. +``` diff --git a/packages/apply-release-plan/CHANGELOG.md b/packages/apply-release-plan/CHANGELOG.md index 523a35e5e..f684b4dfa 100644 --- a/packages/apply-release-plan/CHANGELOG.md +++ b/packages/apply-release-plan/CHANGELOG.md @@ -1,4 +1,60 @@ -# @changesets/apply-release-plan +# @abizzle/changesets-apply-release-plan + +## 7.0.0-next.3 + +### Patch Changes + +- c5a83f9: Fix logic to write a single changelog entry for fixed groups +- Updated dependencies [c5a83f9] + - @abizzle/changesets-types@6.0.0-next.3 + - @abizzle/changesets-config@2.4.0-next.1 + +## 7.0.0-next.2 + +### Patch Changes + +- Fixes dist files +- Updated dependencies + - @abizzle/changesets-types@6.0.0-next.2 + +## 7.0.0-next.1 + +### Major Changes + +- efd8c06: Fixes single changelog fixed groups. + +### Patch Changes + +- Updated dependencies [efd8c06] + - @abizzle/changesets-types@6.0.0-next.1 + +## 6.2.0-next.0 + +### Minor Changes + +- 850b82e: Add support for single changelog fixed package groups. + + Optionally supply an object as a fixed package group entry like so: + + ```json + { + "fixed": [ + { + "group": ["@changesets/button", "@changesets/theme"], + "changelog": "CHANGELOG.md", + "name": "UI Packages" + } + ] + } + ``` + + This will create/update a single changelog at `/CHANGELOG.md` with changelog entries for `@changesets/button` and `@changesets/theme` under the title "UI Packages". + +### Patch Changes + +- Updated dependencies [850b82e] + - @abizzle/changesets-config@2.4.0-next.0 + - @abizzle/changesets-types@5.3.0-next.0 ## 6.1.3 diff --git a/packages/apply-release-plan/package.json b/packages/apply-release-plan/package.json index 524909382..b1378eeb3 100644 --- a/packages/apply-release-plan/package.json +++ b/packages/apply-release-plan/package.json @@ -1,17 +1,17 @@ { - "name": "@changesets/apply-release-plan", - "version": "6.1.3", + "name": "@abizzle/changesets-apply-release-plan", + "version": "7.0.0-next.3", "description": "Takes a release plan and applies it to packages", - "main": "dist/apply-release-plan.cjs.js", - "module": "dist/apply-release-plan.esm.js", + "main": "dist/changesets-apply-release-plan.cjs.js", + "module": "dist/changesets-apply-release-plan.esm.js", "license": "MIT", "repository": "https://github.com/changesets/changesets/tree/main/packages/apply-release-plan", "dependencies": { + "@abizzle/changesets-config": "^2.4.0-next.1", + "@abizzle/changesets-types": "^6.0.0-next.3", "@babel/runtime": "^7.20.1", - "@changesets/config": "^2.3.0", "@changesets/get-version-range-type": "^0.3.2", "@changesets/git": "^2.0.0", - "@changesets/types": "^5.2.1", "@manypkg/get-packages": "^1.1.3", "detect-indent": "^6.0.0", "fs-extra": "^7.0.1", diff --git a/packages/apply-release-plan/src/get-changelog-entry.ts b/packages/apply-release-plan/src/get-changelog-entry.ts index 1f07982de..a98448ea0 100644 --- a/packages/apply-release-plan/src/get-changelog-entry.ts +++ b/packages/apply-release-plan/src/get-changelog-entry.ts @@ -1,6 +1,10 @@ -import { ChangelogFunctions, NewChangesetWithCommit } from "@changesets/types"; +import { + ChangelogFunctions, + ModCompGroupWithPackage, + NewChangesetWithCommit, +} from "@abizzle/changesets-types"; -import { ModCompWithPackage } from "@changesets/types"; +import { ModCompWithPackage } from "@abizzle/changesets-types"; import startCase from "lodash.startcase"; import { shouldUpdateDependencyBasedOnConfig } from "./utils"; @@ -22,7 +26,7 @@ async function generateChangesForVersionTypeMarkdown( } // release is the package and version we are releasing -export default async function getChangelogEntry( +export async function getChangelogEntryForIndividualRelease( release: ModCompWithPackage, releases: ModCompWithPackage[], changesets: NewChangesetWithCommit[], @@ -107,3 +111,42 @@ export default async function getChangelogEntry( .filter((line) => line) .join("\n"); } + +export async function getChangelogEntryForGroupRelease( + release: ModCompGroupWithPackage, + changesets: NewChangesetWithCommit[], + changelogFuncs: ChangelogFunctions, + changelogOpts: any +) { + if (release.projects.every((p) => p.type === "none")) return null; + + const changelogLines: ChangelogLines = { + major: [], + minor: [], + patch: [], + }; + + changesets.forEach((cs) => { + const rls = cs.releases.find((r) => + release.projects.some((p) => p.name === r.name) + ); + if (rls && rls.type !== "none") { + changelogLines[rls.type].push( + changelogFuncs.getReleaseLine( + { ...cs, groupedChangelog: true }, + rls.type, + changelogOpts + ) + ); + } + }); + + return [ + `## ${release.newVersion}`, + await generateChangesForVersionTypeMarkdown(changelogLines, "major"), + await generateChangesForVersionTypeMarkdown(changelogLines, "minor"), + await generateChangesForVersionTypeMarkdown(changelogLines, "patch"), + ] + .filter((line) => line) + .join("\n"); +} diff --git a/packages/apply-release-plan/src/index.test.ts b/packages/apply-release-plan/src/index.test.ts index 8d07a81b4..b570b6a2b 100644 --- a/packages/apply-release-plan/src/index.test.ts +++ b/packages/apply-release-plan/src/index.test.ts @@ -3,13 +3,14 @@ import { Config, NewChangeset, ComprehensiveRelease, -} from "@changesets/types"; + ComprehensiveGroupRelease, +} from "@abizzle/changesets-types"; import * as git from "@changesets/git"; import fs from "fs-extra"; import path from "path"; import outdent from "outdent"; import spawn from "spawndamnit"; -import { defaultConfig } from "@changesets/config"; +import { defaultConfig } from "@abizzle/changesets-config"; import applyReleasePlan from "./"; import { getPackages } from "@manypkg/get-packages"; @@ -21,7 +22,8 @@ import { class FakeReleasePlan { changesets: NewChangeset[]; - releases: ComprehensiveRelease[]; + individualReleases: ComprehensiveRelease[]; + groupedReleases: ComprehensiveGroupRelease[]; config: Config; constructor( @@ -64,13 +66,15 @@ class FakeReleasePlan { }; this.changesets = [baseChangeset, ...changesets]; - this.releases = [baseRelease, ...releases]; + this.individualReleases = [baseRelease, ...releases]; + this.groupedReleases = []; } getReleasePlan(): ReleasePlan { return { changesets: this.changesets, - releases: this.releases, + individualReleases: this.individualReleases, + groupedReleases: [], preState: undefined, }; } @@ -638,7 +642,7 @@ describe("apply release plan", () => { ], }, ], - releases: [ + individualReleases: [ { name: "pkg-a", type: "none", @@ -654,6 +658,7 @@ describe("apply release plan", () => { changesets: ["quick-lions-devour"], }, ], + groupedReleases: [], preState: undefined, }, { @@ -721,7 +726,7 @@ describe("apply release plan", () => { releases: [{ name: "self-referenced", type: "minor" }], }, ], - releases: [ + individualReleases: [ { name: "self-referenced", type: "minor", @@ -730,6 +735,7 @@ describe("apply release plan", () => { changesets: ["quick-lions-devour"], }, ], + groupedReleases: [], preState: undefined, }, { @@ -791,7 +797,7 @@ describe("apply release plan", () => { releases: [{ name: "pkg-b", type: "none" }], }, ], - releases: [ + individualReleases: [ { name: "pkg-b", type: "none", @@ -800,6 +806,7 @@ describe("apply release plan", () => { changesets: ["quick-lions-devour"], }, ], + groupedReleases: [], preState: undefined, }, { ...defaultConfig, changelog: false } @@ -848,7 +855,7 @@ describe("apply release plan", () => { releases: [{ name: "pkg-b", type: "none" }], }, ], - releases: [ + individualReleases: [ { name: "pkg-b", type: "none", @@ -857,6 +864,7 @@ describe("apply release plan", () => { changesets: ["quick-lions-devour"], }, ], + groupedReleases: [], preState: undefined, }, { ...defaultConfig, changelog: false } @@ -972,7 +980,7 @@ describe("apply release plan", () => { ], }, ], - releases: [ + individualReleases: [ { name: "pkg-a", type: "patch", @@ -988,6 +996,7 @@ describe("apply release plan", () => { changesets: ["quick-lions-devour"], }, ], + groupedReleases: [], preState: undefined, }, { @@ -1081,7 +1090,7 @@ describe("apply release plan", () => { ], }, ], - releases: [ + individualReleases: [ { name: "pkg-a", type: "patch", @@ -1104,6 +1113,7 @@ describe("apply release plan", () => { changesets: ["quick-lions-devour"], }, ], + groupedReleases: [], preState: undefined, }, { @@ -1189,7 +1199,7 @@ describe("apply release plan", () => { ], }, ], - releases: [ + individualReleases: [ { name: "pkg-a", type: "minor", @@ -1205,6 +1215,7 @@ describe("apply release plan", () => { changesets: ["quick-lions-devour"], }, ], + groupedReleases: [], preState: undefined, }, { @@ -1289,7 +1300,7 @@ describe("apply release plan", () => { ], }, ], - releases: [ + individualReleases: [ { name: "pkg-a", type: "major", @@ -1305,6 +1316,7 @@ describe("apply release plan", () => { changesets: ["quick-lions-devour"], }, ], + groupedReleases: [], preState: undefined, }, { @@ -1392,7 +1404,7 @@ describe("apply release plan", () => { ], }, ], - releases: [ + individualReleases: [ { name: "pkg-a", type: "patch", @@ -1408,6 +1420,7 @@ describe("apply release plan", () => { changesets: ["quick-lions-devour"], }, ], + groupedReleases: [], preState: undefined, }, { @@ -1501,7 +1514,7 @@ describe("apply release plan", () => { ], }, ], - releases: [ + individualReleases: [ { name: "pkg-a", type: "patch", @@ -1524,6 +1537,7 @@ describe("apply release plan", () => { changesets: ["quick-lions-devour"], }, ], + groupedReleases: [], preState: undefined, }, { @@ -1617,7 +1631,7 @@ describe("apply release plan", () => { ], }, ], - releases: [ + individualReleases: [ { name: "pkg-a", type: "minor", @@ -1633,6 +1647,7 @@ describe("apply release plan", () => { changesets: ["quick-lions-devour"], }, ], + groupedReleases: [], preState: undefined, }, { @@ -1717,7 +1732,7 @@ describe("apply release plan", () => { ], }, ], - releases: [ + individualReleases: [ { name: "pkg-a", type: "major", @@ -1733,6 +1748,7 @@ describe("apply release plan", () => { changesets: ["quick-lions-devour"], }, ], + groupedReleases: [], preState: undefined, }, { @@ -1818,7 +1834,7 @@ describe("apply release plan", () => { ], }, ], - releases: [ + individualReleases: [ { name: "has-peer-dep", type: "patch", @@ -1834,6 +1850,7 @@ describe("apply release plan", () => { changesets: ["quick-lions-devour"], }, ], + groupedReleases: [], preState: undefined, }, { @@ -2047,7 +2064,7 @@ describe("apply release plan", () => { ], }, ], - releases: [ + individualReleases: [ { name: "pkg-a", type: "none", @@ -2063,6 +2080,7 @@ describe("apply release plan", () => { changesets: ["quick-lions-devour"], }, ], + groupedReleases: [], preState: undefined, }, { @@ -2109,7 +2127,10 @@ describe("apply release plan", () => { releases: [{ name: "pkg-a", type: "minor" }], }, ]); - releasePlan.releases[0].changesets.push("some-id-1", "some-id-2"); + releasePlan.individualReleases[0].changesets.push( + "some-id-1", + "some-id-2" + ); let { changedFiles } = await testSetup( { @@ -2185,7 +2206,7 @@ describe("apply release plan", () => { ], }, ], - releases: [ + individualReleases: [ { name: "pkg-a", type: "patch", @@ -2201,6 +2222,7 @@ describe("apply release plan", () => { changesets: ["quick-lions-devour"], }, ], + groupedReleases: [], preState: undefined, }, { @@ -2294,7 +2316,7 @@ describe("apply release plan", () => { ], }, ], - releases: [ + individualReleases: [ { name: "pkg-a", type: "patch", @@ -2310,6 +2332,7 @@ describe("apply release plan", () => { changesets: ["quick-lions-devour"], }, ], + groupedReleases: [], preState: undefined, }, { @@ -2408,7 +2431,7 @@ describe("apply release plan", () => { ], }, ], - releases: [ + individualReleases: [ { name: "pkg-a", type: "patch", @@ -2431,6 +2454,7 @@ describe("apply release plan", () => { changesets: ["quick-lions-devour"], }, ], + groupedReleases: [], preState: undefined, }, { @@ -2543,7 +2567,7 @@ describe("apply release plan", () => { ], }, ], - releases: [ + individualReleases: [ { name: "pkg-a", type: "patch", @@ -2566,6 +2590,7 @@ describe("apply release plan", () => { changesets: ["quick-lions-devour"], }, ], + groupedReleases: [], preState: undefined, }, { @@ -2661,7 +2686,7 @@ describe("apply release plan", () => { releases: [{ name: "pkg-a", type: "minor" }], }, ], - releases: [ + individualReleases: [ { name: "pkg-a", type: "minor", @@ -2677,6 +2702,7 @@ describe("apply release plan", () => { changesets: ["quick-lions-devour"], }, ], + groupedReleases: [], preState: undefined, } ); diff --git a/packages/apply-release-plan/src/index.ts b/packages/apply-release-plan/src/index.ts index 356f82d54..21ee702b8 100644 --- a/packages/apply-release-plan/src/index.ts +++ b/packages/apply-release-plan/src/index.ts @@ -4,9 +4,10 @@ import { ChangelogFunctions, NewChangeset, ModCompWithPackage, -} from "@changesets/types"; + ModCompGroupWithPackage, +} from "@abizzle/changesets-types"; -import { defaultConfig } from "@changesets/config"; +import { defaultConfig } from "@abizzle/changesets-config"; import * as git from "@changesets/git"; import resolveFrom from "resolve-from"; import { Packages } from "@manypkg/get-packages"; @@ -17,7 +18,10 @@ import path from "path"; import prettier from "prettier"; import versionPackage from "./version-package"; -import getChangelogEntry from "./get-changelog-entry"; +import { + getChangelogEntryForIndividualRelease, + getChangelogEntryForGroupRelease, +} from "./get-changelog-entry"; function getPrettierInstance(cwd: string): typeof prettier { try { @@ -81,9 +85,24 @@ export default async function applyReleasePlan( packages.packages.map((x) => [x.packageJson.name, x]) ); - let { releases, changesets } = releasePlan; + let { individualReleases, groupedReleases, changesets } = releasePlan; + + let groupedReleasesWithPackage = groupedReleases.map((group) => ({ + ...group, + projects: group.projects.map((project) => { + let pkg = packagesByName.get(project.name); + if (!pkg) + throw new Error( + `Could not find matching package for release of: ${project.name}` + ); + return { + ...project, + ...pkg, + }; + }), + })); - let releasesWithPackage = releases.map((release) => { + let releasesWithPackage = individualReleases.map((release) => { let pkg = packagesByName.get(release.name); if (!pkg) throw new Error( @@ -96,12 +115,14 @@ export default async function applyReleasePlan( }); // I think this might be the wrong place to do this, but gotta do it somewhere - add changelog entries to releases - let releaseWithChangelogs = await getNewChangelogEntry( - releasesWithPackage, - changesets, - config, - cwd - ); + let { individualReleasesWithChangelogs, groupedReleasesWithChangelogs } = + await getNewChangelogEntry( + groupedReleasesWithPackage, + releasesWithPackage, + changesets, + config, + cwd + ); if (releasePlan.preState !== undefined && snapshot === undefined) { if (releasePlan.preState.mode === "exit") { @@ -114,29 +135,64 @@ export default async function applyReleasePlan( } } - let versionsToUpdate = releases.map(({ name, newVersion, type }) => ({ - name, - version: newVersion, - type, - })); + let versionsToUpdate = individualReleases + .map(({ name, newVersion, type }) => ({ + name, + version: newVersion, + type, + })) + .concat( + ...groupedReleases.flatMap((group) => + group.projects.map((p) => ({ + name: p.name, + version: group.newVersion, + type: p.type, + })) + ) + ); // iterate over releases updating packages - let finalisedRelease = releaseWithChangelogs.map((release) => { - return versionPackage(release, versionsToUpdate, { - updateInternalDependencies: config.updateInternalDependencies, - onlyUpdatePeerDependentsWhenOutOfRange: - config.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH - .onlyUpdatePeerDependentsWhenOutOfRange, - bumpVersionsWithWorkspaceProtocolOnly: - config.bumpVersionsWithWorkspaceProtocolOnly, - snapshot, - }); + let finalisedIndividualRelease = individualReleasesWithChangelogs.map( + (release) => { + return versionPackage(release, versionsToUpdate, { + updateInternalDependencies: config.updateInternalDependencies, + onlyUpdatePeerDependentsWhenOutOfRange: + config.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH + .onlyUpdatePeerDependentsWhenOutOfRange, + bumpVersionsWithWorkspaceProtocolOnly: + config.bumpVersionsWithWorkspaceProtocolOnly, + snapshot, + }); + } + ); + let finalisedGroupRelease = groupedReleasesWithChangelogs.map((release) => { + return { + ...release, + projects: release.projects.map((project) => { + return versionPackage( + { + ...release, + ...project, + }, + versionsToUpdate, + { + updateInternalDependencies: config.updateInternalDependencies, + onlyUpdatePeerDependentsWhenOutOfRange: + config.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH + .onlyUpdatePeerDependentsWhenOutOfRange, + bumpVersionsWithWorkspaceProtocolOnly: + config.bumpVersionsWithWorkspaceProtocolOnly, + snapshot, + } + ); + }), + }; }); let prettierInstance = getPrettierInstance(cwd); let prettierConfig = await prettierInstance.resolveConfig(cwd); - for (let release of finalisedRelease) { + for (let release of finalisedIndividualRelease) { let { changelog, packageJson, dir, name } = release; const pkgJSONPath = path.resolve(dir, "package.json"); @@ -145,6 +201,7 @@ export default async function applyReleasePlan( if (changelog && changelog.length > 0) { const changelogPath = path.resolve(dir, "CHANGELOG.md"); + await updateChangelog( changelogPath, changelog, @@ -156,6 +213,30 @@ export default async function applyReleasePlan( } } + for (let release of finalisedGroupRelease) { + let { changelog, displayName, relativeChangelogPath, projects } = release; + + for (let project of projects) { + const { dir, packageJson } = project; + const pkgJSONPath = path.resolve(dir, "package.json"); + await updatePackageJson(pkgJSONPath, packageJson); + touchedFiles.push(pkgJSONPath); + } + + if (changelog && changelog.length > 0) { + const changelogPath = path.resolve(cwd, relativeChangelogPath); + + await updateChangelog( + changelogPath, + changelog, + displayName, + prettierInstance, + prettierConfig + ); + touchedFiles.push(changelogPath); + } + } + if ( releasePlan.preState === undefined || releasePlan.preState.mode === "exit" @@ -193,18 +274,25 @@ export default async function applyReleasePlan( } async function getNewChangelogEntry( + groupReleasesWithPackage: ModCompGroupWithPackage[], releasesWithPackage: ModCompWithPackage[], changesets: NewChangeset[], config: Config, cwd: string ) { if (!config.changelog) { - return Promise.resolve( - releasesWithPackage.map((release) => ({ + return Promise.resolve({ + individualReleasesWithChangelogs: releasesWithPackage.map((release) => ({ ...release, changelog: null, - })) - ); + })), + groupedReleasesWithChangelogs: groupReleasesWithPackage.map( + (release) => ({ + ...release, + changelog: null, + }) + ), + }); } let getChangelogFuncs: ChangelogFunctions = { @@ -238,9 +326,9 @@ async function getNewChangelogEntry( commit: commits[i], })); - return Promise.all( + let individualReleasesWithChangelogs = await Promise.all( releasesWithPackage.map(async (release) => { - let changelog = await getChangelogEntry( + let changelog = await getChangelogEntryForIndividualRelease( release, releasesWithPackage, moddedChangesets, @@ -268,6 +356,35 @@ async function getNewChangelogEntry( ); throw e; }); + + let groupedReleasesWithChangelogs = await Promise.all( + groupReleasesWithPackage.map(async (release) => { + let changelog = await getChangelogEntryForGroupRelease( + release, + moddedChangesets, + getChangelogFuncs, + changelogOpts + ); + + return { + ...release, + changelog, + }; + }) + ).catch((e) => { + console.error( + "The following error was encountered while generating changelog entries" + ); + console.error( + "We have escaped applying the changesets, and no files should have been affected" + ); + throw e; + }); + + return { + individualReleasesWithChangelogs, + groupedReleasesWithChangelogs, + }; } async function updateChangelog( diff --git a/packages/apply-release-plan/src/test-utils/get-changelog-entry-with-git-hash.ts b/packages/apply-release-plan/src/test-utils/get-changelog-entry-with-git-hash.ts index b9132026c..6ac784344 100644 --- a/packages/apply-release-plan/src/test-utils/get-changelog-entry-with-git-hash.ts +++ b/packages/apply-release-plan/src/test-utils/get-changelog-entry-with-git-hash.ts @@ -1,7 +1,7 @@ /* eslint-disable import/no-extraneous-dependencies */ import startCase from "lodash.startcase"; import { getCommitsThatAddFiles } from "@changesets/git"; -import { ComprehensiveRelease, NewChangeset } from "@changesets/types"; +import { ComprehensiveRelease, NewChangeset } from "@abizzle/changesets-types"; import { RelevantChangesets } from "../types"; diff --git a/packages/apply-release-plan/src/types.ts b/packages/apply-release-plan/src/types.ts index d87214bbc..b5b24fbfd 100644 --- a/packages/apply-release-plan/src/types.ts +++ b/packages/apply-release-plan/src/types.ts @@ -1,4 +1,4 @@ -import { NewChangeset } from "@changesets/types"; +import { NewChangeset } from "@abizzle/changesets-types"; export type RelevantChangesets = { major: NewChangeset[]; diff --git a/packages/apply-release-plan/src/utils.ts b/packages/apply-release-plan/src/utils.ts index 331996d6c..1b166a6fc 100644 --- a/packages/apply-release-plan/src/utils.ts +++ b/packages/apply-release-plan/src/utils.ts @@ -2,7 +2,7 @@ * Shared utility functions and business logic */ import semver from "semver"; -import { VersionType } from "@changesets/types"; +import { VersionType } from "@abizzle/changesets-types"; const bumpTypes = ["none", "patch", "minor", "major"]; diff --git a/packages/apply-release-plan/src/version-package.ts b/packages/apply-release-plan/src/version-package.ts index a5087e8f2..7ac2f8ffa 100644 --- a/packages/apply-release-plan/src/version-package.ts +++ b/packages/apply-release-plan/src/version-package.ts @@ -1,8 +1,4 @@ -import { - ComprehensiveRelease, - PackageJSON, - VersionType, -} from "@changesets/types"; +import { PackageJSON, VersionType } from "@abizzle/changesets-types"; import getVersionRangeType from "@changesets/get-version-range-type"; import semver from "semver"; import { shouldUpdateDependencyBasedOnConfig } from "./utils"; @@ -14,12 +10,10 @@ const DEPENDENCY_TYPES = [ "optionalDependencies", ] as const; -export default function versionPackage( - release: ComprehensiveRelease & { - changelog: string | null; - packageJson: PackageJSON; - dir: string; - }, +export default function versionPackage< + T extends { newVersion: string; packageJson: PackageJSON } +>( + release: T, versionsToUpdate: Array<{ name: string; version: string; type: VersionType }>, { updateInternalDependencies, diff --git a/packages/assemble-release-plan/CHANGELOG.md b/packages/assemble-release-plan/CHANGELOG.md index fec8bb581..8ef92d2ec 100644 --- a/packages/assemble-release-plan/CHANGELOG.md +++ b/packages/assemble-release-plan/CHANGELOG.md @@ -1,4 +1,57 @@ -# @changesets/assemble-release-plan +# @abizzle/changesets-assemble-release-plan + +## 6.0.0-next.3 + +### Patch Changes + +- Updated dependencies [c5a83f9] + - @abizzle/changesets-types@6.0.0-next.3 + +## 6.0.0-next.2 + +### Patch Changes + +- Fixes dist files +- Updated dependencies + - @abizzle/changesets-types@6.0.0-next.2 + +## 6.0.0-next.1 + +### Major Changes + +- efd8c06: Fixes single changelog fixed groups. + +### Patch Changes + +- Updated dependencies [efd8c06] + - @abizzle/changesets-types@6.0.0-next.1 + +## 5.3.0-next.0 + +### Minor Changes + +- 850b82e: Add support for single changelog fixed package groups. + + Optionally supply an object as a fixed package group entry like so: + + ```json + { + "fixed": [ + { + "group": ["@changesets/button", "@changesets/theme"], + "changelog": "CHANGELOG.md", + "name": "UI Packages" + } + ] + } + ``` + + This will create/update a single changelog at `/CHANGELOG.md` with changelog entries for `@changesets/button` and `@changesets/theme` under the title "UI Packages". + +### Patch Changes + +- Updated dependencies [850b82e] + - @abizzle/changesets-types@5.3.0-next.0 ## 5.2.3 diff --git a/packages/assemble-release-plan/package.json b/packages/assemble-release-plan/package.json index 3289e4318..5e36a833c 100644 --- a/packages/assemble-release-plan/package.json +++ b/packages/assemble-release-plan/package.json @@ -1,20 +1,20 @@ { - "name": "@changesets/assemble-release-plan", - "version": "5.2.3", + "name": "@abizzle/changesets-assemble-release-plan", + "version": "6.0.0-next.3", "description": "Reads changesets and adds information on dependents that need bumping", - "main": "dist/assemble-release-plan.cjs.js", - "module": "dist/assemble-release-plan.esm.js", + "main": "dist/changesets-assemble-release-plan.cjs.js", + "module": "dist/changesets-assemble-release-plan.esm.js", "license": "MIT", "repository": "https://github.com/changesets/changesets/tree/main/packages/assemble-release-plan", "dependencies": { + "@abizzle/changesets-types": "^6.0.0-next.3", "@babel/runtime": "^7.20.1", "@changesets/errors": "^0.1.4", "@changesets/get-dependents-graph": "^1.3.5", - "@changesets/types": "^5.2.1", "@manypkg/get-packages": "^1.1.3", "semver": "^5.4.1" }, "devDependencies": { - "@changesets/config": "*" + "@abizzle/changesets-config": "2.4.0-next.1" } } diff --git a/packages/assemble-release-plan/src/apply-links.ts b/packages/assemble-release-plan/src/apply-links.ts index e954f65ee..467fbfd0d 100644 --- a/packages/assemble-release-plan/src/apply-links.ts +++ b/packages/assemble-release-plan/src/apply-links.ts @@ -1,4 +1,4 @@ -import { Linked } from "@changesets/types"; +import { Linked } from "@abizzle/changesets-types"; import { Package } from "@manypkg/get-packages"; import { InternalRelease } from "./types"; import { getCurrentHighestVersion, getHighestReleaseType } from "./utils"; diff --git a/packages/assemble-release-plan/src/determine-dependents.ts b/packages/assemble-release-plan/src/determine-dependents.ts index 97359614f..52eee7690 100644 --- a/packages/assemble-release-plan/src/determine-dependents.ts +++ b/packages/assemble-release-plan/src/determine-dependents.ts @@ -4,7 +4,7 @@ import { PackageJSON, VersionType, Config, -} from "@changesets/types"; +} from "@abizzle/changesets-types"; import { Package } from "@manypkg/get-packages"; import { InternalRelease, PreInfo } from "./types"; import { incrementVersion } from "./increment"; diff --git a/packages/assemble-release-plan/src/flatten-releases.ts b/packages/assemble-release-plan/src/flatten-releases.ts index 0055c1279..345a8de1e 100644 --- a/packages/assemble-release-plan/src/flatten-releases.ts +++ b/packages/assemble-release-plan/src/flatten-releases.ts @@ -1,7 +1,7 @@ // This function takes in changesets and returns one release per // package listed in the changesets -import { NewChangeset } from "@changesets/types"; +import { NewChangeset } from "@abizzle/changesets-types"; import { Package } from "@manypkg/get-packages"; import { InternalRelease } from "./types"; diff --git a/packages/assemble-release-plan/src/index.test.ts b/packages/assemble-release-plan/src/index.test.ts index 24d958379..d7b3f66af 100644 --- a/packages/assemble-release-plan/src/index.test.ts +++ b/packages/assemble-release-plan/src/index.test.ts @@ -1,4 +1,4 @@ -import { defaultConfig } from "@changesets/config"; +import { defaultConfig } from "@abizzle/changesets-config"; import assembleReleasePlan from "./"; import FakeFullState from "./test-utils"; @@ -14,15 +14,15 @@ describe("assemble-release-plan", () => { }); it("should assemble release plan for basic setup", () => { - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toBe(1); - expect(releases[0]).toEqual({ + expect(individualReleases.length).toBe(1); + expect(individualReleases[0]).toEqual({ name: "pkg-a", type: "patch", newVersion: "1.0.1", @@ -32,7 +32,7 @@ describe("assemble-release-plan", () => { }); it("should assemble release plan for basic setup with snapshot", () => { - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, @@ -42,12 +42,14 @@ describe("assemble-release-plan", () => { } ); - expect(releases.length).toBe(1); - expect(/0\.0\.0-\d{14}/.test(releases[0].newVersion)).toBeTruthy(); + expect(individualReleases.length).toBe(1); + expect( + /0\.0\.0-\d{14}/.test(individualReleases[0].newVersion) + ).toBeTruthy(); }); it("should assemble release plan for basic setup with snapshot and tag", () => { - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, @@ -57,8 +59,10 @@ describe("assemble-release-plan", () => { } ); - expect(releases.length).toBe(1); - expect(/0\.0\.0-foo-\d{14}/.test(releases[0].newVersion)).toBeTruthy(); + expect(individualReleases.length).toBe(1); + expect( + /0\.0\.0-foo-\d{14}/.test(individualReleases[0].newVersion) + ).toBeTruthy(); }); it("should assemble release plan with multiple packages", () => { @@ -71,22 +75,22 @@ describe("assemble-release-plan", () => { ], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toBe(4); - expect(releases[0].name).toBe("pkg-a"); - expect(releases[0].newVersion).toBe("1.0.1"); - expect(releases[1].name).toBe("pkg-b"); - expect(releases[1].newVersion).toBe("1.0.1"); - expect(releases[2].name).toBe("pkg-c"); - expect(releases[2].newVersion).toBe("1.0.1"); - expect(releases[3].name).toBe("pkg-d"); - expect(releases[3].newVersion).toBe("2.0.0"); + expect(individualReleases.length).toBe(4); + expect(individualReleases[0].name).toBe("pkg-a"); + expect(individualReleases[0].newVersion).toBe("1.0.1"); + expect(individualReleases[1].name).toBe("pkg-b"); + expect(individualReleases[1].newVersion).toBe("1.0.1"); + expect(individualReleases[2].name).toBe("pkg-c"); + expect(individualReleases[2].newVersion).toBe("1.0.1"); + expect(individualReleases[3].name).toBe("pkg-d"); + expect(individualReleases[3].newVersion).toBe("2.0.0"); }); it("should handle two changesets for a package", () => { setup.addChangeset({ @@ -94,17 +98,17 @@ describe("assemble-release-plan", () => { releases: [{ name: "pkg-a", type: "major" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toEqual(1); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].type).toEqual("major"); - expect(releases[0].newVersion).toEqual("2.0.0"); + expect(individualReleases.length).toEqual(1); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].type).toEqual("major"); + expect(individualReleases[0].newVersion).toEqual("2.0.0"); }); it("`none` changeset should not override other release types", () => { setup.addChangeset({ @@ -132,26 +136,26 @@ describe("assemble-release-plan", () => { ], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toEqual(3); + expect(individualReleases.length).toEqual(3); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].type).toEqual("patch"); - expect(releases[0].newVersion).toEqual("1.0.1"); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].type).toEqual("patch"); + expect(individualReleases[0].newVersion).toEqual("1.0.1"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].type).toEqual("minor"); - expect(releases[1].newVersion).toEqual("1.1.0"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].type).toEqual("minor"); + expect(individualReleases[1].newVersion).toEqual("1.1.0"); - expect(releases[2].name).toEqual("pkg-c"); - expect(releases[2].type).toEqual("major"); - expect(releases[2].newVersion).toEqual("2.0.0"); + expect(individualReleases[2].name).toEqual("pkg-c"); + expect(individualReleases[2].type).toEqual("major"); + expect(individualReleases[2].newVersion).toEqual("2.0.0"); }); it("should assemble release plan with dependents", () => { setup.updateDependency("pkg-b", "pkg-a", "^1.0.0"); @@ -160,57 +164,57 @@ describe("assemble-release-plan", () => { releases: [{ name: "pkg-a", type: "major" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toEqual(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("2.0.0"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].newVersion).toEqual("1.0.1"); - expect(releases[1].changesets).toEqual([]); + expect(individualReleases.length).toEqual(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("2.0.0"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].newVersion).toEqual("1.0.1"); + expect(individualReleases[1].changesets).toEqual([]); }); it("should update multiple dependents of a single package", () => { setup.updateDependency("pkg-b", "pkg-a", "1.0.0"); setup.updateDependency("pkg-c", "pkg-a", "1.0.0"); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toEqual(3); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("1.0.1"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].newVersion).toEqual("1.0.1"); - expect(releases[2].name).toEqual("pkg-c"); - expect(releases[2].newVersion).toEqual("1.0.1"); + expect(individualReleases.length).toEqual(3); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("1.0.1"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].newVersion).toEqual("1.0.1"); + expect(individualReleases[2].name).toEqual("pkg-c"); + expect(individualReleases[2].newVersion).toEqual("1.0.1"); }); it("should update a second dependent based on updating a first dependent", () => { setup.updateDependency("pkg-b", "pkg-a", "1.0.0"); setup.updateDependency("pkg-c", "pkg-b", "1.0.0"); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toEqual(3); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("1.0.1"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].newVersion).toEqual("1.0.1"); - expect(releases[2].name).toEqual("pkg-c"); - expect(releases[2].newVersion).toEqual("1.0.1"); + expect(individualReleases.length).toEqual(3); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("1.0.1"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].newVersion).toEqual("1.0.1"); + expect(individualReleases[2].name).toEqual("pkg-c"); + expect(individualReleases[2].newVersion).toEqual("1.0.1"); }); it("should assemble release plan with without a wildcard dependent", () => { setup.updateDependency("pkg-b", "pkg-a", "*"); @@ -219,16 +223,16 @@ describe("assemble-release-plan", () => { releases: [{ name: "pkg-a", type: "major" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toEqual(1); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("2.0.0"); + expect(individualReleases.length).toEqual(1); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("2.0.0"); }); it("should assemble the release plan only with workspace protocol dependents when using bumpVersionsWithWorkspaceProtocolOnly", () => { @@ -239,7 +243,7 @@ describe("assemble-release-plan", () => { releases: [{ name: "pkg-a", type: "major" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -249,12 +253,12 @@ describe("assemble-release-plan", () => { undefined ); - expect(releases.length).toEqual(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("2.0.0"); - expect(releases[1].name).toEqual("pkg-c"); - expect(releases[1].newVersion).toEqual("1.0.1"); - expect(releases[1].changesets).toEqual([]); + expect(individualReleases.length).toEqual(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("2.0.0"); + expect(individualReleases[1].name).toEqual("pkg-c"); + expect(individualReleases[1].newVersion).toEqual("1.0.1"); + expect(individualReleases[1].changesets).toEqual([]); }); it("should assemble the release plan with workspace:^ and workspace:~ dependents", () => { setup.updateDependency("pkg-b", "pkg-a", "workspace:~"); @@ -264,7 +268,7 @@ describe("assemble-release-plan", () => { releases: [{ name: "pkg-a", type: "major" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -274,18 +278,18 @@ describe("assemble-release-plan", () => { undefined ); - expect(releases.length).toEqual(3); + expect(individualReleases.length).toEqual(3); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("2.0.0"); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("2.0.0"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].newVersion).toEqual("1.0.1"); - expect(releases[1].changesets).toEqual([]); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].newVersion).toEqual("1.0.1"); + expect(individualReleases[1].changesets).toEqual([]); - expect(releases[2].name).toEqual("pkg-c"); - expect(releases[2].newVersion).toEqual("1.0.1"); - expect(releases[2].changesets).toEqual([]); + expect(individualReleases[2].name).toEqual("pkg-c"); + expect(individualReleases[2].newVersion).toEqual("1.0.1"); + expect(individualReleases[2].changesets).toEqual([]); }); it("should assemble release plan without dependent through dev dependency", () => { setup.updateDevDependency("pkg-b", "pkg-a", "^1.0.0"); @@ -294,18 +298,18 @@ describe("assemble-release-plan", () => { releases: [{ name: "pkg-a", type: "major" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toEqual(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("2.0.0"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].newVersion).toEqual("1.0.0"); + expect(individualReleases.length).toEqual(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("2.0.0"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].newVersion).toEqual("1.0.0"); }); it("should assemble release plan with dependent when the dependent has both a changed prod and dev dependency", () => { setup.updateDevDependency("pkg-b", "pkg-a", "^1.0.0"); @@ -318,21 +322,21 @@ describe("assemble-release-plan", () => { ], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toEqual(3); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("2.0.0"); - expect(releases[1].name).toEqual("pkg-c"); - expect(releases[1].newVersion).toEqual("2.0.0"); - expect(releases[2].name).toEqual("pkg-b"); - expect(releases[2].oldVersion).toEqual("1.0.0"); - expect(releases[2].newVersion).toEqual("1.0.1"); + expect(individualReleases.length).toEqual(3); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("2.0.0"); + expect(individualReleases[1].name).toEqual("pkg-c"); + expect(individualReleases[1].newVersion).toEqual("2.0.0"); + expect(individualReleases[2].name).toEqual("pkg-b"); + expect(individualReleases[2].oldVersion).toEqual("1.0.0"); + expect(individualReleases[2].newVersion).toEqual("1.0.1"); }); it("should assemble release plan without dependencies when the dependent has a changeset type of none", () => { setup.updateDependency("pkg-c", "pkg-b", "^1.0.0"); @@ -341,18 +345,18 @@ describe("assemble-release-plan", () => { releases: [{ name: "pkg-b", type: "none" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toEqual(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].oldVersion).toEqual("1.0.0"); - expect(releases[1].newVersion).toEqual("1.0.0"); + expect(individualReleases.length).toEqual(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].oldVersion).toEqual("1.0.0"); + expect(individualReleases[1].newVersion).toEqual("1.0.0"); }); it("should assemble release plan without dependent through the link protocol", () => { setup.updateDevDependency("pkg-b", "pkg-a", "link:../pkg-a"); @@ -361,16 +365,16 @@ describe("assemble-release-plan", () => { releases: [{ name: "pkg-a", type: "major" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toEqual(1); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("2.0.0"); + expect(individualReleases.length).toEqual(1); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("2.0.0"); }); it("should assemble release plan without dependent through the file protocol", () => { setup.updateDevDependency("pkg-b", "pkg-a", "file:../pkg-a"); @@ -379,16 +383,16 @@ describe("assemble-release-plan", () => { releases: [{ name: "pkg-a", type: "major" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toEqual(1); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("2.0.0"); + expect(individualReleases.length).toEqual(1); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("2.0.0"); }); it("should update a peerDep by a major bump", () => { setup.updatePeerDependency("pkg-b", "pkg-a", "~1.0.0"); @@ -397,18 +401,18 @@ describe("assemble-release-plan", () => { releases: [{ name: "pkg-a", type: "minor" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toEqual(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("1.1.0"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].newVersion).toEqual("2.0.0"); + expect(individualReleases.length).toEqual(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("1.1.0"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].newVersion).toEqual("2.0.0"); }); it("should assemble release plan without ignored packages", () => { setup.addChangeset({ @@ -419,7 +423,7 @@ describe("assemble-release-plan", () => { id: "small-dogs-sad", releases: [{ name: "pkg-b", type: "minor" }], }); - const { releases } = assembleReleasePlan( + const { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -429,11 +433,11 @@ describe("assemble-release-plan", () => { undefined ); - expect(releases.length).toEqual(1); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("2.0.0"); + expect(individualReleases.length).toEqual(1); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("2.0.0"); }); - it("should generate releases with 'none' release type for ignored packages through dependencies", () => { + it("should generate individualReleases with 'none' release type for ignored packages through dependencies", () => { setup.updateDependency("pkg-b", "pkg-a", "1.0.0"); setup.addChangeset({ id: "big-cats-delight", @@ -443,7 +447,7 @@ describe("assemble-release-plan", () => { id: "small-dogs-sad", releases: [{ name: "pkg-b", type: "minor" }], }); - const { releases } = assembleReleasePlan( + const { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -453,14 +457,14 @@ describe("assemble-release-plan", () => { undefined ); - expect(releases.length).toEqual(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("2.0.0"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].type).toEqual("none"); - expect(releases[1].newVersion).toEqual("1.0.0"); + expect(individualReleases.length).toEqual(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("2.0.0"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].type).toEqual("none"); + expect(individualReleases[1].newVersion).toEqual("1.0.0"); }); - it("should generate releases with 'none' release type for ignored packages through peerDependencies", () => { + it("should generate individualReleases with 'none' release type for ignored packages through peerDependencies", () => { setup.updatePeerDependency("pkg-b", "pkg-a", "1.0.0"); setup.addChangeset({ id: "big-cats-delight", @@ -470,7 +474,7 @@ describe("assemble-release-plan", () => { id: "small-dogs-sad", releases: [{ name: "pkg-b", type: "minor" }], }); - const { releases } = assembleReleasePlan( + const { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -480,14 +484,14 @@ describe("assemble-release-plan", () => { undefined ); - expect(releases.length).toEqual(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("2.0.0"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].type).toEqual("none"); - expect(releases[1].newVersion).toEqual("1.0.0"); + expect(individualReleases.length).toEqual(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("2.0.0"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].type).toEqual("none"); + expect(individualReleases[1].newVersion).toEqual("1.0.0"); }); - it("should generate releases with 'none' release type for ignored packages through devDependencies", () => { + it("should generate individualReleases with 'none' release type for ignored packages through devDependencies", () => { setup.updateDevDependency("pkg-b", "pkg-a", "1.0.0"); setup.addChangeset({ id: "big-cats-delight", @@ -497,7 +501,7 @@ describe("assemble-release-plan", () => { id: "small-dogs-sad", releases: [{ name: "pkg-b", type: "minor" }], }); - const { releases } = assembleReleasePlan( + const { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -507,12 +511,12 @@ describe("assemble-release-plan", () => { undefined ); - expect(releases.length).toEqual(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("2.0.0"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].type).toEqual("none"); - expect(releases[1].newVersion).toEqual("1.0.0"); + expect(individualReleases.length).toEqual(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("2.0.0"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].type).toEqual("none"); + expect(individualReleases[1].newVersion).toEqual("1.0.0"); }); // Mixed changesets are the ones that contains both ignored packages and not ignored packages it("should throw for mixed changesets", () => { @@ -546,18 +550,18 @@ Mixed changesets that contain both ignored and not ignored packages are not allo setup.updateDevDependency("pkg-b", "pkg-a", "1.0.0"); setup.updateDependency("pkg-c", "pkg-b", "1.0.0"); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toBe(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("1.0.1"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].newVersion).toEqual("1.0.0"); + expect(individualReleases.length).toBe(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("1.0.1"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].newVersion).toEqual("1.0.0"); }); describe("fixed packages", () => { @@ -567,7 +571,7 @@ Mixed changesets that contain both ignored and not ignored packages are not allo releases: [{ name: "pkg-a", type: "minor" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -577,9 +581,9 @@ Mixed changesets that contain both ignored and not ignored packages are not allo undefined ); - expect(releases.length).toEqual(2); - expect(releases[0].newVersion).toEqual("1.1.0"); - expect(releases[1].newVersion).toEqual("1.1.0"); + expect(individualReleases.length).toEqual(2); + expect(individualReleases[0].newVersion).toEqual("1.1.0"); + expect(individualReleases[1].newVersion).toEqual("1.1.0"); }); it("should assemble a release plan where new highest version is set by an unreleased package", () => { setup.addChangeset({ @@ -592,7 +596,7 @@ Mixed changesets that contain both ignored and not ignored packages are not allo setup.updatePackage("pkg-c", "2.0.0"); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -602,10 +606,10 @@ Mixed changesets that contain both ignored and not ignored packages are not allo undefined ); - expect(releases.length).toEqual(3); - expect(releases[0].newVersion).toEqual("2.1.0"); - expect(releases[1].newVersion).toEqual("2.1.0"); - expect(releases[2].newVersion).toEqual("2.1.0"); + expect(individualReleases.length).toEqual(3); + expect(individualReleases[0].newVersion).toEqual("2.1.0"); + expect(individualReleases[1].newVersion).toEqual("2.1.0"); + expect(individualReleases[2].newVersion).toEqual("2.1.0"); }); it("should assemble release plan where a fixed constraint causes a dependency to need changing which causes a second fixed group to update", () => { @@ -625,7 +629,7 @@ Mixed changesets that contain both ignored and not ignored packages are not allo setup.updateDependency("pkg-c", "pkg-a", "^1.0.0"); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -638,15 +642,15 @@ Mixed changesets that contain both ignored and not ignored packages are not allo undefined ); - expect(releases.length).toEqual(4); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("2.0.0"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].newVersion).toEqual("2.0.0"); - expect(releases[2].name).toEqual("pkg-d"); - expect(releases[2].newVersion).toEqual("1.1.0"); - expect(releases[3].name).toEqual("pkg-c"); - expect(releases[3].newVersion).toEqual("1.1.0"); + expect(individualReleases.length).toEqual(4); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("2.0.0"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].newVersion).toEqual("2.0.0"); + expect(individualReleases[2].name).toEqual("pkg-d"); + expect(individualReleases[2].newVersion).toEqual("1.1.0"); + expect(individualReleases[3].name).toEqual("pkg-c"); + expect(individualReleases[3].newVersion).toEqual("1.1.0"); }); it("should assemble release plan where a fixed constraint causes a dependency to need changing which causes a second fixed group to update 2", () => { setup.addChangeset({ @@ -660,7 +664,7 @@ Mixed changesets that contain both ignored and not ignored packages are not allo setup.updateDependency("pkg-c", "pkg-b", "^1.0.0"); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -673,18 +677,18 @@ Mixed changesets that contain both ignored and not ignored packages are not allo undefined ); - expect(releases.length).toEqual(4); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("2.0.0"); - expect(releases[1].name).toEqual("pkg-d"); - expect(releases[1].newVersion).toEqual("1.1.0"); - expect(releases[2].name).toEqual("pkg-b"); - expect(releases[2].newVersion).toEqual("2.0.0"); - expect(releases[3].name).toEqual("pkg-c"); - expect(releases[3].newVersion).toEqual("1.1.0"); + expect(individualReleases.length).toEqual(4); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("2.0.0"); + expect(individualReleases[1].name).toEqual("pkg-d"); + expect(individualReleases[1].newVersion).toEqual("1.1.0"); + expect(individualReleases[2].name).toEqual("pkg-b"); + expect(individualReleases[2].newVersion).toEqual("2.0.0"); + expect(individualReleases[3].name).toEqual("pkg-c"); + expect(individualReleases[3].newVersion).toEqual("1.1.0"); }); it("should return an empty release array when no changes will occur", () => { - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( [], setup.packages, { @@ -697,7 +701,7 @@ Mixed changesets that contain both ignored and not ignored packages are not allo undefined ); - expect(releases).toEqual([]); + expect(individualReleases).toEqual([]); }); it("should bump peer dependents where the version is updated because of fixed", () => { @@ -708,7 +712,7 @@ Mixed changesets that contain both ignored and not ignored packages are not allo releases: [{ type: "minor", name: "pkg-a" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -718,7 +722,7 @@ Mixed changesets that contain both ignored and not ignored packages are not allo undefined ); - expect(releases).toMatchObject([ + expect(individualReleases).toMatchObject([ { name: "pkg-a", newVersion: "1.1.0", @@ -742,7 +746,7 @@ Mixed changesets that contain both ignored and not ignored packages are not allo releases: [{ name: "pkg-b", type: "major" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -752,9 +756,9 @@ Mixed changesets that contain both ignored and not ignored packages are not allo undefined ); - expect(releases.length).toEqual(2); - expect(releases[0].newVersion).toEqual("2.0.0"); - expect(releases[1].newVersion).toEqual("2.0.0"); + expect(individualReleases.length).toEqual(2); + expect(individualReleases[0].newVersion).toEqual("2.0.0"); + expect(individualReleases[1].newVersion).toEqual("2.0.0"); }); it("should assemble a release plan where new highest version is set by an unreleased package", () => { setup.addChangeset({ @@ -767,7 +771,7 @@ Mixed changesets that contain both ignored and not ignored packages are not allo setup.updatePackage("pkg-c", "2.0.0"); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -777,9 +781,9 @@ Mixed changesets that contain both ignored and not ignored packages are not allo undefined ); - expect(releases.length).toEqual(2); - expect(releases[0].newVersion).toEqual("2.1.0"); - expect(releases[1].newVersion).toEqual("2.1.0"); + expect(individualReleases.length).toEqual(2); + expect(individualReleases[0].newVersion).toEqual("2.1.0"); + expect(individualReleases[1].newVersion).toEqual("2.1.0"); }); it("should assemble release plan where a link causes a dependency to need changing which causes a second link to update", () => { /* @@ -800,7 +804,7 @@ Mixed changesets that contain both ignored and not ignored packages are not allo setup.updateDependency("pkg-c", "pkg-a", "^1.0.0"); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -813,14 +817,14 @@ Mixed changesets that contain both ignored and not ignored packages are not allo undefined ); - expect(releases.length).toEqual(4); - expect(releases[0].newVersion).toEqual("2.0.0"); - expect(releases[1].newVersion).toEqual("2.0.0"); - expect(releases[2].newVersion).toEqual("1.1.0"); - expect(releases[3].newVersion).toEqual("1.1.0"); + expect(individualReleases.length).toEqual(4); + expect(individualReleases[0].newVersion).toEqual("2.0.0"); + expect(individualReleases[1].newVersion).toEqual("2.0.0"); + expect(individualReleases[2].newVersion).toEqual("1.1.0"); + expect(individualReleases[3].newVersion).toEqual("1.1.0"); }); it("should return an empty release array when no changes will occur", () => { - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( [], setup.packages, { @@ -833,7 +837,7 @@ Mixed changesets that contain both ignored and not ignored packages are not allo undefined ); - expect(releases).toEqual([]); + expect(individualReleases).toEqual([]); }); it("should bump peer dependents where the version is updated because of linked", () => { setup.updatePeerDependency("pkg-b", "pkg-a", "1.0.0"); @@ -843,7 +847,7 @@ Mixed changesets that contain both ignored and not ignored packages are not allo releases: [{ type: "minor", name: "pkg-c" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -853,7 +857,7 @@ Mixed changesets that contain both ignored and not ignored packages are not allo undefined ); - expect(releases).toMatchObject([ + expect(individualReleases).toMatchObject([ { name: "pkg-a", newVersion: "1.1.0", @@ -872,7 +876,7 @@ Mixed changesets that contain both ignored and not ignored packages are not allo describe("pre mode", () => { it("should not generate a release for package that has no changesets and is not a dependent of any packages being released when exiting pre mode", () => { - const { releases } = assembleReleasePlan( + const { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -886,9 +890,9 @@ Mixed changesets that contain both ignored and not ignored packages are not allo } ); - expect(releases.length).toEqual(1); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("1.0.1"); + expect(individualReleases.length).toEqual(1); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("1.0.1"); }); it("should bump dev dependents when exiting pre-release mode", () => { @@ -896,7 +900,7 @@ Mixed changesets that contain both ignored and not ignored packages are not allo setup.updatePackage("pkg-b", "1.0.1-next.0"); setup.updateDevDependency("pkg-b", "pkg-a", "1.0.1-next.0"); - const { releases } = assembleReleasePlan( + const { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -913,11 +917,11 @@ Mixed changesets that contain both ignored and not ignored packages are not allo } ); - expect(releases.length).toEqual(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("1.0.1"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].newVersion).toEqual("1.0.1"); + expect(individualReleases.length).toEqual(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("1.0.1"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].newVersion).toEqual("1.0.1"); }); it("should not bump ignored dev dependents when exiting pre-release mode", () => { @@ -925,7 +929,7 @@ Mixed changesets that contain both ignored and not ignored packages are not allo setup.updatePackage("pkg-b", "1.0.1-next.0"); setup.updateDevDependency("pkg-b", "pkg-a", "1.0.1-next.0"); - const { releases } = assembleReleasePlan( + const { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -943,11 +947,11 @@ Mixed changesets that contain both ignored and not ignored packages are not allo } ); - expect(releases.length).toEqual(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("1.0.1"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].newVersion).toEqual("1.0.1-next.0"); + expect(individualReleases.length).toEqual(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("1.0.1"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].newVersion).toEqual("1.0.1-next.0"); }); it("should return a release with the highest bump type within the current release despite of having a higher release among previous prereleases", () => { @@ -973,7 +977,7 @@ Mixed changesets that contain both ignored and not ignored packages are not allo }, ], }); - const { releases } = assembleReleasePlan( + const { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -991,10 +995,10 @@ Mixed changesets that contain both ignored and not ignored packages are not allo } ); - expect(releases.length).toEqual(1); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("2.0.0-next.1"); - expect(releases[0].type).toEqual("minor"); + expect(individualReleases.length).toEqual(1); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("2.0.0-next.1"); + expect(individualReleases[0].type).toEqual("minor"); }); }); @@ -1006,18 +1010,18 @@ Mixed changesets that contain both ignored and not ignored packages are not allo releases: [{ name: "pkg-b", type: "none" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toEqual(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].oldVersion).toEqual("1.0.0"); - expect(releases[1].newVersion).toEqual("1.0.0"); + expect(individualReleases.length).toEqual(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].oldVersion).toEqual("1.0.0"); + expect(individualReleases[1].newVersion).toEqual("1.0.0"); }); it("should assemble release plan without workspace:* dependencies when the dependent has a changeset type of none", () => { setup.updateDependency("pkg-c", "pkg-b", "workspace:*"); @@ -1026,34 +1030,34 @@ Mixed changesets that contain both ignored and not ignored packages are not allo releases: [{ name: "pkg-b", type: "none" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toEqual(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].oldVersion).toEqual("1.0.0"); - expect(releases[1].newVersion).toEqual("1.0.0"); + expect(individualReleases.length).toEqual(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].oldVersion).toEqual("1.0.0"); + expect(individualReleases[1].newVersion).toEqual("1.0.0"); }); it("should assemble release plan with workspace:* dependencies", () => { setup.updateDependency("pkg-b", "pkg-a", "workspace:*"); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toEqual(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].oldVersion).toEqual("1.0.0"); - expect(releases[1].newVersion).toEqual("1.0.1"); + expect(individualReleases.length).toEqual(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].oldVersion).toEqual("1.0.0"); + expect(individualReleases[1].newVersion).toEqual("1.0.1"); }); }); @@ -1061,7 +1065,7 @@ Mixed changesets that contain both ignored and not ignored packages are not allo it("should bump a direct dependent when a dependency package gets bumped", () => { setup.updateDependency("pkg-b", "pkg-a", "^1.0.0"); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -1074,18 +1078,18 @@ Mixed changesets that contain both ignored and not ignored packages are not allo undefined ); - expect(releases.length).toBe(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("1.0.1"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].newVersion).toEqual("1.0.1"); + expect(individualReleases.length).toBe(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("1.0.1"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].newVersion).toEqual("1.0.1"); }); it("should bump a transitive dependent when a dependency package gets bumped", () => { setup.updateDependency("pkg-b", "pkg-a", "^1.0.0"); setup.updateDependency("pkg-c", "pkg-b", "^1.0.0"); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -1098,13 +1102,13 @@ Mixed changesets that contain both ignored and not ignored packages are not allo undefined ); - expect(releases.length).toBe(3); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("1.0.1"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].newVersion).toEqual("1.0.1"); - expect(releases[2].name).toEqual("pkg-c"); - expect(releases[2].newVersion).toEqual("1.0.1"); + expect(individualReleases.length).toBe(3); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("1.0.1"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].newVersion).toEqual("1.0.1"); + expect(individualReleases[2].name).toEqual("pkg-c"); + expect(individualReleases[2].newVersion).toEqual("1.0.1"); }); it("not bump a dependent package when a dependency has `none` changeset", () => { @@ -1114,7 +1118,7 @@ Mixed changesets that contain both ignored and not ignored packages are not allo releases: [{ name: "pkg-c", type: "none" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -1127,18 +1131,18 @@ Mixed changesets that contain both ignored and not ignored packages are not allo undefined ); - expect(releases.length).toBe(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("1.0.1"); - expect(releases[1].name).toEqual("pkg-c"); - expect(releases[1].newVersion).toEqual("1.0.0"); + expect(individualReleases.length).toBe(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("1.0.1"); + expect(individualReleases[1].name).toEqual("pkg-c"); + expect(individualReleases[1].newVersion).toEqual("1.0.0"); }); it("should not bump a dev dependent nor its dependent when a package gets bumped", () => { setup.updateDevDependency("pkg-b", "pkg-a", "^1.0.0"); setup.updateDependency("pkg-c", "pkg-b", "^1.0.0"); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -1151,11 +1155,11 @@ Mixed changesets that contain both ignored and not ignored packages are not allo undefined ); - expect(releases.length).toBe(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("1.0.1"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].newVersion).toEqual("1.0.0"); + expect(individualReleases.length).toBe(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("1.0.1"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].newVersion).toEqual("1.0.0"); }); }); }); @@ -1174,17 +1178,17 @@ describe("version update thoroughness", () => { }); it("should patch a single pinned dependent", () => { - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toEqual(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("1.0.1"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].newVersion).toEqual("1.0.1"); + expect(individualReleases.length).toEqual(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("1.0.1"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].newVersion).toEqual("1.0.1"); }); it("should path a pinned and tilde dependents when minor versioning", () => { setup.addChangeset({ @@ -1192,20 +1196,20 @@ describe("version update thoroughness", () => { releases: [{ name: "pkg-a", type: "minor" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toEqual(3); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("1.1.0"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].newVersion).toEqual("1.0.1"); - expect(releases[2].name).toEqual("pkg-c"); - expect(releases[2].newVersion).toEqual("1.0.1"); + expect(individualReleases.length).toEqual(3); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("1.1.0"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].newVersion).toEqual("1.0.1"); + expect(individualReleases[2].name).toEqual("pkg-c"); + expect(individualReleases[2].newVersion).toEqual("1.0.1"); }); it("should patch pinned, tilde and caret dependents when a major versioning", () => { setup.addChangeset({ @@ -1213,22 +1217,22 @@ describe("version update thoroughness", () => { releases: [{ name: "pkg-a", type: "major" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toEqual(4); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("2.0.0"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].newVersion).toEqual("1.0.1"); - expect(releases[2].name).toEqual("pkg-c"); - expect(releases[2].newVersion).toEqual("1.0.1"); - expect(releases[3].name).toEqual("pkg-d"); - expect(releases[3].newVersion).toEqual("1.0.1"); + expect(individualReleases.length).toEqual(4); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("2.0.0"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].newVersion).toEqual("1.0.1"); + expect(individualReleases[2].name).toEqual("pkg-c"); + expect(individualReleases[2].newVersion).toEqual("1.0.1"); + expect(individualReleases[3].name).toEqual("pkg-d"); + expect(individualReleases[3].newVersion).toEqual("1.0.1"); }); }); @@ -1242,18 +1246,18 @@ describe("bumping peerDeps", () => { it("should patch a pinned peerDep", () => { setup.updatePeerDependency("pkg-b", "pkg-a", "1.0.0"); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toBe(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("1.0.1"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].newVersion).toEqual("1.0.1"); + expect(individualReleases.length).toBe(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("1.0.1"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].newVersion).toEqual("1.0.1"); }); it("should not bump the dependent when bumping a tilde peerDep by none", () => { setup.updatePeerDependency("pkg-b", "pkg-a", "~1.0.0"); @@ -1263,30 +1267,30 @@ describe("bumping peerDeps", () => { releases: [{ name: "pkg-a", type: "none" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toBe(1); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("1.0.0"); + expect(individualReleases.length).toBe(1); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("1.0.0"); }); it("should not bump the dependent when bumping a tilde peerDep by a patch", () => { setup.updatePeerDependency("pkg-b", "pkg-a", "~1.0.0"); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toBe(1); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("1.0.1"); + expect(individualReleases.length).toBe(1); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("1.0.1"); }); it("should major bump dependent when bumping a tilde peerDep by minor", () => { setup.updatePeerDependency("pkg-b", "pkg-a", "~1.0.0"); @@ -1295,18 +1299,18 @@ describe("bumping peerDeps", () => { releases: [{ name: "pkg-a", type: "minor" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toBe(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("1.1.0"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].newVersion).toEqual("2.0.0"); + expect(individualReleases.length).toBe(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("1.1.0"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].newVersion).toEqual("2.0.0"); }); it("should major bump dependent when bumping a tilde peerDep by major", () => { setup.updatePeerDependency("pkg-b", "pkg-a", "~1.0.0"); @@ -1315,18 +1319,18 @@ describe("bumping peerDeps", () => { releases: [{ name: "pkg-a", type: "major" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toBe(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("2.0.0"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].newVersion).toEqual("2.0.0"); + expect(individualReleases.length).toBe(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("2.0.0"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].newVersion).toEqual("2.0.0"); }); it("should not bump dependent when bumping caret peerDep by none", () => { setup.updatePeerDependency("pkg-b", "pkg-a", "^1.0.0"); @@ -1336,30 +1340,30 @@ describe("bumping peerDeps", () => { releases: [{ name: "pkg-a", type: "none" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toBe(1); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("1.0.0"); + expect(individualReleases.length).toBe(1); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("1.0.0"); }); it("should not bump dependent when bumping caret peerDep by patch", () => { setup.updatePeerDependency("pkg-b", "pkg-a", "^1.0.0"); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toBe(1); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("1.0.1"); + expect(individualReleases.length).toBe(1); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("1.0.1"); }); it("should major bump dependent when bumping caret peerDep by minor", () => { setup.updatePeerDependency("pkg-b", "pkg-a", "^1.0.0"); @@ -1368,18 +1372,18 @@ describe("bumping peerDeps", () => { releases: [{ name: "pkg-a", type: "minor" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toBe(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("1.1.0"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].newVersion).toEqual("2.0.0"); + expect(individualReleases.length).toBe(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("1.1.0"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].newVersion).toEqual("2.0.0"); }); it("should major bump dependent when bumping caret peerDep by major", () => { setup.updatePeerDependency("pkg-b", "pkg-a", "^1.0.0"); @@ -1388,18 +1392,18 @@ describe("bumping peerDeps", () => { releases: [{ name: "pkg-a", type: "major" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toBe(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("2.0.0"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].newVersion).toEqual("2.0.0"); + expect(individualReleases.length).toBe(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("2.0.0"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].newVersion).toEqual("2.0.0"); }); it("should patch bump transitive dep that is only affected by peerDep bump", () => { setup.updatePeerDependency("pkg-b", "pkg-a", "^1.0.0"); @@ -1410,23 +1414,23 @@ describe("bumping peerDeps", () => { releases: [{ name: "pkg-a", type: "minor" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, defaultConfig, undefined ); - expect(releases.length).toBe(3); - expect(releases[0]).toMatchObject({ + expect(individualReleases.length).toBe(3); + expect(individualReleases[0]).toMatchObject({ name: "pkg-a", newVersion: "1.1.0", }); - expect(releases[1]).toMatchObject({ + expect(individualReleases[1]).toMatchObject({ name: "pkg-b", newVersion: "2.0.0", }); - expect(releases[2]).toMatchObject({ + expect(individualReleases[2]).toMatchObject({ name: "pkg-c", newVersion: "1.0.1", }); @@ -1439,7 +1443,7 @@ describe("bumping peerDeps", () => { id: "anyway-the-windblows", releases: [{ name: "pkg-a", type: "minor" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -1451,9 +1455,9 @@ describe("bumping peerDeps", () => { }, undefined ); - expect(releases.length).toBe(1); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("1.1.0"); + expect(individualReleases.length).toBe(1); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("1.1.0"); }); it("should major bump dependent when leaving range", () => { @@ -1463,7 +1467,7 @@ describe("bumping peerDeps", () => { releases: [{ name: "pkg-a", type: "minor" }], }); - let { releases } = assembleReleasePlan( + let { individualReleases } = assembleReleasePlan( setup.changesets, setup.packages, { @@ -1476,11 +1480,11 @@ describe("bumping peerDeps", () => { undefined ); - expect(releases.length).toBe(2); - expect(releases[0].name).toEqual("pkg-a"); - expect(releases[0].newVersion).toEqual("1.1.0"); - expect(releases[1].name).toEqual("pkg-b"); - expect(releases[1].newVersion).toEqual("2.0.0"); + expect(individualReleases.length).toBe(2); + expect(individualReleases[0].name).toEqual("pkg-a"); + expect(individualReleases[0].newVersion).toEqual("1.1.0"); + expect(individualReleases[1].name).toEqual("pkg-b"); + expect(individualReleases[1].newVersion).toEqual("2.0.0"); }); }); }); diff --git a/packages/assemble-release-plan/src/index.ts b/packages/assemble-release-plan/src/index.ts index 3ffb6fa77..f88c34c79 100644 --- a/packages/assemble-release-plan/src/index.ts +++ b/packages/assemble-release-plan/src/index.ts @@ -4,10 +4,14 @@ import { NewChangeset, PreState, PackageGroup, -} from "@changesets/types"; + Fixed, + SingleChangelogPackageGroup, +} from "@abizzle/changesets-types"; import determineDependents from "./determine-dependents"; import flattenReleases from "./flatten-releases"; -import matchFixedConstraint from "./match-fixed-constraint"; +import matchFixedConstraint, { + isSingleChangelogFixedPackageGroup, +} from "./match-fixed-constraint"; import applyLinks from "./apply-links"; import { incrementVersion } from "./increment"; import * as semver from "semver"; @@ -242,19 +246,61 @@ function assembleReleasePlan( return { changesets: relevantChangesets, - releases: [...releases.values()].map((incompleteRelease) => { - return { - ...incompleteRelease, - newVersion: snapshotSuffix - ? getSnapshotVersion( - incompleteRelease, - preInfo, - refinedConfig.snapshot.useCalculatedVersion, - snapshotSuffix - ) - : getNewVersion(incompleteRelease, preInfo), - }; - }), + individualReleases: [...releases.values()] + .filter( + (r) => !packageIsInSingleChangelogFixedGroup(config.fixed, r.name) + ) + .map((incompleteRelease) => { + return { + ...incompleteRelease, + newVersion: snapshotSuffix + ? getSnapshotVersion( + incompleteRelease, + preInfo, + refinedConfig.snapshot.useCalculatedVersion, + snapshotSuffix + ) + : getNewVersion(incompleteRelease, preInfo), + }; + }), + groupedReleases: [...releases.values()].reduce((acc, cur) => { + const group = packageIsInSingleChangelogFixedGroup( + config.fixed, + cur.name + ); + if (group) { + const existingEntry = acc.find((entry) => entry.relativeChangelogPath); + if (existingEntry) { + existingEntry.projects.push({ + name: cur.name, + oldVersion: cur.oldVersion, + type: cur.type, + }); + } else { + acc.push({ + changesets: cur.changesets, + displayName: group.name, + newVersion: snapshotSuffix + ? getSnapshotVersion( + cur, + preInfo, + refinedConfig.snapshot.useCalculatedVersion, + snapshotSuffix + ) + : getNewVersion(cur, preInfo), + projects: [ + { + name: cur.name, + oldVersion: cur.oldVersion, + type: cur.type, + }, + ], + relativeChangelogPath: group.changelog, + }); + } + } + return acc; + }, [] as ReleasePlan["groupedReleases"]), preState: preInfo?.state, }; } @@ -349,8 +395,11 @@ function getPreInfo( ); } for (let fixedGroup of config.fixed) { - let highestPreVersion = getHighestPreVersion(fixedGroup, packagesByName); - for (let fixedPackage of fixedGroup) { + const packageGroup = isSingleChangelogFixedPackageGroup(fixedGroup) + ? fixedGroup.group + : fixedGroup; + let highestPreVersion = getHighestPreVersion(packageGroup, packagesByName); + for (let fixedPackage of packageGroup) { preVersions.set(fixedPackage, highestPreVersion); } } @@ -367,4 +416,12 @@ function getPreInfo( }; } +function packageIsInSingleChangelogFixedGroup(fixed: Fixed, pkgName: string) { + return fixed.find( + (entry): entry is SingleChangelogPackageGroup => + !Array.isArray(entry) && + (entry as SingleChangelogPackageGroup).group.includes(pkgName) + ); +} + export default assembleReleasePlan; diff --git a/packages/assemble-release-plan/src/match-fixed-constraint.ts b/packages/assemble-release-plan/src/match-fixed-constraint.ts index 40ea445b4..faa6f7562 100644 --- a/packages/assemble-release-plan/src/match-fixed-constraint.ts +++ b/packages/assemble-release-plan/src/match-fixed-constraint.ts @@ -1,4 +1,4 @@ -import { Config } from "@changesets/types"; +import { Config, SingleChangelogPackageGroup } from "@abizzle/changesets-types"; import { Package } from "@manypkg/get-packages"; import { InternalRelease } from "./types"; import { getCurrentHighestVersion, getHighestReleaseType } from "./utils"; @@ -11,21 +11,21 @@ export default function matchFixedConstraint( let updated = false; for (let fixedPackages of config.fixed) { + const packageGroup = isSingleChangelogFixedPackageGroup(fixedPackages) + ? fixedPackages.group + : fixedPackages; let releasingFixedPackages = [...releases.values()].filter( (release) => - fixedPackages.includes(release.name) && release.type !== "none" + packageGroup.includes(release.name) && release.type !== "none" ); if (releasingFixedPackages.length === 0) continue; let highestReleaseType = getHighestReleaseType(releasingFixedPackages); - let highestVersion = getCurrentHighestVersion( - fixedPackages, - packagesByName - ); + let highestVersion = getCurrentHighestVersion(packageGroup, packagesByName); // Finally, we update the packages so all of them are on the highest version - for (let pkgName of fixedPackages) { + for (let pkgName of packageGroup) { if (config.ignore.includes(pkgName)) { continue; } @@ -55,3 +55,16 @@ export default function matchFixedConstraint( return updated; } + +export const isSingleChangelogFixedPackageGroup = ( + pkgGroup: unknown +): pkgGroup is SingleChangelogPackageGroup => { + return Boolean( + pkgGroup && + Array.isArray((pkgGroup as SingleChangelogPackageGroup).group) && + ((pkgGroup as SingleChangelogPackageGroup).group as unknown[]).every( + (pkgName) => typeof pkgName === "string" + ) && + typeof (pkgGroup as SingleChangelogPackageGroup).changelog === "string" + ); +}; diff --git a/packages/assemble-release-plan/src/test-utils.ts b/packages/assemble-release-plan/src/test-utils.ts index 2bd16710e..2dd734dbf 100644 --- a/packages/assemble-release-plan/src/test-utils.ts +++ b/packages/assemble-release-plan/src/test-utils.ts @@ -1,4 +1,4 @@ -import { NewChangeset, Release, VersionType } from "@changesets/types"; +import { NewChangeset, Release, VersionType } from "@abizzle/changesets-types"; import { Package, Packages } from "@manypkg/get-packages"; function getPackage({ diff --git a/packages/assemble-release-plan/src/types.ts b/packages/assemble-release-plan/src/types.ts index 83826c2af..79a764c0a 100644 --- a/packages/assemble-release-plan/src/types.ts +++ b/packages/assemble-release-plan/src/types.ts @@ -1,4 +1,4 @@ -import { VersionType, PreState } from "@changesets/types"; +import { VersionType, PreState } from "@abizzle/changesets-types"; export type InternalRelease = { name: string; diff --git a/packages/assemble-release-plan/src/utils.ts b/packages/assemble-release-plan/src/utils.ts index be300ff9b..7cee0fd3a 100644 --- a/packages/assemble-release-plan/src/utils.ts +++ b/packages/assemble-release-plan/src/utils.ts @@ -1,4 +1,4 @@ -import { PackageGroup, VersionType } from "@changesets/types"; +import { PackageGroup, VersionType } from "@abizzle/changesets-types"; import { Package } from "@manypkg/get-packages"; import semver from "semver"; import { InternalRelease } from "./types"; diff --git a/packages/changelog-git/CHANGELOG.md b/packages/changelog-git/CHANGELOG.md index 9312490a3..ce8011afe 100644 --- a/packages/changelog-git/CHANGELOG.md +++ b/packages/changelog-git/CHANGELOG.md @@ -1,4 +1,33 @@ -# @changesets/changelog-git +# @abizzle/changesets-changelog-git + +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies [c5a83f9] + - @abizzle/changesets-types@6.0.0-next.3 + +## 0.2.0-next.0 + +### Minor Changes + +- 850b82e: Add support for single changelog fixed package groups. + + Optionally supply an object as a fixed package group entry like so: + + ```json + { + "fixed": [ + { + "group": ["@changesets/button", "@changesets/theme"], + "changelog": "CHANGELOG.md", + "name": "UI Packages" + } + ] + } + ``` + + This will create/update a single changelog at `/CHANGELOG.md` with changelog entries for `@changesets/button` and `@changesets/theme` under the title "UI Packages". ## 0.1.14 diff --git a/packages/changelog-git/package.json b/packages/changelog-git/package.json index 921fdbf30..983fd53e3 100644 --- a/packages/changelog-git/package.json +++ b/packages/changelog-git/package.json @@ -1,12 +1,12 @@ { - "name": "@changesets/changelog-git", - "version": "0.1.14", + "name": "@abizzle/changesets-changelog-git", + "version": "0.2.0-next.1", "description": "A changelog entry generator for git that writes hashes", - "main": "dist/changelog-git.cjs.js", - "module": "dist/changelog-git.esm.js", + "main": "dist/changesets-changelog-git.cjs.js", + "module": "dist/changesets-changelog-git.esm.js", "license": "MIT", "repository": "https://github.com/changesets/changesets/tree/main/packages/changelog-git", "dependencies": { - "@changesets/types": "^5.2.1" + "@abizzle/changesets-types": "^6.0.0-next.3" } } diff --git a/packages/changelog-git/src/index.ts b/packages/changelog-git/src/index.ts index 9d6528ff8..db69e42a9 100644 --- a/packages/changelog-git/src/index.ts +++ b/packages/changelog-git/src/index.ts @@ -3,7 +3,7 @@ import { VersionType, ChangelogFunctions, ModCompWithPackage, -} from "@changesets/types"; +} from "@abizzle/changesets-types"; const getReleaseLine = async ( changeset: NewChangesetWithCommit, @@ -13,8 +13,10 @@ const getReleaseLine = async ( .split("\n") .map((l) => l.trimRight()); - let returnVal = `- ${ - changeset.commit ? `${changeset.commit}: ` : "" + let returnVal = `- ${changeset.commit ? `${changeset.commit}: ` : ""}${ + changeset.groupedChangelog + ? `**(${changeset.releases.map(({ name }) => name).join(", ")})** ` + : "" }${firstLine}`; if (futureLines.length > 0) { diff --git a/packages/changelog-github/CHANGELOG.md b/packages/changelog-github/CHANGELOG.md index de47d343b..93444b0ef 100644 --- a/packages/changelog-github/CHANGELOG.md +++ b/packages/changelog-github/CHANGELOG.md @@ -1,4 +1,33 @@ -# @changesets/changelog-github +# @abizzle/changesets-changelog-github + +## 0.5.0-next.1 + +### Patch Changes + +- Updated dependencies [c5a83f9] + - @abizzle/changesets-types@6.0.0-next.3 + +## 0.5.0-next.0 + +### Minor Changes + +- 850b82e: Add support for single changelog fixed package groups. + + Optionally supply an object as a fixed package group entry like so: + + ```json + { + "fixed": [ + { + "group": ["@changesets/button", "@changesets/theme"], + "changelog": "CHANGELOG.md", + "name": "UI Packages" + } + ] + } + ``` + + This will create/update a single changelog at `/CHANGELOG.md` with changelog entries for `@changesets/button` and `@changesets/theme` under the title "UI Packages". ## 0.4.8 diff --git a/packages/changelog-github/package.json b/packages/changelog-github/package.json index 32afdea80..76c286f6d 100644 --- a/packages/changelog-github/package.json +++ b/packages/changelog-github/package.json @@ -1,14 +1,14 @@ { - "name": "@changesets/changelog-github", - "version": "0.4.8", + "name": "@abizzle/changesets-changelog-github", + "version": "0.5.0-next.1", "description": "A changelog entry generator for GitHub that links to commits, PRs and users", - "main": "dist/changelog-github.cjs.js", - "module": "dist/changelog-github.esm.js", + "main": "dist/changesets-changelog-github.cjs.js", + "module": "dist/changesets-changelog-github.esm.js", "license": "MIT", "repository": "https://github.com/changesets/changesets/tree/main/packages/changelog-github", "dependencies": { + "@abizzle/changesets-types": "^6.0.0-next.3", "@changesets/get-github-info": "^0.5.2", - "@changesets/types": "^5.2.1", "dotenv": "^8.1.0" }, "devDependencies": { diff --git a/packages/changelog-github/src/index.ts b/packages/changelog-github/src/index.ts index 6b9092e5a..67c707c00 100644 --- a/packages/changelog-github/src/index.ts +++ b/packages/changelog-github/src/index.ts @@ -1,4 +1,4 @@ -import { ChangelogFunctions } from "@changesets/types"; +import { ChangelogFunctions } from "@abizzle/changesets-types"; // @ts-ignore import { config } from "dotenv"; import { getInfo, getInfoFromPullRequest } from "@changesets/get-github-info"; @@ -13,7 +13,7 @@ const changelogFunctions: ChangelogFunctions = { ) => { if (!options.repo) { throw new Error( - 'Please provide a repo to this changelog generator like this:\n"changelog": ["@changesets/changelog-github", { "repo": "org/repo" }]' + 'Please provide a repo to this changelog generator like this:\n"changelog": ["@abizzle/changesets-changelog-github", { "repo": "org/repo" }]' ); } if (dependenciesUpdated.length === 0) return ""; @@ -43,7 +43,7 @@ const changelogFunctions: ChangelogFunctions = { getReleaseLine: async (changeset, type, options) => { if (!options || !options.repo) { throw new Error( - 'Please provide a repo to this changelog generator like this:\n"changelog": ["@changesets/changelog-github", { "repo": "org/repo" }]' + 'Please provide a repo to this changelog generator like this:\n"changelog": ["@abizzle/changesets-changelog-github", { "repo": "org/repo" }]' ); } @@ -112,6 +112,9 @@ const changelogFunctions: ChangelogFunctions = { const prefix = [ links.pull === null ? "" : ` ${links.pull}`, links.commit === null ? "" : ` ${links.commit}`, + changeset.groupedChangelog + ? ` **(${changeset.releases.map(({ name }) => name).join(", ")})**` + : "", users === null ? "" : ` Thanks ${users}!`, ].join(""); diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 4b9c12ade..a93c8c9cd 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,4 +1,50 @@ -# @changesets/cli +# @abizzle/changesets-cli + +## 2.27.0-next.3 + +### Patch Changes + +- Updated dependencies [c5a83f9] + - @abizzle/changesets-types@6.0.0-next.3 + - @abizzle/changesets-apply-release-plan@7.0.0-next.3 + - @abizzle/changesets-assemble-release-plan@6.0.0-next.3 + - @abizzle/changesets-changelog-git@0.2.0-next.1 + - @abizzle/changesets-config@2.4.0-next.1 + - @abizzle/changesets-get-release-plan@3.0.17-next.3 + +## 2.27.0-next.2 + +### Patch Changes + +- Fixes dist files +- Updated dependencies + - @abizzle/changesets-assemble-release-plan@6.0.0-next.2 + - @abizzle/changesets-apply-release-plan@7.0.0-next.2 + - @abizzle/changesets-get-release-plan@3.0.17-next.2 + +## 2.27.0-next.1 + +### Minor Changes + +- efd8c06: Fixes single changelog fixed groups. + +### Patch Changes + +- Updated dependencies [efd8c06] + - @abizzle/changesets-assemble-release-plan@6.0.0-next.1 + - @abizzle/changesets-apply-release-plan@7.0.0-next.1 + - @abizzle/changesets-get-release-plan@3.0.17-next.1 + +## 2.26.1-next.0 + +### Patch Changes + +- Updated dependencies [850b82e] + - @abizzle/changesets-assemble-release-plan@5.3.0-next.0 + - @abizzle/changesets-apply-release-plan@6.2.0-next.0 + - @abizzle/changesets-changelog-git@0.2.0-next.0 + - @abizzle/changesets-config@2.4.0-next.0 + - @abizzle/changesets-get-release-plan@3.0.17-next.0 ## 2.26.0 diff --git a/packages/cli/changelog/package.json b/packages/cli/changelog/package.json index 6fd608aae..81a26b8d5 100644 --- a/packages/cli/changelog/package.json +++ b/packages/cli/changelog/package.json @@ -1,6 +1,6 @@ { - "main": "dist/cli.cjs.js", - "module": "dist/cli.esm.js", + "main": "dist/changesets-cli.cjs.js", + "module": "dist/changesets-cli.esm.js", "preconstruct": { "source": "../src/changelog" } diff --git a/packages/cli/commit/package.json b/packages/cli/commit/package.json index c028d12de..21bf5d28f 100644 --- a/packages/cli/commit/package.json +++ b/packages/cli/commit/package.json @@ -1,6 +1,6 @@ { - "main": "dist/cli.cjs.js", - "module": "dist/cli.esm.js", + "main": "dist/changesets-cli.cjs.js", + "module": "dist/changesets-cli.esm.js", "preconstruct": { "source": "../src/commit" } diff --git a/packages/cli/package.json b/packages/cli/package.json index 0912d0f8f..fded89c99 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { - "name": "@changesets/cli", - "version": "2.26.0", + "name": "@abizzle/changesets-cli", + "version": "2.27.0-next.3", "description": "Organise your package versioning and publishing to make both contributors and maintainers happy", "bin": { "changeset": "bin.js" @@ -13,8 +13,8 @@ "changelog", "commit" ], - "main": "dist/cli.cjs.js", - "module": "dist/cli.esm.js", + "main": "dist/changesets-cli.cjs.js", + "module": "dist/changesets-cli.esm.js", "author": "Changesets Contributors", "contributors": [ "Ben Conolly", @@ -30,19 +30,19 @@ }, "license": "MIT", "dependencies": { + "@abizzle/changesets-apply-release-plan": "^7.0.0-next.3", + "@abizzle/changesets-assemble-release-plan": "^6.0.0-next.3", + "@abizzle/changesets-changelog-git": "^0.2.0-next.1", + "@abizzle/changesets-config": "^2.4.0-next.1", + "@abizzle/changesets-get-release-plan": "^3.0.17-next.3", + "@abizzle/changesets-types": "^6.0.0-next.3", "@babel/runtime": "^7.20.1", - "@changesets/apply-release-plan": "^6.1.3", - "@changesets/assemble-release-plan": "^5.2.3", - "@changesets/changelog-git": "^0.1.14", - "@changesets/config": "^2.3.0", "@changesets/errors": "^0.1.4", "@changesets/get-dependents-graph": "^1.3.5", - "@changesets/get-release-plan": "^3.0.16", "@changesets/git": "^2.0.0", "@changesets/logger": "^0.0.5", "@changesets/pre": "^1.0.14", "@changesets/read": "^0.5.9", - "@changesets/types": "^5.2.1", "@changesets/write": "^0.2.3", "@manypkg/get-packages": "^1.1.3", "@types/is-ci": "^3.0.0", diff --git a/packages/cli/src/changelog.ts b/packages/cli/src/changelog.ts index 0a80c80ed..54feb4179 100644 --- a/packages/cli/src/changelog.ts +++ b/packages/cli/src/changelog.ts @@ -1 +1 @@ -export { default } from "@changesets/changelog-git"; +export { default } from "@abizzle/changesets-changelog-git"; diff --git a/packages/cli/src/commands/add/__tests__/add.ts b/packages/cli/src/commands/add/__tests__/add.ts index 25a87422d..d081929dc 100644 --- a/packages/cli/src/commands/add/__tests__/add.ts +++ b/packages/cli/src/commands/add/__tests__/add.ts @@ -1,7 +1,7 @@ import path from "path"; import stripAnsi from "strip-ansi"; import * as git from "@changesets/git"; -import { defaultConfig } from "@changesets/config"; +import { defaultConfig } from "@abizzle/changesets-config"; import { silenceLogsInBlock, testdir } from "@changesets/test-utils"; import writeChangeset from "@changesets/write"; diff --git a/packages/cli/src/commands/add/createChangeset.ts b/packages/cli/src/commands/add/createChangeset.ts index c6bb0bfd9..6ef811d03 100644 --- a/packages/cli/src/commands/add/createChangeset.ts +++ b/packages/cli/src/commands/add/createChangeset.ts @@ -4,7 +4,7 @@ import semver from "semver"; import * as cli from "../../utils/cli-utilities"; import { error, log } from "@changesets/logger"; -import { Release, PackageJSON } from "@changesets/types"; +import { Release, PackageJSON } from "@abizzle/changesets-types"; import { Package } from "@manypkg/get-packages"; import { ExitError } from "@changesets/errors"; diff --git a/packages/cli/src/commands/add/index.ts b/packages/cli/src/commands/add/index.ts index 680629257..3d7d1c459 100644 --- a/packages/cli/src/commands/add/index.ts +++ b/packages/cli/src/commands/add/index.ts @@ -5,7 +5,7 @@ import { spawn } from "child_process"; import * as cli from "../../utils/cli-utilities"; import * as git from "@changesets/git"; import { info, log, warn } from "@changesets/logger"; -import { Config } from "@changesets/types"; +import { Config } from "@abizzle/changesets-types"; import { getPackages } from "@manypkg/get-packages"; import writeChangeset from "@changesets/write"; diff --git a/packages/cli/src/commands/add/isListablePackage.ts b/packages/cli/src/commands/add/isListablePackage.ts index 9b11b1fdf..bcdd03964 100644 --- a/packages/cli/src/commands/add/isListablePackage.ts +++ b/packages/cli/src/commands/add/isListablePackage.ts @@ -1,5 +1,5 @@ -import { Config } from "@changesets/types"; -import { PackageJSON } from "@changesets/types"; +import { Config } from "@abizzle/changesets-types"; +import { PackageJSON } from "@abizzle/changesets-types"; export function isListablePackage(config: Config, packageJson: PackageJSON) { const packageIgnoredInConfig = config.ignore.includes(packageJson.name); diff --git a/packages/cli/src/commands/add/messages.ts b/packages/cli/src/commands/add/messages.ts index 3ebd582b4..976245f08 100644 --- a/packages/cli/src/commands/add/messages.ts +++ b/packages/cli/src/commands/add/messages.ts @@ -1,7 +1,7 @@ import chalk from "chalk"; import outdent from "outdent"; import { log } from "@changesets/logger"; -import { Release, VersionType } from "@changesets/types"; +import { Release, VersionType } from "@abizzle/changesets-types"; export default function printConfirmationMessage( changeset: { diff --git a/packages/cli/src/commands/init/__tests__/command.ts b/packages/cli/src/commands/init/__tests__/command.ts index 277c09cbb..4b77b2800 100644 --- a/packages/cli/src/commands/init/__tests__/command.ts +++ b/packages/cli/src/commands/init/__tests__/command.ts @@ -1,6 +1,6 @@ import fs from "fs-extra"; import path from "path"; -import { defaultWrittenConfig } from "@changesets/config"; +import { defaultWrittenConfig } from "@abizzle/changesets-config"; import { silenceLogsInBlock, testdir } from "@changesets/test-utils"; import initializeCommand from ".."; diff --git a/packages/cli/src/commands/init/index.ts b/packages/cli/src/commands/init/index.ts index b29e61134..a9be8973d 100644 --- a/packages/cli/src/commands/init/index.ts +++ b/packages/cli/src/commands/init/index.ts @@ -2,10 +2,12 @@ import path from "path"; import fs from "fs-extra"; import chalk from "chalk"; -import { defaultWrittenConfig } from "@changesets/config"; +import { defaultWrittenConfig } from "@abizzle/changesets-config"; import { info, log, warn, error } from "@changesets/logger"; -const pkgPath = path.dirname(require.resolve("@changesets/cli/package.json")); +const pkgPath = path.dirname( + require.resolve("@abizzle/changesets-cli/package.json") +); // Modify base branch to "main" without changing defaultWrittenConfig since it also serves as a fallback // for config files that don't specify a base branch. Changing that to main would be a breaking change. diff --git a/packages/cli/src/commands/publish/__tests__/index.test.ts b/packages/cli/src/commands/publish/__tests__/index.test.ts index 0e32f9a01..03b326ef0 100644 --- a/packages/cli/src/commands/publish/__tests__/index.test.ts +++ b/packages/cli/src/commands/publish/__tests__/index.test.ts @@ -1,7 +1,7 @@ import publishCommand from "../index"; -import { defaultConfig } from "@changesets/config"; +import { defaultConfig } from "@abizzle/changesets-config"; import * as path from "path"; -import { Config } from "@changesets/types"; +import { Config } from "@abizzle/changesets-types"; import { silenceLogsInBlock, testdir } from "@changesets/test-utils"; let changelogPath = path.resolve(__dirname, "../../changelog"); diff --git a/packages/cli/src/commands/publish/__tests__/releaseCommand.test.ts b/packages/cli/src/commands/publish/__tests__/releaseCommand.test.ts index 24f57b768..36e07c11b 100644 --- a/packages/cli/src/commands/publish/__tests__/releaseCommand.test.ts +++ b/packages/cli/src/commands/publish/__tests__/releaseCommand.test.ts @@ -1,6 +1,6 @@ import publishPackages from "../publishPackages"; import * as git from "@changesets/git"; -import { defaultConfig } from "@changesets/config"; +import { defaultConfig } from "@abizzle/changesets-config"; import { silenceLogsInBlock, testdir } from "@changesets/test-utils"; import runRelease from ".."; diff --git a/packages/cli/src/commands/publish/index.ts b/packages/cli/src/commands/publish/index.ts index d57f6edf9..86062a374 100644 --- a/packages/cli/src/commands/publish/index.ts +++ b/packages/cli/src/commands/publish/index.ts @@ -3,7 +3,7 @@ import { ExitError } from "@changesets/errors"; import { error, log, success, warn } from "@changesets/logger"; import * as git from "@changesets/git"; import { readPreState } from "@changesets/pre"; -import { Config, PreState } from "@changesets/types"; +import { Config, PreState } from "@abizzle/changesets-types"; import { getPackages } from "@manypkg/get-packages"; import chalk from "chalk"; import { getUntaggedPrivatePackages } from "./getUntaggedPrivatePackages"; diff --git a/packages/cli/src/commands/publish/npm-utils.ts b/packages/cli/src/commands/publish/npm-utils.ts index 4b78d93d2..eae3278da 100644 --- a/packages/cli/src/commands/publish/npm-utils.ts +++ b/packages/cli/src/commands/publish/npm-utils.ts @@ -1,6 +1,6 @@ import { ExitError } from "@changesets/errors"; import { error, info, warn } from "@changesets/logger"; -import { PackageJSON } from "@changesets/types"; +import { PackageJSON } from "@abizzle/changesets-types"; import pLimit from "p-limit"; import preferredPM from "preferred-pm"; import chalk from "chalk"; diff --git a/packages/cli/src/commands/publish/publishPackages.ts b/packages/cli/src/commands/publish/publishPackages.ts index 62b6d8a31..af523a23d 100644 --- a/packages/cli/src/commands/publish/publishPackages.ts +++ b/packages/cli/src/commands/publish/publishPackages.ts @@ -1,10 +1,10 @@ import { join } from "path"; import semver from "semver"; import chalk from "chalk"; -import { AccessType } from "@changesets/types"; +import { AccessType } from "@abizzle/changesets-types"; import { Package } from "@manypkg/get-packages"; import { info, warn } from "@changesets/logger"; -import { PreState } from "@changesets/types"; +import { PreState } from "@abizzle/changesets-types"; import * as npmUtils from "./npm-utils"; import { TwoFactorState } from "../../utils/types"; import isCI from "is-ci"; diff --git a/packages/cli/src/commands/status/__tests__/status.ts b/packages/cli/src/commands/status/__tests__/status.ts index c7770b7c3..29fc4464e 100644 --- a/packages/cli/src/commands/status/__tests__/status.ts +++ b/packages/cli/src/commands/status/__tests__/status.ts @@ -1,7 +1,7 @@ -import { defaultConfig } from "@changesets/config"; +import { defaultConfig } from "@abizzle/changesets-config"; import * as git from "@changesets/git"; import { gitdir, silenceLogsInBlock } from "@changesets/test-utils"; -import { ReleasePlan } from "@changesets/types"; +import { ReleasePlan } from "@abizzle/changesets-types"; import writeChangeset from "@changesets/write"; import fs from "fs-extra"; import path from "path"; @@ -28,7 +28,11 @@ function replaceHumanIds(releaseObj: ReleasePlan | undefined) { id: replacedId, }; }), - releases: releaseObj.releases.map((release) => ({ + individualReleases: releaseObj.individualReleases.map((release) => ({ + ...release, + changesets: release.changesets.map((id) => changesetNames.get(id) || id), + })), + groupedReleases: releaseObj.groupedReleases.map((release) => ({ ...release, changesets: release.changesets.map((id) => changesetNames.get(id) || id), })), @@ -72,34 +76,31 @@ describe("status", () => { await git.commit("updated a", cwd); const releaseObj = await status(cwd, { since: "main" }, defaultConfig); - expect(replaceHumanIds(releaseObj)).toMatchInlineSnapshot(` - { - "changesets": [ - { - "id": "~changeset-1~", - "releases": [ - { - "name": "pkg-a", - "type": "minor", - }, - ], - "summary": "This is a summary", - }, - ], - "preState": undefined, - "releases": [ - { - "changesets": [ - "~changeset-1~", - ], - "name": "pkg-a", - "newVersion": "1.1.0", - "oldVersion": "1.0.0", - "type": "minor", - }, - ], - } - `); + expect(replaceHumanIds(releaseObj)).toStrictEqual({ + changesets: [ + { + id: "~changeset-1~", + releases: [ + { + name: "pkg-a", + type: "minor", + }, + ], + summary: "This is a summary", + }, + ], + preState: undefined, + groupedReleases: [], + individualReleases: [ + { + changesets: ["~changeset-1~"], + name: "pkg-a", + newVersion: "1.1.0", + oldVersion: "1.0.0", + type: "minor", + }, + ], + }); }); it("should exit early with a non-zero error code when there are changed packages but no changesets", async () => { @@ -156,7 +157,8 @@ describe("status", () => { expect(process.exit).not.toHaveBeenCalled(); expect(releaseObj).toEqual({ changesets: [], - releases: [], + groupedReleases: [], + individualReleases: [], preState: undefined, }); }); @@ -257,7 +259,8 @@ describe("status", () => { "summary": "This is a summary", }, ], - "releases": [ + "groupedReleases": [], + "individualReleases": [ { "changesets": [ "~changeset-1~", @@ -307,7 +310,8 @@ describe("status", () => { expect(process.exit).not.toHaveBeenCalled(); expect(releaseObj).toEqual({ changesets: [], - releases: [], + groupedReleases: [], + individualReleases: [], preState: undefined, }); }); @@ -383,33 +387,30 @@ describe("status", () => { { since: "main" }, { ...defaultConfig, changedFilePatterns: ["src/**"] } ); - expect(replaceHumanIds(releaseObj)).toMatchInlineSnapshot(` - { - "changesets": [ - { - "id": "~changeset-1~", - "releases": [ - { - "name": "pkg-a", - "type": "minor", - }, - ], - "summary": "This is a summary", - }, - ], - "preState": undefined, - "releases": [ - { - "changesets": [ - "~changeset-1~", - ], - "name": "pkg-a", - "newVersion": "1.1.0", - "oldVersion": "1.0.0", - "type": "minor", - }, - ], - } - `); + expect(replaceHumanIds(releaseObj)).toStrictEqual({ + changesets: [ + { + id: "~changeset-1~", + releases: [ + { + name: "pkg-a", + type: "minor", + }, + ], + summary: "This is a summary", + }, + ], + preState: undefined, + groupedReleases: [], + individualReleases: [ + { + changesets: ["~changeset-1~"], + name: "pkg-a", + newVersion: "1.1.0", + oldVersion: "1.0.0", + type: "minor", + }, + ], + }); }); }); diff --git a/packages/cli/src/commands/status/index.ts b/packages/cli/src/commands/status/index.ts index 7907cd30c..b4788c492 100644 --- a/packages/cli/src/commands/status/index.ts +++ b/packages/cli/src/commands/status/index.ts @@ -4,14 +4,14 @@ import fs from "fs-extra"; import path from "path"; import * as git from "@changesets/git"; -import getReleasePlan from "@changesets/get-release-plan"; +import getReleasePlan from "@abizzle/changesets-get-release-plan"; import { error, log, info, warn } from "@changesets/logger"; import { VersionType, Release, ComprehensiveRelease, Config, -} from "@changesets/types"; +} from "@abizzle/changesets-types"; export default async function getStatus( cwd: string, @@ -37,7 +37,18 @@ export default async function getStatus( const sinceBranch = since === undefined ? (sinceMaster ? "master" : undefined) : since; const releasePlan = await getReleasePlan(cwd, sinceBranch, config); - const { changesets, releases } = releasePlan; + const { changesets, individualReleases, groupedReleases } = releasePlan; + const releases = individualReleases.concat( + ...groupedReleases.flatMap((g) => + g.projects.map((p) => ({ + changesets: g.changesets, + name: p.name, + newVersion: g.newVersion, + oldVersion: p.oldVersion, + type: p.type, + })) + ) + ); const changedPackages = await git.getChangedPackagesSinceRef({ cwd, ref: sinceBranch || config.baseBranch, diff --git a/packages/cli/src/commands/version/index.ts b/packages/cli/src/commands/version/index.ts index 510c46847..3b3791081 100644 --- a/packages/cli/src/commands/version/index.ts +++ b/packages/cli/src/commands/version/index.ts @@ -2,10 +2,10 @@ import chalk from "chalk"; import path from "path"; import * as git from "@changesets/git"; import { log, warn, error } from "@changesets/logger"; -import { Config } from "@changesets/types"; -import applyReleasePlan from "@changesets/apply-release-plan"; +import { Config } from "@abizzle/changesets-types"; +import applyReleasePlan from "@abizzle/changesets-apply-release-plan"; import readChangesets from "@changesets/read"; -import assembleReleasePlan from "@changesets/assemble-release-plan"; +import assembleReleasePlan from "@abizzle/changesets-assemble-release-plan"; import { getPackages } from "@manypkg/get-packages"; import { removeEmptyFolders } from "../../utils/v1-legacy/removeFolders"; diff --git a/packages/cli/src/commands/version/version.test.ts b/packages/cli/src/commands/version/version.test.ts index 2af298c8c..a22afd2a6 100644 --- a/packages/cli/src/commands/version/version.test.ts +++ b/packages/cli/src/commands/version/version.test.ts @@ -4,8 +4,8 @@ import * as git from "@changesets/git"; import { warn } from "@changesets/logger"; import { silenceLogsInBlock, testdir } from "@changesets/test-utils"; import writeChangeset from "@changesets/write"; -import { Config, Changeset } from "@changesets/types"; -import { defaultConfig } from "@changesets/config"; +import { Config, Changeset } from "@abizzle/changesets-types"; +import { defaultConfig } from "@abizzle/changesets-config"; import { getPackages } from "@manypkg/get-packages"; import pre from "../pre"; import version from "./index"; diff --git a/packages/cli/src/commit/commit.test.ts b/packages/cli/src/commit/commit.test.ts index cd2af9711..f3d9da14c 100644 --- a/packages/cli/src/commit/commit.test.ts +++ b/packages/cli/src/commit/commit.test.ts @@ -1,6 +1,6 @@ import outdent from "outdent"; import defaultCommitFunctions from "."; -import { NewChangeset, ReleasePlan } from "@changesets/types"; +import { NewChangeset, ReleasePlan } from "@abizzle/changesets-types"; const simpleChangeset: NewChangeset = { summary: "This is a summary", @@ -19,7 +19,7 @@ const simpleChangeset2: NewChangeset = { let simpleReleasePlan: ReleasePlan = { changesets: [simpleChangeset], - releases: [ + individualReleases: [ { name: "package-a", type: "minor", @@ -28,12 +28,13 @@ let simpleReleasePlan: ReleasePlan = { changesets: [simpleChangeset.id], }, ], + groupedReleases: [], preState: undefined, }; let secondReleasePlan: ReleasePlan = { changesets: [simpleChangeset, simpleChangeset2], - releases: [ + individualReleases: [ { name: "package-a", type: "minor", @@ -49,6 +50,7 @@ let secondReleasePlan: ReleasePlan = { changesets: [simpleChangeset2.id], }, ], + groupedReleases: [], preState: undefined, }; @@ -123,7 +125,7 @@ describe("defaultCommitFunctions", () => { it("should handle a multiple releases from one changeset", async () => { let releasePlan: ReleasePlan = { changesets: [simpleChangeset, simpleChangeset2], - releases: [ + individualReleases: [ { name: "package-a", type: "patch", @@ -139,6 +141,7 @@ describe("defaultCommitFunctions", () => { changesets: [simpleChangeset2.id], }, ], + groupedReleases: [], preState: undefined, }; const commitStr = await getVersionMessage(releasePlan, { @@ -186,7 +189,7 @@ describe("defaultCommitFunctions", () => { ], }, ], - releases: [ + individualReleases: [ { name: "pkg-a", type: "none", @@ -202,6 +205,7 @@ describe("defaultCommitFunctions", () => { changesets: ["quick-lions-devour"], }, ], + groupedReleases: [], preState: undefined, }, { skipCI: "version" } diff --git a/packages/cli/src/commit/getCommitFunctions.ts b/packages/cli/src/commit/getCommitFunctions.ts index 50c66c5f8..048dcc24e 100644 --- a/packages/cli/src/commit/getCommitFunctions.ts +++ b/packages/cli/src/commit/getCommitFunctions.ts @@ -1,4 +1,4 @@ -import { CommitFunctions } from "@changesets/types"; +import { CommitFunctions } from "@abizzle/changesets-types"; import path from "path"; import resolveFrom from "resolve-from"; diff --git a/packages/cli/src/commit/index.ts b/packages/cli/src/commit/index.ts index fe76c65c6..ba924188a 100644 --- a/packages/cli/src/commit/index.ts +++ b/packages/cli/src/commit/index.ts @@ -1,4 +1,9 @@ -import { Changeset, CommitFunctions, ReleasePlan } from "@changesets/types"; +import { + Changeset, + CommitFunctions, + ComprehensiveRelease, + ReleasePlan, +} from "@abizzle/changesets-types"; import outdent from "outdent"; type SkipCI = boolean | "add" | "version"; @@ -18,9 +23,23 @@ const getVersionMessage: CommitFunctions["getVersionMessage"] = async ( options: { skipCI?: SkipCI } | null ) => { const skipCI = options?.skipCI === "version" || options?.skipCI === true; - const publishableReleases = releasePlan.releases.filter( + const publishableReleases = releasePlan.individualReleases.filter( (release) => release.type !== "none" ); + publishableReleases.concat( + releasePlan.groupedReleases + .flatMap((g) => + g.projects.map((p) => ({ + changesets: g.changesets, + name: p.name, + newVersion: g.newVersion, + oldVersion: p.oldVersion, + type: p.type, + })) + ) + .filter((release) => release.type !== "none") + ); + const numPackagesReleased = publishableReleases.length; const releasesLines = publishableReleases diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 10ef30602..0a0959443 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -82,9 +82,9 @@ ${format("", err).replace(process.cwd(), "")} ## Versions -- @changesets/cli@${ +- @abizzle/changesets-cli@${ // eslint-disable-next-line import/no-extraneous-dependencies - require("@changesets/cli/package.json").version + require("@abizzle/changesets-cli/package.json").version } - node@${process.version} diff --git a/packages/cli/src/run.ts b/packages/cli/src/run.ts index 82b4e41b4..f4618c8d8 100644 --- a/packages/cli/src/run.ts +++ b/packages/cli/src/run.ts @@ -1,10 +1,10 @@ -import { Config } from "@changesets/types"; +import { Config } from "@abizzle/changesets-types"; import fs from "fs-extra"; import path from "path"; import { getPackages } from "@manypkg/get-packages"; import { getDependentsGraph } from "@changesets/get-dependents-graph"; import { error } from "@changesets/logger"; -import { read } from "@changesets/config"; +import { read } from "@abizzle/changesets-config"; import { ExitError } from "@changesets/errors"; import init from "./commands/init"; diff --git a/packages/config/CHANGELOG.md b/packages/config/CHANGELOG.md index 0540615ac..06632f4b4 100644 --- a/packages/config/CHANGELOG.md +++ b/packages/config/CHANGELOG.md @@ -1,4 +1,33 @@ -# @changesets/config +# @abizzle/changesets-config + +## 2.4.0-next.1 + +### Patch Changes + +- Updated dependencies [c5a83f9] + - @abizzle/changesets-types@6.0.0-next.3 + +## 2.4.0-next.0 + +### Minor Changes + +- 850b82e: Add support for single changelog fixed package groups. + + Optionally supply an object as a fixed package group entry like so: + + ```json + { + "fixed": [ + { + "group": ["@changesets/button", "@changesets/theme"], + "changelog": "CHANGELOG.md", + "name": "UI Packages" + } + ] + } + ``` + + This will create/update a single changelog at `/CHANGELOG.md` with changelog entries for `@changesets/button` and `@changesets/theme` under the title "UI Packages". ## 2.3.0 diff --git a/packages/config/package.json b/packages/config/package.json index 17c03037d..abe60bdc5 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -1,9 +1,9 @@ { - "name": "@changesets/config", - "version": "2.3.0", + "name": "@abizzle/changesets-config", + "version": "2.4.0-next.1", "description": "Utilities for reading and parsing Changeset's config", - "main": "dist/config.cjs.js", - "module": "dist/config.esm.js", + "main": "dist/changesets-config.cjs.js", + "module": "dist/changesets-config.esm.js", "license": "MIT", "repository": "https://github.com/changesets/changesets/tree/main/packages/config", "files": [ @@ -11,10 +11,10 @@ "schema.json" ], "dependencies": { + "@abizzle/changesets-types": "^6.0.0-next.3", "@changesets/errors": "^0.1.4", "@changesets/get-dependents-graph": "^1.3.5", "@changesets/logger": "^0.0.5", - "@changesets/types": "^5.2.1", "@manypkg/get-packages": "^1.1.3", "fs-extra": "^7.0.1", "micromatch": "^4.0.2" diff --git a/packages/config/schema.json b/packages/config/schema.json index 459e45106..df09c2c7f 100644 --- a/packages/config/schema.json +++ b/packages/config/schema.json @@ -26,15 +26,40 @@ } ], "description": "The configuration for changelog generators.", - "default": ["@changesets/cli", null] + "default": ["@abizzle/changesets-cli", null] }, "fixed": { "type": "array", "items": { - "type": "array", - "items": { - "type": "string" - } + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "object", + "properties": { + "changelog": { + "type": "string", + "description": "File path relative to project root." + }, + "group": { + "type": "array", + "items": { + "type": "string" + }, + "description": "An array of package names/globs." + }, + "name": { + "type": "string", + "description": "A name for the package group." + } + }, + "required": ["changelog", "group", "name"] + } + ] }, "description": "Packages that should always be released together with the same version.", "default": [] diff --git a/packages/config/src/index.test.ts b/packages/config/src/index.test.ts index b8b7f8835..eac7ccfb8 100644 --- a/packages/config/src/index.test.ts +++ b/packages/config/src/index.test.ts @@ -1,7 +1,7 @@ import { read, parse } from "./"; import jestInCase from "jest-in-case"; import * as logger from "@changesets/logger"; -import { Config, WrittenConfig } from "@changesets/types"; +import { Config, WrittenConfig } from "@abizzle/changesets-types"; import { Packages } from "@manypkg/get-packages"; import { testdir } from "@changesets/test-utils"; @@ -42,7 +42,7 @@ test("read reads the config", async () => { fixed: [], linked: [], changelog: false, - commit: ["@changesets/cli/commit", { skipCI: "version" }], + commit: ["@abizzle/changesets-cli/commit", { skipCI: "version" }], access: "restricted", baseBranch: "master", changedFilePatterns: ["**"], @@ -67,7 +67,7 @@ test("read reads the config", async () => { let defaults: Config = { fixed: [], linked: [], - changelog: ["@changesets/cli/changelog", null], + changelog: ["@abizzle/changesets-cli/changelog", null], commit: false, access: "restricted", baseBranch: "master", @@ -133,7 +133,7 @@ let correctCases: Record = { }, output: { ...defaults, - commit: ["@changesets/cli/commit", { skipCI: "version" }], + commit: ["@abizzle/changesets-cli/commit", { skipCI: "version" }], }, }, "commit custom": { @@ -368,7 +368,7 @@ describe("parser errors", () => { unsafeParse({ changelog: {} }, defaultPackages); }).toThrowErrorMatchingInlineSnapshot(` "Some errors occurred when validating the changesets config: - The \`changelog\` option is set as {} when the only valid values are undefined, false, a module path(e.g. "@changesets/cli/changelog" or "./some-module") or a tuple with a module path and config for the changelog generator(e.g. ["@changesets/cli/changelog", { someOption: true }])" + The \`changelog\` option is set as {} when the only valid values are undefined, false, a module path(e.g. "@abizzle/changesets-cli/changelog" or "./some-module") or a tuple with a module path and config for the changelog generator(e.g. ["@abizzle/changesets-cli/changelog", { someOption: true }])" `); }); test("changelog array with 3 values", () => { @@ -383,7 +383,7 @@ describe("parser errors", () => { "some-module", "something", "other" - ] when the only valid values are undefined, false, a module path(e.g. "@changesets/cli/changelog" or "./some-module") or a tuple with a module path and config for the changelog generator(e.g. ["@changesets/cli/changelog", { someOption: true }])" + ] when the only valid values are undefined, false, a module path(e.g. "@abizzle/changesets-cli/changelog" or "./some-module") or a tuple with a module path and config for the changelog generator(e.g. ["@abizzle/changesets-cli/changelog", { someOption: true }])" `); }); test("changelog array with first value not string", () => { @@ -394,7 +394,7 @@ describe("parser errors", () => { The \`changelog\` option is set as [ false, "something" - ] when the only valid values are undefined, false, a module path(e.g. "@changesets/cli/changelog" or "./some-module") or a tuple with a module path and config for the changelog generator(e.g. ["@changesets/cli/changelog", { someOption: true }])" + ] when the only valid values are undefined, false, a module path(e.g. "@abizzle/changesets-cli/changelog" or "./some-module") or a tuple with a module path and config for the changelog generator(e.g. ["@abizzle/changesets-cli/changelog", { someOption: true }])" `); }); test("access other string", () => { @@ -410,7 +410,7 @@ describe("parser errors", () => { unsafeParse({ commit: {} }, defaultPackages); }).toThrowErrorMatchingInlineSnapshot(` "Some errors occurred when validating the changesets config: - The \`commit\` option is set as {} when the only valid values are undefined or a boolean or a module path (e.g. "@changesets/cli/commit" or "./some-module") or a tuple with a module path and config for the commit message generator (e.g. ["@changesets/cli/commit", { "skipCI": "version" }])" + The \`commit\` option is set as {} when the only valid values are undefined or a boolean or a module path (e.g. "@abizzle/changesets-cli/commit" or "./some-module") or a tuple with a module path and config for the commit message generator (e.g. ["@abizzle/changesets-cli/commit", { "skipCI": "version" }])" `); }); describe("fixed", () => { @@ -419,7 +419,7 @@ describe("parser errors", () => { unsafeParse({ fixed: {} }, defaultPackages); }).toThrowErrorMatchingInlineSnapshot(` "Some errors occurred when validating the changesets config: - The \`fixed\` option is set as {} when the only valid values are undefined or an array of arrays of package names" + The \`fixed\` option is set as {} when the only valid values are undefined or an array of either arrays of package names or objects with a "group" property as an array of package names and a "changelog" property as a file path." `); }); test("array of non array", () => { @@ -429,7 +429,7 @@ describe("parser errors", () => { "Some errors occurred when validating the changesets config: The \`fixed\` option is set as [ {} - ] when the only valid values are undefined or an array of arrays of package names" + ] when the only valid values are undefined or an array of either arrays of package names or objects with a "group" property as an array of package names and a "changelog" property as a file path." `); }); test("array of array of non-string", () => { @@ -441,7 +441,7 @@ describe("parser errors", () => { [ {} ] - ] when the only valid values are undefined or an array of arrays of package names" + ] when the only valid values are undefined or an array of either arrays of package names or objects with a "group" property as an array of package names and a "changelog" property as a file path." `); }); test("package that does not exist", () => { diff --git a/packages/config/src/index.ts b/packages/config/src/index.ts index 07e913ec2..44794f3c4 100644 --- a/packages/config/src/index.ts +++ b/packages/config/src/index.ts @@ -10,13 +10,14 @@ import { Fixed, Linked, PackageGroup, -} from "@changesets/types"; + SingleChangelogPackageGroup, +} from "@abizzle/changesets-types"; import packageJson from "../package.json"; import { getDependentsGraph } from "@changesets/get-dependents-graph"; export let defaultWrittenConfig = { - $schema: `https://unpkg.com/@changesets/config@${packageJson.version}/schema.json`, - changelog: "@changesets/cli/changelog", + $schema: `https://unpkg.com/@abizzle/changesets-config@${packageJson.version}/schema.json`, + changelog: "@abizzle/changesets-cli/changelog", commit: false, fixed: [] as Fixed, linked: [] as Linked, @@ -26,8 +27,10 @@ export let defaultWrittenConfig = { ignore: [] as ReadonlyArray, } as const; -function flatten(arr: Array): T[] { - return ([] as T[]).concat(...arr); +function flatten(arr: Array): T[] { + return ([] as T[]).concat( + ...arr.map((a) => (Array.isArray(a) ? a : a.group)) + ); } function getNormalizedChangelogOption( @@ -49,7 +52,7 @@ function getNormalizedCommitOption( return false; } if (thing === true) { - return ["@changesets/cli/commit", { skipCI: "version" }]; + return ["@abizzle/changesets-cli/commit", { skipCI: "version" }]; } if (typeof thing === "string") { return [thing, null]; @@ -67,7 +70,7 @@ function getUnmatchedPatterns( ); } -const havePackageGroupsCorrectShape = ( +const haveLinkedPackageGroupsCorrectShape = ( pkgGroups: ReadonlyArray ) => { return ( @@ -79,6 +82,33 @@ const havePackageGroupsCorrectShape = ( ); }; +const haveFixedPackageGroupsCorrectShape = ( + pkgGroups: unknown +): pkgGroups is Fixed => { + return ( + isArray(pkgGroups) && + pkgGroups.every( + (group) => + (isArray(group) && group.every((entry) => typeof entry === "string")) || + isSingleChangelogFixedPackageGroup(group) + ) + ); +}; + +const isSingleChangelogFixedPackageGroup = ( + pkgGroup: unknown +): pkgGroup is SingleChangelogPackageGroup => { + return ( + isObject(pkgGroup) && + isArray(pkgGroup.group) && + (pkgGroup.group as unknown[]).every( + (pkgName) => typeof pkgName === "string" + ) && + typeof pkgGroup.changelog === "string" && + typeof pkgGroup.name === "string" + ); +}; + // TODO: it might be possible to remove this if improvements to `Array.isArray` ever land // related thread: github.com/microsoft/TypeScript/issues/36554 function isArray( @@ -91,6 +121,10 @@ function isArray( return Array.isArray(arg); } +function isObject(arg: unknown): arg is Record { + return !isArray(arg) && Boolean(arg && typeof arg === "object"); +} + export let read = async (cwd: string, packages: Packages) => { let json = await fs.readJSON(path.join(cwd, ".changeset", "config.json")); return parse(json, packages); @@ -117,7 +151,7 @@ export let parse = (json: WrittenConfig, packages: Packages): Config => { json.changelog, null, 2 - )} when the only valid values are undefined, false, a module path(e.g. "@changesets/cli/changelog" or "./some-module") or a tuple with a module path and config for the changelog generator(e.g. ["@changesets/cli/changelog", { someOption: true }])` + )} when the only valid values are undefined, false, a module path(e.g. "@abizzle/changesets-cli/changelog" or "./some-module") or a tuple with a module path and config for the changelog generator(e.g. ["@abizzle/changesets-cli/changelog", { someOption: true }])` ); } @@ -157,7 +191,7 @@ export let parse = (json: WrittenConfig, packages: Packages): Config => { json.commit, null, 2 - )} when the only valid values are undefined or a boolean or a module path (e.g. "@changesets/cli/commit" or "./some-module") or a tuple with a module path and config for the commit message generator (e.g. ["@changesets/cli/commit", { "skipCI": "version" }])` + )} when the only valid values are undefined or a boolean or a module path (e.g. "@abizzle/changesets-cli/commit" or "./some-module") or a tuple with a module path and config for the commit message generator (e.g. ["@abizzle/changesets-cli/commit", { "skipCI": "version" }])` ); } if (json.baseBranch !== undefined && typeof json.baseBranch !== "string") { @@ -184,21 +218,31 @@ export let parse = (json: WrittenConfig, packages: Packages): Config => { ); } - let fixed: string[][] = []; + let fixed: Array< + | string[] + | { + group: string[]; + changelog: string; + name: string; + } + > = []; if (json.fixed !== undefined) { - if (!havePackageGroupsCorrectShape(json.fixed)) { + if (!haveFixedPackageGroupsCorrectShape(json.fixed)) { messages.push( `The \`fixed\` option is set as ${JSON.stringify( json.fixed, null, 2 - )} when the only valid values are undefined or an array of arrays of package names` + )} when the only valid values are undefined or an array of either arrays of package names or objects with a "group" property as an array of package names and a "changelog" property as a file path.` ); } else { let foundPkgNames = new Set(); let duplicatedPkgNames = new Set(); - for (let fixedGroup of json.fixed) { + for (let fixedGrouping of json.fixed) { + const fixedGroup = isSingleChangelogFixedPackageGroup(fixedGrouping) + ? fixedGrouping.group + : fixedGrouping; messages.push( ...getUnmatchedPatterns(fixedGroup, pkgNames).map( (pkgOrGlob) => @@ -207,7 +251,15 @@ export let parse = (json: WrittenConfig, packages: Packages): Config => { ); let expandedFixedGroup = micromatch(pkgNames, fixedGroup); - fixed.push(expandedFixedGroup); + fixed.push( + isSingleChangelogFixedPackageGroup(fixedGrouping) + ? { + group: expandedFixedGroup, + name: fixedGrouping.name, + changelog: fixedGrouping.changelog, + } + : expandedFixedGroup + ); for (let fixedPkgName of expandedFixedGroup) { if (foundPkgNames.has(fixedPkgName)) { @@ -229,7 +281,7 @@ export let parse = (json: WrittenConfig, packages: Packages): Config => { let linked: string[][] = []; if (json.linked !== undefined) { - if (!havePackageGroupsCorrectShape(json.linked)) { + if (!haveLinkedPackageGroupsCorrectShape(json.linked)) { messages.push( `The \`linked\` option is set as ${JSON.stringify( json.linked, diff --git a/packages/get-release-plan/CHANGELOG.md b/packages/get-release-plan/CHANGELOG.md index 48137025d..95e559c0d 100644 --- a/packages/get-release-plan/CHANGELOG.md +++ b/packages/get-release-plan/CHANGELOG.md @@ -1,4 +1,36 @@ -# @changesets/get-release-plan +# @abizzle/changesets-get-release-plan + +## 3.0.17-next.3 + +### Patch Changes + +- Updated dependencies [c5a83f9] + - @abizzle/changesets-types@6.0.0-next.3 + - @abizzle/changesets-assemble-release-plan@6.0.0-next.3 + - @abizzle/changesets-config@2.4.0-next.1 + +## 3.0.17-next.2 + +### Patch Changes + +- Fixes dist files +- Updated dependencies + - @abizzle/changesets-assemble-release-plan@6.0.0-next.2 + +## 3.0.17-next.1 + +### Patch Changes + +- Updated dependencies [efd8c06] + - @abizzle/changesets-assemble-release-plan@6.0.0-next.1 + +## 3.0.17-next.0 + +### Patch Changes + +- Updated dependencies [850b82e] + - @abizzle/changesets-assemble-release-plan@5.3.0-next.0 + - @abizzle/changesets-config@2.4.0-next.0 ## 3.0.16 diff --git a/packages/get-release-plan/package.json b/packages/get-release-plan/package.json index 2e6ea42dd..5a54a5e95 100644 --- a/packages/get-release-plan/package.json +++ b/packages/get-release-plan/package.json @@ -1,15 +1,16 @@ { - "name": "@changesets/get-release-plan", - "version": "3.0.16", + "name": "@abizzle/changesets-get-release-plan", + "version": "3.0.17-next.3", "description": "Reads changesets and adds information on dependents that need bumping", - "main": "dist/get-release-plan.cjs.js", - "module": "dist/get-release-plan.esm.js", + "main": "dist/changesets-get-release-plan.cjs.js", + "module": "dist/changesets-get-release-plan.esm.js", "license": "MIT", "repository": "https://github.com/changesets/changesets/tree/main/packages/get-release-plan", "dependencies": { + "@abizzle/changesets-assemble-release-plan": "^6.0.0-next.3", + "@abizzle/changesets-config": "^2.4.0-next.1", + "@abizzle/changesets-types": "^6.0.0-next.3", "@babel/runtime": "^7.20.1", - "@changesets/assemble-release-plan": "^5.2.3", - "@changesets/config": "^2.3.0", "@changesets/pre": "^1.0.14", "@changesets/read": "^0.5.9", "@changesets/types": "^5.2.1", diff --git a/packages/get-release-plan/src/index.ts b/packages/get-release-plan/src/index.ts index af9d7e611..abd69bb87 100644 --- a/packages/get-release-plan/src/index.ts +++ b/packages/get-release-plan/src/index.ts @@ -1,7 +1,7 @@ -import assembleReleasePlan from "@changesets/assemble-release-plan"; +import assembleReleasePlan from "@abizzle/changesets-assemble-release-plan"; import readChangesets from "@changesets/read"; -import { read } from "@changesets/config"; -import { Config, ReleasePlan } from "@changesets/types"; +import { read } from "@abizzle/changesets-config"; +import { Config, ReleasePlan } from "@abizzle/changesets-types"; import { getPackages } from "@manypkg/get-packages"; import { readPreState } from "@changesets/pre"; diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md index dab6e0640..a129f4717 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/CHANGELOG.md @@ -1,4 +1,44 @@ -# @changesets/types +# @abizzle/changesets-types + +## 6.0.0-next.3 + +### Minor Changes + +- c5a83f9: Fix logic to write a single changelog entry for fixed groups + +## 6.0.0-next.2 + +### Patch Changes + +- Fixes dist files + +## 6.0.0-next.1 + +### Major Changes + +- efd8c06: Fixes single changelog fixed groups. + +## 5.3.0-next.0 + +### Minor Changes + +- 850b82e: Add support for single changelog fixed package groups. + + Optionally supply an object as a fixed package group entry like so: + + ```json + { + "fixed": [ + { + "group": ["@changesets/button", "@changesets/theme"], + "changelog": "CHANGELOG.md", + "name": "UI Packages" + } + ] + } + ``` + + This will create/update a single changelog at `/CHANGELOG.md` with changelog entries for `@changesets/button` and `@changesets/theme` under the title "UI Packages". ## 5.2.1 diff --git a/packages/types/package.json b/packages/types/package.json index ac30d1406..382b781b3 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,9 +1,10 @@ { - "name": "@changesets/types", - "version": "5.2.1", + "name": "@abizzle/changesets-types", + "version": "6.0.0-next.3", "description": "Common types shared between changeset packages", - "main": "dist/types.cjs.js", - "module": "dist/types.esm.js", + "main": "dist/changesets-types.cjs.js", + "types": "dist/changesets-types.cjs.d.ts", + "module": "dist/changesets-types.esm.js", "license": "MIT", "repository": "https://github.com/changesets/changesets/tree/main/packages/types" } diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 17bb849eb..1fc586f67 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -34,9 +34,22 @@ export type NewChangeset = Changeset & { id: string; }; +export type ComprehensiveGroupRelease = { + displayName: string; + relativeChangelogPath: string; + newVersion: string; + changesets: string[]; + projects: Array<{ + name: string; + oldVersion: string; + type: VersionType; + }>; +}; + export type ReleasePlan = { changesets: NewChangeset[]; - releases: ComprehensiveRelease[]; + individualReleases: ComprehensiveRelease[]; + groupedReleases: ComprehensiveGroupRelease[]; preState: PreState | undefined; }; @@ -58,7 +71,13 @@ export type PackageJSON = { export type PackageGroup = ReadonlyArray; -export type Fixed = ReadonlyArray; +export type SingleChangelogPackageGroup = { + group: PackageGroup; + changelog: string; + name: string; +}; + +export type Fixed = ReadonlyArray; export type Linked = ReadonlyArray; export interface PrivatePackages { @@ -124,13 +143,28 @@ export type ExperimentalOptions = { useCalculatedVersionForSnapshots?: boolean; }; -export type NewChangesetWithCommit = NewChangeset & { commit?: string }; +export type NewChangesetWithCommit = NewChangeset & { + commit?: string; + groupedChangelog?: boolean; +}; export type ModCompWithPackage = ComprehensiveRelease & { packageJson: PackageJSON; dir: string; }; +export type ModCompGroupWithPackage = Omit< + ComprehensiveGroupRelease, + "projects" +> & { + projects: Array< + ComprehensiveGroupRelease["projects"][number] & { + packageJson: PackageJSON; + dir: string; + } + >; +}; + export type GetReleaseLine = ( changeset: NewChangesetWithCommit, type: VersionType, diff --git a/yarn.lock b/yarn.lock index f0650c06c..7ada4d43c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1327,6 +1327,11 @@ resolved "https://registry.yarnpkg.com/@changesets/types/-/types-4.1.0.tgz#fb8f7ca2324fd54954824e864f9a61a82cb78fe0" integrity sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw== +"@changesets/types@^5.2.1": + version "5.2.1" + resolved "https://registry.yarnpkg.com/@changesets/types/-/types-5.2.1.tgz#a228c48004aa8a93bce4be2d1d31527ef3bf21f6" + integrity sha512-myLfHbVOqaq9UtUKqR/nZA/OY7xFjQMdfgfqeZIBK4d0hA6pgxArvdv8M+6NUzzBsjWLOtvApv8YHr4qM+Kpfg== + "@eslint/eslintrc@^1.3.3": version "1.3.3" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.3.tgz#2b044ab39fdfa75b4688184f9e573ce3c5b0ff95"