Skip to content

Commit

Permalink
Add new config option for always upgrading internal dependents (#542)
Browse files Browse the repository at this point in the history
* Add new config option for always upgrading internal dependents

* Fixed tests

* Add a config test for updateInternalDependents

* Fixed apply-release-plan tests

* Fixed config test

* Mock git hash for version tests

* Refactor updateInternalDependents to an enum

* Move updateInternalDependents to experimental options

* Add a note about updateInternalDependencies

* fix stuff

* Enabled updateInternalDependents: always for the repo itself

* add cahngesets

* Update .changeset/light-buttons-chew.md
  • Loading branch information
Andarist committed Apr 8, 2021
1 parent 707002d commit de2b4a5
Show file tree
Hide file tree
Showing 15 changed files with 378 additions and 171 deletions.
5 changes: 4 additions & 1 deletion .changeset/config.json
Expand Up @@ -5,5 +5,8 @@
],
"baseBranch": "main",
"commit": false,
"access": "public"
"access": "public",
"___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
"updateInternalDependents": "always"
}
}
17 changes: 17 additions & 0 deletions .changeset/light-buttons-chew.md
@@ -0,0 +1,17 @@
---
"@changesets/cli": minor
"@changesets/config": minor
"@changesets/types": major
---

A new `updateInternalDependents` experimental option has been added. It can be used to add dependent packages to the release (if they are not already a part of it) with patch bumps. To use it you can add this to your config:

```json
{
"___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
"updateInternalDependents": "always"
}
}
```

This option accepts two values - `"always"` and `"out-of-range"` (the latter matches the current default behavior).
7 changes: 7 additions & 0 deletions .changeset/rare-balloons-kick.md
@@ -0,0 +1,7 @@
---
"@changesets/apply-release-plan": major
"@changesets/assemble-release-plan": major
"@changesets/get-release-plan": major
---

