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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add new bump option "prefix" #101

Merged
merged 7 commits into from
May 13, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const cli = meow(
--debug Output debugging information.
--sequential-init Avoid hypothetical concurrent initialization collisions.
--first-parent Apply commit filtering to current branch only.
--deps.bump Define deps version updating rule. Allowed: override, satisfy, inherit.
--deps.bump Define deps version updating rule. Allowed: override, override-carret, satisfy, inherit.
--deps.release Define release type for dependent package if any of its deps changes. Supported values: patch, minor, major, inherit.
--ignore-packages Packages' list to be ignored on bumping process
--ignore-private-packages Ignore private packages
Expand Down
2 changes: 1 addition & 1 deletion lib/createInlinePluginCreator.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ function createInlinePluginCreator(packages, multiContext, synchronizer, flags)
getLucky("_readyForTagging", pkg);
await waitFor("_readyForTagging", pkg);

updateManifestDeps(pkg);
updateManifestDeps(pkg, true, flags.deps.bump === "override-carret");
pkg._depsUpdated = true;

const res = await plugins.prepare(context);
Expand Down
17 changes: 11 additions & 6 deletions lib/updateDeps.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ const getHighestReleaseType = (...releaseTypes) =>
* Resolve package release type taking into account the cascading dependency update.
*
* @param {Package} pkg Package object.
* @param {string|undefined} bumpStrategy Dependency resolution strategy: override, satisfy, inherit.
* @param {string|undefined} bumpStrategy Dependency resolution strategy: override, override-carret, satisfy, inherit.
* @param {string|undefined} releaseStrategy Release type triggered by deps updating: patch, minor, major, inherit.
* @returns {string|undefined} Resolved release type.
* @internal
Expand Down Expand Up @@ -173,7 +173,7 @@ const resolveReleaseType = (pkg, bumpStrategy = "override", releaseStrategy = "p
* Indicates if the manifest file requires a change for the given dependency
* @param {Package} pkg Package object.
* @param {Package} dependency dependency to check
* @param {string|undefined} bumpStrategy Dependency resolution strategy: override, satisfy, inherit.
* @param {string|undefined} bumpStrategy Dependency resolution strategy: override, override-carret, satisfy, inherit.
* @returns {boolean } true if dependency needs to change
*/
const needsDependencyUpdate = (pkg, dependency, bumpStrategy) => {
Expand Down Expand Up @@ -210,7 +210,7 @@ const needsDependencyUpdate = (pkg, dependency, bumpStrategy) => {
* @param {Object} scope object containing dependencies. Dependency names are the keys, dependency rule the values.
* @param {string} name name of the dependency to update
* @param {string} nextVersion the new version of the dependency
* @param {string} bumpStrategy Dependency resolution strategy: override, satisfy, inherit.
* @param {string} bumpStrategy Dependency resolution strategy: override, override-carret, satisfy, inherit.
* @returns {boolean} true if a the dependency exists in the scope and requires a version update
*/
const manifestUpdateNecessary = (scope, name, nextVersion, bumpStrategy) => {
Expand All @@ -232,7 +232,7 @@ const manifestUpdateNecessary = (scope, name, nextVersion, bumpStrategy) => {
*
* @param {string} currentVersion Current dep version
* @param {string} nextVersion Next release type: patch, minor, major
* @param {string|undefined} bumpStrategy Resolution strategy: inherit, override, satisfy
* @param {string|undefined} bumpStrategy Resolution strategy: inherit, override, override-carret, satisfy
* @returns {string} Next dependency version
* @internal
*/
Expand Down Expand Up @@ -264,6 +264,10 @@ const resolveNextVersion = (currentVersion, nextVersion, bumpStrategy = "overrid
return resolvedChunks.join(sep);
}

if (bumpStrategy === "override-carret") {
return "^" + nextVersion;
}

// "override"
// By default next package version would be set as is for the all dependants.
return nextVersion;
Expand All @@ -274,10 +278,11 @@ const resolveNextVersion = (currentVersion, nextVersion, bumpStrategy = "overrid
*
* @param {Package} pkg The package this function is being called on.
* @param {boolean} writeOut Commit the package to the file store (set to false to suppres)
* @param {boolean} useCarret Prefix version with carret
* @returns {undefined}
* @internal
*/
const updateManifestDeps = (pkg, writeOut = true) => {
const updateManifestDeps = (pkg, writeOut = true, useCarret = false) => {
const { manifest, path } = pkg;

// Loop through changed deps to verify release consistency.
Expand All @@ -298,7 +303,7 @@ const updateManifestDeps = (pkg, writeOut = true) => {
} = pkg.manifest;
const scopes = [dependencies, devDependencies, peerDependencies, optionalDependencies];
scopes.forEach((scope) => {
if (scope[dependency.name]) scope[dependency.name] = release.version;
if (scope[dependency.name]) scope[dependency.name] = useCarret ? `^${release.version}` : release.version;
});
});

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"license": "0BSD",
"engines": {
"node": ">=10.18",
"yarn": ">=1.0.0"
"yarn": ">=1.0.0",
"npm": "please-use-yarn"
Copy link
Collaborator

Choose a reason for hiding this comment

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

hmm... npm v7+ works with monorepos as well

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, but the repository is using yarn.lock and npm will ignore yarn.lock and create package-lock.json; hence this will remove the advantage of having lock file

Copy link
Collaborator

@antongolub antongolub May 12, 2022

Choose a reason for hiding this comment

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

The idea is clear, but I've never seen this kind of restriction anywhere else) Maybe it would be enough just to add package-lock.json to gitignore instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@antongolub I revert this change

},
"main": "lib/multiSemanticRelease.js",
"bin": {
Expand Down
20 changes: 20 additions & 0 deletions test/fixtures/yarnWorkspacesPackagesCarret/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "msr-test-yarn",
"author": "Dave Houlbrooke <dave@shax.com>",
"version": "0.0.0-semantically-released",
"private": true,
"license": "0BSD",
"engines": {
"node": ">=8.3"
},
"workspaces": {
"packages": ["packages/*"]
},
"release": {
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator"
],
"noCi": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "msr-test-a",
"version": "0.0.0",
"peerDependencies": {
"msr-test-c": "^0.0.0",
"left-pad": "latest"
}
}
11 changes: 11 additions & 0 deletions test/fixtures/yarnWorkspacesPackagesCarret/packages/b/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "msr-test-b",
"version": "0.0.0",
"dependencies": {
"msr-test-a": "^0.0.0"
},
"devDependencies": {
"msr-test-c": "^0.0.0",
"left-pad": "latest"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"tagFormat": "multi-semantic-release-test-c@v${version}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "msr-test-c",
"version": "0.0.0",
"devDependencies": {
"msr-test-b": "^0.0.0",
"msr-test-d": "^0.0.0"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "msr-test-d",
"version": "0.0.0"
}
131 changes: 131 additions & 0 deletions test/lib/multiSemanticRelease.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1431,4 +1431,135 @@ describe("multiSemanticRelease()", () => {
});
});
});
describe.each([
["override-carret", "yarnWorkspacesPackagesCarret"],
["override-carret", "yarnWorkspacesPackages"],
["inherit", "yarnWorkspacesPackagesCarret"],
])("With deps.bump=%s strategy & fixture=%s", (strategy, fixtureName) => {
test("should bump with carret", async () => {
// Create Git repo with copy of Yarn workspaces fixture.
const cwd = gitInit();
copyDirectory(`test/fixtures/${fixtureName}/`, cwd);
const sha = gitCommitAll(cwd, "feat: Initial release");
gitInitOrigin(cwd);
gitPush(cwd);

// Capture output.
const stdout = new WritableStreamBuffer();
const stderr = new WritableStreamBuffer();

// Call multiSemanticRelease()
// Doesn't include plugins that actually publish.
const multiSemanticRelease = require("../../");
const result = await multiSemanticRelease(
[
`packages/a/package.json`,
`packages/b/package.json`,
`packages/c/package.json`,
`packages/d/package.json`,
],
{},
{ cwd, stdout, stderr },
{ deps: { bump: strategy } }
);

// Get stdout and stderr output.
const err = stderr.getContentsAsString("utf8");
expect(err).toBe(false);
const out = stdout.getContentsAsString("utf8");
expect(out).toMatch("Started multirelease! Loading 4 packages...");
expect(out).toMatch("Loaded package msr-test-a");
expect(out).toMatch("Loaded package msr-test-b");
expect(out).toMatch("Loaded package msr-test-c");
expect(out).toMatch("Loaded package msr-test-d");
expect(out).toMatch("Queued 4 packages! Starting release...");
expect(out).toMatch("Created tag msr-test-a@1.0.0");
expect(out).toMatch("Created tag msr-test-b@1.0.0");
expect(out).toMatch("Created tag msr-test-c@1.0.0");
expect(out).toMatch("Created tag msr-test-d@1.0.0");
expect(out).toMatch("Released 4 of 4 packages, semantically!");

// A.
expect(result[0].name).toBe("msr-test-a");
expect(result[0].result.lastRelease).toEqual({});
expect(result[0].result.nextRelease).toMatchObject({
gitHead: sha,
gitTag: "msr-test-a@1.0.0",
type: "minor",
version: "1.0.0",
});
expect(result[0].result.nextRelease.notes).toMatch("# msr-test-a 1.0.0");
expect(result[0].result.nextRelease.notes).toMatch("### Features\n\n* Initial release");
expect(result[0].result.nextRelease.notes).toMatch(
"### Dependencies\n\n* **msr-test-c:** upgraded to 1.0.0"
);

// B.
expect(result[1].name).toBe("msr-test-b");
expect(result[1].result.lastRelease).toEqual({});
expect(result[1].result.nextRelease).toMatchObject({
gitHead: sha,
gitTag: "msr-test-b@1.0.0",
type: "minor",
version: "1.0.0",
});
expect(result[1].result.nextRelease.notes).toMatch("# msr-test-b 1.0.0");
expect(result[1].result.nextRelease.notes).toMatch("### Features\n\n* Initial release");
expect(result[1].result.nextRelease.notes).toMatch(
"### Dependencies\n\n* **msr-test-a:** upgraded to 1.0.0\n* **msr-test-c:** upgraded to 1.0.0"
);

// C.
expect(result[2].name).toBe("msr-test-c");
expect(result[2].result.lastRelease).toEqual({});
expect(result[2].result.nextRelease).toMatchObject({
gitHead: sha,
gitTag: "msr-test-c@1.0.0",
type: "minor",
version: "1.0.0",
});
expect(result[2].result.nextRelease.notes).toMatch("# msr-test-c 1.0.0");
expect(result[2].result.nextRelease.notes).toMatch("### Features\n\n* Initial release");
expect(result[2].result.nextRelease.notes).toMatch(
"### Dependencies\n\n* **msr-test-b:** upgraded to 1.0.0"
);

// D.
expect(result[3].name).toBe("msr-test-d");
expect(result[3].result.lastRelease).toEqual({});
expect(result[3].result.nextRelease).toMatchObject({
gitHead: sha,
gitTag: "msr-test-d@1.0.0",
type: "minor",
version: "1.0.0",
});
expect(result[3].result.nextRelease.notes).toMatch("# msr-test-d 1.0.0");
expect(result[3].result.nextRelease.notes).toMatch("### Features\n\n* Initial release");
expect(result[3].result.nextRelease.notes).not.toMatch("### Dependencies");

// ONLY four times.
expect(result).toHaveLength(4);

// Check manifests.
expect(require(`${cwd}/packages/a/package.json`)).toMatchObject({
peerDependencies: {
"msr-test-c": strategy === "inherit" ? "1.0.0" : "^1.0.0",
},
});
expect(require(`${cwd}/packages/b/package.json`)).toMatchObject({
dependencies: {
"msr-test-a": strategy === "inherit" ? "1.0.0" : "^1.0.0",
},
devDependencies: {
"msr-test-c": strategy === "inherit" ? "1.0.0" : "^1.0.0",
},
});
expect(require(`${cwd}/packages/c/package.json`)).toMatchObject({
devDependencies: {
"msr-test-b": strategy === "inherit" ? "1.0.0" : "^1.0.0",
"msr-test-d": strategy === "inherit" ? "1.0.0" : "^1.0.0",
},
});
});
});
});
Loading