Skip to content

Commit

Permalink
feat: bumpVersionsWithWorkspaceProtocolOnly (#507)
Browse files Browse the repository at this point in the history
* feat: workspaceVersionsOnly

close #506

* Update packages/assemble-release-plan/src/index.test.ts

Co-authored-by: Mateusz Burzy艅ski <mateuszburzynski@gmail.com>

* Update packages/apply-release-plan/src/index.test.ts

Co-authored-by: Mateusz Burzy艅ski <mateuszburzynski@gmail.com>

* update fixture

* fix CR suggestions

* Update packages/cli/src/run.ts

Co-authored-by: Mateusz Burzy艅ski <mateuszburzynski@gmail.com>

* refactor: workspaceVersionsOnly=>bumpVersionsWithWorkspaceProtocolOnly

* style: fix

Co-authored-by: Mateusz Burzy艅ski <mateuszburzynski@gmail.com>
  • Loading branch information
zkochan and Andarist committed Jan 21, 2021
1 parent 049f0b3 commit 12f9a43
Show file tree
Hide file tree
Showing 18 changed files with 175 additions and 10 deletions.
10 changes: 10 additions & 0 deletions .changeset/great-dancers-kneel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"@changesets/apply-release-plan": minor
"@changesets/assemble-release-plan": minor
"@changesets/cli": minor
"@changesets/config": minor
"@changesets/get-dependents-graph": minor
"@changesets/types": minor
---

New setting added: bumpVersionsWithWorkspaceProtocolOnly. When it is set to `true`, versions are bumped in `dependencies`, only if those versions are prefixed by the workspace protocol. For instance, `"foo": "workspace:^1.0.0"`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# We just want a file in here so git collects it

For this we have deliberately not included a config file, as we want to test the defaults
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
9 changes: 9 additions & 0 deletions __fixtures__/workspace-and-other-range-dep/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"private": true,
"name": "simple-project",
"description": "three projects, each depending on one other",
"version": "1.0.0",
"workspaces": [
"packages/*"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "pkg-a",
"version": "1.0.0",
"dependencies": {
"pkg-b": "workspace:1.0.0"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "pkg-b",
"version": "1.0.0"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "pkg-c",
"version": "1.0.0",
"dependencies": {
"pkg-b": "1.0.0"
}
}
73 changes: 71 additions & 2 deletions packages/apply-release-plan/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ class FakeReleasePlan {

constructor(
changesets: NewChangeset[] = [],
releases: ComprehensiveRelease[] = []
releases: ComprehensiveRelease[] = [],
config: Partial<Config> = {}
) {
const baseChangeset: NewChangeset = {
id: "quick-lions-devour",
Expand All @@ -48,7 +49,8 @@ class FakeReleasePlan {
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
useCalculatedVersionForSnapshots: false
}
},
...config
};

this.changesets = [baseChangeset, ...changesets];
Expand Down Expand Up @@ -264,6 +266,73 @@ describe("apply release plan", () => {
}
});
});
it("should update workspace ranges only with bumpVersionsWithWorkspaceProtocolOnly", async () => {
const releasePlan = new FakeReleasePlan(
[
{
id: "some-id",
releases: [
{ name: "pkg-b", type: "minor" },
{ name: "pkg-c", type: "minor" }
],
summary: "a very useful summary"
}
],
[
{
changesets: ["some-id"],
name: "pkg-b",
newVersion: "1.1.0",
oldVersion: "1.0.0",
type: "minor"
},
{
changesets: ["some-id"],
name: "pkg-c",
newVersion: "1.1.0",
oldVersion: "1.0.0",
type: "minor"
}
],
{
bumpVersionsWithWorkspaceProtocolOnly: true
}
);
let { changedFiles } = await testSetup(
"workspace-and-other-range-dep",
releasePlan.getReleasePlan(),
releasePlan.config
);
let pkgAPath = changedFiles.find(a =>
a.endsWith(`pkg-a${path.sep}package.json`)
);

if (!pkgAPath) throw new Error(`could not find an updated package json`);
let pkgAJSON = await fs.readJSON(pkgAPath);

expect(pkgAJSON).toEqual({
name: "pkg-a",
version: "1.1.0",
dependencies: {
"pkg-b": "workspace:1.1.0"
}
});

let pkgCPath = changedFiles.find(a =>
a.endsWith(`pkg-c${path.sep}package.json`)
);

if (!pkgCPath) throw new Error(`could not find an updated package json`);
let pkgCJSON = await fs.readJSON(pkgCPath);

expect(pkgCJSON).toEqual({
name: "pkg-c",
version: "1.1.0",
dependencies: {
"pkg-b": "1.0.0"
}
});
});
it("should update a version for two packages with different new versions", async () => {
const releasePlan = new FakeReleasePlan(
[],
Expand Down
4 changes: 3 additions & 1 deletion packages/apply-release-plan/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ export default async function applyReleasePlan(
updateInternalDependencies: config.updateInternalDependencies,
onlyUpdatePeerDependentsWhenOutOfRange:
config.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH
.onlyUpdatePeerDependentsWhenOutOfRange
.onlyUpdatePeerDependentsWhenOutOfRange,
bumpVersionsWithWorkspaceProtocolOnly:
config.bumpVersionsWithWorkspaceProtocolOnly
});
});