The accepted `Config` type has been changed - a new experimental option (`updateInternalDependents`) was added to it.
4 changes: 3 additions & 1 deletion docs/config-file-options.md
Expand Up @@ -14,7 +14,7 @@ Changesets has a minimal amount of configuration options. Mostly these are for w
}
```

> NOTE: the `linked`, `updateInternalDependencies` and `ignore` options are only for behaviour in monorepos.
> NOTE: the `linked`, `updateInternalDependencies`, and `ignore` options are only for behaviour in monorepos.
## `commit` (`true` | `false`)

Expand Down Expand Up @@ -99,6 +99,8 @@ Using `minor` allows consumers to more actively control their own deduplication

Changesets will always update the dependency if it would leave the old semver range.

> ⚠ Note: this is only applied for packages which are already released in the current release. If A depends on B and we only release B then A won't be bumped.
## `changelog` (false or a path)

This option is for setting how the changelog for packages should be generated. If it is `false`, no changelogs will be generated. Setting it to a string specifies a path from where we will load the changelog generation functions. It expects to be a file that exports the following:
Expand Down
24 changes: 10 additions & 14 deletions packages/apply-release-plan/src/get-changelog-entry.ts
Expand Up @@ -22,7 +22,7 @@ async function generateChangesForVersionTypeMarkdown(
}

// release is the package and version we are releasing
export default async function generateMarkdown(
export default async function getChangelogEntry(
release: ModCompWithPackage,
releases: ModCompWithPackage[],
changesets: NewChangesetWithCommit[],
Expand All @@ -38,7 +38,7 @@ export default async function generateMarkdown(
) {
if (release.type === "none") return null;

const releaseObj: ChangelogLines = {
const changelogLines: ChangelogLines = {
major: [],
minor: [],
patch: []
Expand All @@ -51,19 +51,15 @@ export default async function generateMarkdown(
changesets.forEach(cs => {
const rls = cs.releases.find(r => r.name === release.name);
if (rls && rls.type !== "none") {
releaseObj[rls.type].push(
changelogLines[rls.type].push(
changelogFuncs.getReleaseLine(cs, rls.type, changelogOpts)
);
}
});

let dependentReleases = releases.filter(rel => {
const dependencyVersionRange = release.packageJson.dependencies
? release.packageJson.dependencies[rel.name]
: null;
const peerDependencyVersionRange = release.packageJson.peerDependencies
? release.packageJson.peerDependencies[rel.name]
: null;
const dependencyVersionRange = release.packageJson.dependencies?.[rel.name];
const peerDependencyVersionRange =
release.packageJson.peerDependencies?.[rel.name];

const versionRange = dependencyVersionRange || peerDependencyVersionRange;
return (
Expand Down Expand Up @@ -94,7 +90,7 @@ export default async function generateMarkdown(
relevantChangesetIds.has(cs.id)
);

releaseObj.patch.push(
changelogLines.patch.push(
changelogFuncs.getDependencyReleaseLine(
relevantChangesets,
dependentReleases,
Expand All @@ -104,9 +100,9 @@ export default async function generateMarkdown(

return [
`## ${release.newVersion}`,
await generateChangesForVersionTypeMarkdown(releaseObj, "major"),
await generateChangesForVersionTypeMarkdown(releaseObj, "minor"),
await generateChangesForVersionTypeMarkdown(releaseObj, "patch")
await generateChangesForVersionTypeMarkdown(changelogLines, "major"),
await generateChangesForVersionTypeMarkdown(changelogLines, "minor"),
await generateChangesForVersionTypeMarkdown(changelogLines, "patch")
]
.filter(line => line)
.join("\n");
Expand Down
19 changes: 19 additions & 0 deletions packages/apply-release-plan/src/index.test.ts
Expand Up @@ -49,6 +49,7 @@ class FakeReleasePlan {
ignore: [],
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
useCalculatedVersionForSnapshots: false
},
...config
Expand Down Expand Up @@ -84,6 +85,7 @@ async function testSetup(
ignore: [],
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
useCalculatedVersionForSnapshots: false
}
};
Expand Down Expand Up @@ -417,6 +419,7 @@ describe("apply release plan", () => {
ignore: [],
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
useCalculatedVersionForSnapshots: false
}
}
Expand Down Expand Up @@ -478,6 +481,7 @@ describe("apply release plan", () => {
ignore: [],
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
useCalculatedVersionForSnapshots: false
}
}
Expand Down Expand Up @@ -625,6 +629,7 @@ describe("apply release plan", () => {
ignore: [],
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
useCalculatedVersionForSnapshots: false
}
}
Expand Down Expand Up @@ -708,6 +713,7 @@ describe("apply release plan", () => {
ignore: [],
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
useCalculatedVersionForSnapshots: false
}
}
Expand Down Expand Up @@ -783,6 +789,7 @@ describe("apply release plan", () => {
ignore: [],
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
useCalculatedVersionForSnapshots: false
}
}
Expand Down Expand Up @@ -858,6 +865,7 @@ describe("apply release plan", () => {
ignore: [],
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
useCalculatedVersionForSnapshots: false
}
}
Expand Down Expand Up @@ -936,6 +944,7 @@ describe("apply release plan", () => {
ignore: [],
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
useCalculatedVersionForSnapshots: false
}
}
Expand Down Expand Up @@ -1019,6 +1028,7 @@ describe("apply release plan", () => {
ignore: [],
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
useCalculatedVersionForSnapshots: false
}
}
Expand Down Expand Up @@ -1094,6 +1104,7 @@ describe("apply release plan", () => {
ignore: [],
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
useCalculatedVersionForSnapshots: false
}
}
Expand Down Expand Up @@ -1169,6 +1180,7 @@ describe("apply release plan", () => {
ignore: [],
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
useCalculatedVersionForSnapshots: false
}
}
Expand Down Expand Up @@ -1248,6 +1260,7 @@ describe("apply release plan", () => {
ignore: [],
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: true,
updateInternalDependents: "out-of-range",
useCalculatedVersionForSnapshots: false
}
}
Expand Down Expand Up @@ -1406,6 +1419,7 @@ describe("apply release plan", () => {
ignore: [],
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
useCalculatedVersionForSnapshots: false
}
}
Expand Down Expand Up @@ -1509,6 +1523,7 @@ describe("apply release plan", () => {
ignore: [],
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
useCalculatedVersionForSnapshots: false
}
}
Expand Down Expand Up @@ -1590,6 +1605,7 @@ describe("apply release plan", () => {
ignore: [],
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
useCalculatedVersionForSnapshots: false
}
}
Expand Down Expand Up @@ -1675,6 +1691,7 @@ describe("apply release plan", () => {
ignore: [],
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
useCalculatedVersionForSnapshots: false
}
}
Expand Down Expand Up @@ -1773,6 +1790,7 @@ describe("apply release plan", () => {
ignore: [],
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
useCalculatedVersionForSnapshots: false
}
}
Expand Down Expand Up @@ -2172,6 +2190,7 @@ describe("apply release plan", () => {
ignore: [],
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
useCalculatedVersionForSnapshots: false
}
}
Expand Down
4 changes: 2 additions & 2 deletions packages/apply-release-plan/src/index.ts
Expand Up @@ -75,7 +75,7 @@ export default async function applyReleasePlan(

const versionCommit = createVersionCommit(releasePlan, config.commit);

let releaseWithPackages = releases.map(release => {
let releasesWithPackage = releases.map(release => {
let pkg = packagesByName.get(release.name);
if (!pkg)
throw new Error(
Expand All @@ -89,7 +89,7 @@ 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(
releaseWithPackages,
releasesWithPackage,
changesets,
config,
cwd
Expand Down
38 changes: 21 additions & 17 deletions packages/assemble-release-plan/src/determine-dependents.ts
Expand Up @@ -3,7 +3,8 @@ import {
Release,
DependencyType,
PackageJSON,
VersionType
VersionType,
Config
} from "@changesets/types";
import { Package } from "@manypkg/get-packages";
import { InternalRelease, PreInfo } from "./types";
Expand All @@ -21,20 +22,18 @@ import { incrementVersion } from "./increment";
We could solve this by inlining this function, or by returning a deep-cloned then
modified array, but we decided both of those are worse than this solution.
*/
export default function getDependents({
export default function determineDependents({
releases,
packagesByName,
dependencyGraph,
preInfo,
ignoredPackages,
onlyUpdatePeerDependentsWhenOutOfRange
config
}: {
releases: Map<string, InternalRelease>;
packagesByName: Map<string, Package>;
dependencyGraph: Map<string, string[]>;
preInfo: PreInfo | undefined;
ignoredPackages: Readonly<string[]>;
onlyUpdatePeerDependentsWhenOutOfRange: boolean;
config: Config;
}): boolean {
let updated = false;
// NOTE this is intended to be called recursively
Expand All @@ -51,17 +50,14 @@ export default function getDependents({
`Error in determining dependents - could not find package in repository: ${nextRelease.name}`
);
}
// For each dependent we are going to see whether it needs to be bumped because it's dependency
// is leaving the version range.
pkgDependents
.map(dependent => {
let type: VersionType | undefined;

const dependentPackage = packagesByName.get(dependent);
if (!dependentPackage) throw new Error("Dependency map is incorrect");

// If the dependent is an ignored package, we want to bump its dependencies without a release, so setting type to "none"
if (ignoredPackages.includes(dependent)) {
if (config.ignore.includes(dependent)) {
type = "none";
} else {
const dependencyVersionRanges = getDependencyVersionRanges(
Expand All @@ -78,7 +74,9 @@ export default function getDependents({
releases,
nextRelease,
preInfo,
onlyUpdatePeerDependentsWhenOutOfRange
onlyUpdatePeerDependentsWhenOutOfRange:
config.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH
.onlyUpdatePeerDependentsWhenOutOfRange
})
) {
type = "major";
Expand All @@ -87,11 +85,13 @@ export default function getDependents({
// TODO validate this - I don't think it's right anymore
(!releases.has(dependent) ||
releases.get(dependent)!.type === "none") &&
!semver.satisfies(
incrementVersion(nextRelease, preInfo),
// to deal with a * versionRange that comes from workspace:* dependencies as the wildcard will match anything
versionRange === "*" ? nextRelease.oldVersion : versionRange
)
(config.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH
.updateInternalDependents === "always" ||
!semver.satisfies(
incrementVersion(nextRelease, preInfo),
// to deal with a * versionRange that comes from workspace:* dependencies as the wildcard will match anything
versionRange === "*" ? nextRelease.oldVersion : versionRange
))
) {
switch (depType) {
case "dependencies":
Expand Down Expand Up @@ -119,7 +119,11 @@ export default function getDependents({
if (releases.has(dependent) && releases.get(dependent)!.type === type) {
type = undefined;
}
return { name: dependent, type, pkgJSON: dependentPackage.packageJson };
return {
name: dependent,
type,
pkgJSON: dependentPackage.packageJson
};
})
.filter(({ type }) => type)
.forEach(
Expand Down

0 comments on commit de2b4a5

Please sign in to comment.