Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed issues with * ranges not being replaced in premode #703

Merged
merged 1 commit into from
Feb 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/dull-pears-crash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@changesets/apply-release-plan": patch
"@changesets/cli": patch
---

Fixed an issue with `*` dependency ranges not being replaced in premode. Those have to replaced with exact versions because prereleases don't satisfy wildcard ranges. A published prerelease package with such dependency range left untouched won't install correct prerelease dependency version.
6 changes: 6 additions & 0 deletions .changeset/weak-needles-grin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@changesets/assemble-release-plan": patch
"@changesets/cli": patch
---

Fixed an issue with dependant packages being always bumped when their `*` dependency was bumped.
30 changes: 24 additions & 6 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,35 @@
"version": "0.2.0",
"configurations": [
{
"name": "Debug Jest Tests",
"type": "node",
"request": "launch",
"runtimeArgs": [
"--inspect-brk",
"${workspaceRoot}/node_modules/.bin/jest",
"--runInBand"
"name": "Jest All",
"program": "${workspaceFolder}/node_modules/.bin/jest",
"args": ["--runInBand"],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"disableOptimisticBPs": true,
"windows": {
"program": "${workspaceFolder}/node_modules/jest/bin/jest"
}
},
{
"type": "node",
"request": "launch",
"name": "Jest Current File",
"program": "${workspaceFolder}/node_modules/.bin/jest",
"args": [
"${fileBasenameNoExtension}",
"--config",
"jest.config.js",
"--no-cache"
],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"port": 9229
"disableOptimisticBPs": true,
"windows": {
"program": "${workspaceFolder}/node_modules/jest/bin/jest"
}
}
]
}
7 changes: 7 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
clearMocks: true,
watchPlugins: [
"jest-watch-typeahead/filename",
"jest-watch-typeahead/testname"
]
};
7 changes: 0 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,5 @@
"packages/*"
]
},
"jest": {
"clearMocks": true,
"watchPlugins": [
"jest-watch-typeahead/filename",
"jest-watch-typeahead/testname"
]
},
"prettier": {}
}
34 changes: 24 additions & 10 deletions packages/apply-release-plan/src/version-package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
VersionType
} from "@changesets/types";
import getVersionRangeType from "@changesets/get-version-range-type";
import { Range } from "semver";
import semver from "semver";
import { shouldUpdateDependencyBasedOnConfig } from "./utils";

const DEPENDENCY_TYPES = [
Expand Down Expand Up @@ -55,27 +55,41 @@ export default function versionPackage(
onlyUpdatePeerDependentsWhenOutOfRange
}
)
)
) {
continue;
}
const usesWorkspaceRange = depCurrentVersion.startsWith("workspace:");

if (
!usesWorkspaceRange &&
bumpVersionsWithWorkspaceProtocolOnly === true
) {
continue;
}

if (usesWorkspaceRange) {
const workspaceDepVersion = depCurrentVersion.replace(
/^workspace:/,
""
);
depCurrentVersion =
workspaceDepVersion === "^" || workspaceDepVersion === "~"
? "*"
: workspaceDepVersion;
} else if (bumpVersionsWithWorkspaceProtocolOnly === true) {
continue;
if (
workspaceDepVersion === "*" ||
workspaceDepVersion === "^" ||
workspaceDepVersion === "~"
) {
continue;
}
depCurrentVersion = workspaceDepVersion;
}
if (
// an empty string is the normalised version of x/X/*
// we don't want to change these versions because they will match
// any version and if someone makes the range that
// they probably want it to stay like that
new Range(depCurrentVersion).range !== ""
// they probably want it to stay like that...
new semver.Range(depCurrentVersion).range !== "" ||
// ...unless the current version of a dependency is a prerelease (which doesn't satisfy x/X/*)
// leaving those as is would leave the package in a non-installable state (wrong dep versions would get installed)
semver.prerelease(version) !== null
) {
let rangeType = getVersionRangeType(depCurrentVersion);
let newNewRange = `${rangeType}${version}`;
Expand Down
27 changes: 19 additions & 8 deletions packages/assemble-release-plan/src/determine-dependents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export default function determineDependents({
} else {
const dependencyVersionRanges = getDependencyVersionRanges(
dependentPackage.packageJson,
nextRelease.name
nextRelease
);

for (const { depType, versionRange } of dependencyVersionRanges) {
Expand All @@ -89,8 +89,7 @@ export default function determineDependents({
.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
versionRange
))
) {
switch (depType) {
Expand Down Expand Up @@ -167,7 +166,7 @@ export default function determineDependents({
*/
function getDependencyVersionRanges(
dependentPkgJSON: PackageJSON,
dependencyName: string
dependencyRelease: InternalRelease
): {
depType: DependencyType;
versionRange: string;
Expand All @@ -183,12 +182,24 @@ function getDependencyVersionRanges(
versionRange: string;
}[] = [];
for (const type of DEPENDENCY_TYPES) {
const deps = dependentPkgJSON[type];
if (!deps) continue;
if (deps[dependencyName]) {
const versionRange = dependentPkgJSON[type]?.[dependencyRelease.name];
if (!versionRange) continue;

if (versionRange.startsWith("workspace:")) {
dependencyVersionRanges.push({
depType: type,
versionRange: deps[dependencyName].replace("workspace:", "")
versionRange:
// intentionally keep other workspace ranges untouched
// this has to be fixed but this should only be done when adding appropriate tests
versionRange === "workspace:*"
? // workspace:* actually means the current exact version, and not a wildcard similar to a reguler * range
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

馃樁

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hehe, ye - this is weird. Basically workspace:* means "replace with the current version (exact)", workspace:^ means "replace with the current version, modified with ^" (and the same applies to workspace:~).

dependencyRelease.oldVersion
: versionRange.replace(/^workspace:/, "")
});
} else {
dependencyVersionRanges.push({
depType: type,
versionRange
});
}
}
Expand Down
19 changes: 19 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,25 @@ describe("assemble-release-plan", () => {
expect(releases[1].newVersion).toEqual("1.0.1");
expect(releases[1].changesets).toEqual([]);
});
it("should assemble release plan with without a wildcard dependent", () => {
setup.updateDependency("pkg-b", "pkg-a", "*");
setup.addChangeset({
id: "big-cats-delight",
releases: [{ name: "pkg-a", type: "major" }]
});

let { releases } = 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");
});

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");
Expand Down