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

Call version lifecycle scripts during publish #1029

Merged
merged 2 commits into from
Sep 27, 2017
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
34 changes: 33 additions & 1 deletion src/commands/PublishCommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -536,12 +536,26 @@ export default class PublishCommand extends Command {
this.updatePackageDepsObject(pkg, "devDependencies", exact);
this.updatePackageDepsObject(pkg, "peerDependencies", exact);

// exec preversion script
pkg.runScript("preversion", (err) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

This will run script asynchronously, wouldn't it? Same goes for other hooks that were added.
Are we fine with that?

Copy link
Member

Choose a reason for hiding this comment

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

That’s true. I forgot that almost everything in publish is synchronous, unlike bootstrap where parallelism is important.

if (err) {
this.logger.error("publish", "error running preversion", pkg.name, err);
}
});

// write new package
writePkg.sync(packageJsonLocation, pkg.toJSON());
// NOTE: Object.prototype.toJSON() is normally called when passed to
// JSON.stringify(), but write-pkg iterates Object.keys() before serializing
// so it has to be explicit here (otherwise it mangles the instance properties)

// exec version script
pkg.runScript("version", (err) => {
if (err) {
this.logger.error("publish", "error running version", pkg.name, err);
}
});

// we can now generate the Changelog, based on the
// the updated version that we're about to release.
if (this.options.conventionalCommits) {
Expand Down Expand Up @@ -595,7 +609,7 @@ export default class PublishCommand extends Command {
}

gitCommitAndTagVersionForUpdates() {
const tags = this.updates.map(({ package: { name } }) =>
const tags = this.updates.map(({ "package": { name } }) =>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can back out this change, but package is a reserved keyword and shouldn't be referenced without quotes.

Copy link
Member

Choose a reason for hiding this comment

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

Indeed, good call!

`${name}@${this.updatesVersions[name]}`
);
const subject = this.options.message || "Publish";
Expand All @@ -604,6 +618,15 @@ export default class PublishCommand extends Command {
GitUtilities.commit(message, this.execOpts);
tags.forEach((tag) => GitUtilities.addTag(tag, this.execOpts));

// run the postversion script for each update
this.updates.forEach(({ "package": pkg }) => {
pkg.runScript("postversion", (err) => {
if (err) {
this.logger.error("publish", "error running postversion", pkg.name, err);
}
});
});

return tags;
}

Expand All @@ -614,6 +637,15 @@ export default class PublishCommand extends Command {
GitUtilities.commit(message, this.execOpts);
GitUtilities.addTag(tag, this.execOpts);

// run the postversion script for each update
this.updates.forEach(({ "package": pkg }) => {
pkg.runScript("postversion", (err) => {
if (err) {
this.logger.error("publish", "error running postversion", pkg.name, err);
}
});
});

return tag;
}

Expand Down
44 changes: 44 additions & 0 deletions test/PublishCommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -995,4 +995,48 @@ describe("PublishCommand", () => {
});
});
});

/** =========================================================================
* VERSION LIFECYCLE SCRIPTS
* ======================================================================= */

describe("lifecycle scripts", () => {
let testDir;

const scripts = ["preversion", "version", "postversion"];

beforeEach(async () => {
testDir = await initFixture("PublishCommand/lifecycle");
});

it("should call version lifecycle scripts for a package", async () => {
await run(testDir)();
scripts.forEach(script => {
expect(NpmUtilities.runScriptInDir).toHaveBeenCalledWith(
script,
[],
path.resolve(testDir, "packages", "package-1"),
expect.any(Function)
);
});
});

it("should not call version lifecycle scripts for a package missing them", async () => {
await run(testDir)();
scripts.forEach(script => {
expect(NpmUtilities.runScriptInDir).not.toHaveBeenCalledWith(
script,
[],
path.resolve(testDir, "packages", "package-2"),
expect.any(Function)
);
});
});

it("should call version lifecycle scripts in the correct order", async () => {
await run(testDir)();
expect(NpmUtilities.runScriptInDir.mock.calls.map(args => args[0])).toEqual(scripts);
});
});
});

4 changes: 4 additions & 0 deletions test/fixtures/PublishCommand/lifecycle/lerna.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"lerna": "__TEST_VERSION__",
"version": "1.0.0"
}
3 changes: 3 additions & 0 deletions test/fixtures/PublishCommand/lifecycle/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "lifecycle"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "package-1",
"version": "1.0.0",
"scripts": {
"preversion": "exit 0",
"version": "exit 0",
"postversion": "exit 0",
"prepublishOnly": "exit 0",
"prepublish": "exit 0",
"publish": "exit 0",
"postpublish": "exit 0"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "package-2",
"version": "1.0.0",
"dependencies": {
"package-1": "^1.0.0"
}
}