Expand Down
6 changes: 5 additions & 1 deletion packages/apply-release-plan/src/version-package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ export default function versionPackage(
versionsToUpdate: Array<{ name: string; version: string; type: VersionType }>,
{
updateInternalDependencies,
onlyUpdatePeerDependentsWhenOutOfRange
onlyUpdatePeerDependentsWhenOutOfRange,
bumpVersionsWithWorkspaceProtocolOnly
}: {
updateInternalDependencies: "patch" | "minor";
onlyUpdatePeerDependentsWhenOutOfRange: boolean;
bumpVersionsWithWorkspaceProtocolOnly?: boolean;
}
) {
let { newVersion, packageJson } = release;
Expand Down Expand Up @@ -58,6 +60,8 @@ export default function versionPackage(
const usesWorkspaceRange = depCurrentVersion.startsWith("workspace:");
if (usesWorkspaceRange) {
depCurrentVersion = depCurrentVersion.substr(10);
} else if (bumpVersionsWithWorkspaceProtocolOnly === true) {
continue;
}
if (
// an empty string is the normalised version of x/X/*
Expand Down
25 changes: 25 additions & 0 deletions packages/assemble-release-plan/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,31 @@ describe("assemble-release-plan", () => {
expect(releases[1].newVersion).toEqual("1.0.1");
expect(releases[1].changesets).toEqual([]);
});
it("should assemble the release plan only with workspace protocol dependents when using bumpVersionsWithWorkspaceProtocolOnly", () => {
setup.updateDependency("pkg-b", "pkg-a", "^1.0.0");
setup.updateDependency("pkg-c", "pkg-a", "workspace:^1.0.0");
setup.addChangeset({
id: "big-cats-delight",
releases: [{ name: "pkg-a", type: "major" }]
});

let { releases } = assembleReleasePlan(
setup.changesets,
setup.packages,
{
...defaultConfig,
bumpVersionsWithWorkspaceProtocolOnly: true
},
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([]);
});
it("should assemble release plan without dependent through dev dependency", () => {
setup.updateDevDependency("pkg-b", "pkg-a", "^1.0.0");
setup.addChangeset({
Expand Down
5 changes: 4 additions & 1 deletion packages/assemble-release-plan/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ function assembleReleasePlan(
config.ignore
);

let dependencyGraph = getDependentsGraph(packages);
let dependencyGraph = getDependentsGraph(packages, {
bumpVersionsWithWorkspaceProtocolOnly:
config.bumpVersionsWithWorkspaceProtocolOnly
});

let releasesValidated = false;
while (releasesValidated === false) {
Expand Down
5 changes: 4 additions & 1 deletion packages/cli/src/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,10 @@ export async function run(
}

// Validate that all dependents of ignored packages are listed in the ignore list
const dependentsGraph = getDependentsGraph(packages);
const dependentsGraph = getDependentsGraph(packages, {
bumpVersionsWithWorkspaceProtocolOnly:
config.bumpVersionsWithWorkspaceProtocolOnly
});
for (const ignoredPackage of config.ignore) {
const dependents = dependentsGraph.get(ignoredPackage) || [];
for (const dependent of dependents) {
Expand Down
4 changes: 3 additions & 1 deletion packages/config/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ test("read reads the config", async () => {
baseBranch: "master",
updateInternalDependencies: "patch",
ignore: [],
bumpVersionsWithWorkspaceProtocolOnly: false,
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
useCalculatedVersionForSnapshots: false
Expand All @@ -61,7 +62,8 @@ let defaults = {
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
useCalculatedVersionForSnapshots: false
}
},
bumpVersionsWithWorkspaceProtocolOnly: false
} as const;

let correctCases: Record<string, CorrectCase> = {
Expand Down
3 changes: 3 additions & 0 deletions packages/config/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,9 @@ export let parse = (json: WrittenConfig, packages: Packages): Config => {
? defaultWrittenConfig.ignore
: normalizePackageNames(json.ignore, pkgNames)[0],

bumpVersionsWithWorkspaceProtocolOnly:
json.bumpVersionsWithWorkspaceProtocolOnly === true,

___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange:
json.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH === undefined ||
Expand Down
7 changes: 6 additions & 1 deletion packages/get-dependents-graph/src/get-dependency-graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ const getAllDependencies = (config: PackageJSON) => {
};

export default function getDependencyGraph(
packages: Packages
packages: Packages,
opts?: {
bumpVersionsWithWorkspaceProtocolOnly?: boolean;
}
): {
graph: Map<string, { pkg: Package; dependencies: Array<string> }>;
valid: boolean;
Expand Down Expand Up @@ -70,6 +73,8 @@ export default function getDependencyGraph(

if (depVersion.startsWith("workspace:")) {
depVersion = depVersion.substr(10);
} else if (opts?.bumpVersionsWithWorkspaceProtocolOnly === true) {
continue;
}

// internal dependencies only need to semver satisfy, not '==='
Expand Down
10 changes: 8 additions & 2 deletions packages/get-dependents-graph/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { Packages, Package } from "@manypkg/get-packages";
import getDependencyGraph from "./get-dependency-graph";

export function getDependentsGraph(packages: Packages) {
export function getDependentsGraph(
packages: Packages,
opts?: { bumpVersionsWithWorkspaceProtocolOnly?: boolean }
) {
const graph: Map<string, { pkg: Package; dependents: string[] }> = new Map();

const { graph: dependencyGraph } = getDependencyGraph(packages);
const { graph: dependencyGraph } = getDependencyGraph(packages, {
bumpVersionsWithWorkspaceProtocolOnly:
opts?.bumpVersionsWithWorkspaceProtocolOnly === true
});

const dependentsLookup: {
[key: string]: { pkg: Package; dependents: Array<string> };
Expand Down
2 changes: 2 additions & 0 deletions packages/types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export type Config = {
/** The minimum bump type to trigger automatic update of internal dependencies that are part of the same release */
updateInternalDependencies: "patch" | "minor";
ignore: ReadonlyArray<string>;
bumpVersionsWithWorkspaceProtocolOnly?: boolean;
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: Required<
ExperimentalOptions
>;
Expand All @@ -79,6 +80,7 @@ export type WrittenConfig = {
/** The minimum bump type to trigger automatic update of internal dependencies that are part of the same release */
updateInternalDependencies?: "patch" | "minor";
ignore?: ReadonlyArray<string>;
bumpVersionsWithWorkspaceProtocolOnly?: boolean;
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH?: ExperimentalOptions;
};

Expand Down

0 comments on commit 12f9a43

Please sign in to comment.