Skip to content

Commit

Permalink
feat(publish): Add --amend flag (#1422)
Browse files Browse the repository at this point in the history
For the CI/CD use case of releasing-per-commit, adding a commit to update
the version number and/or the CHANGELOG, for every merged patch, creates
unnecessary noise. This patch allows us to amend the existing commit with any
new changes, without replacing the message or generating a new commit.

- Added the `--amend` commandline flag to the publish command
- Add an 'amend' flag to the git-commit helper, which translates into
  `--amend --no-edit`.
- Added tests for all the above.
- Updated the README.md flag with the new option.
  • Loading branch information
krotscheck authored and evocateur committed May 29, 2018
1 parent 1116a4a commit ef5f0db
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 2 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ node_js:
env:
global:
- NO_UPDATE_NOTIFIER=1
- NODE_NO_WARNINGS=1

matrix:
fast_finish: true
Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,19 @@ This can be configured in lerna.json, as well:
}
```

#### --amend

```sh
$ lerna publish --amend
# commit message is retained, and `git push` is skipped.
```

When run with this flag, `publish` will perform all changes on the current commit, instead of adding a new one. This is
useful during [Continuous integration (CI)](https://en.wikipedia.org/wiki/Continuous_integration), to reduce the number
of commits in the projects' history.

In order to prevent unintended overwrites, this command will skip `git push`.

#### --allow-branch [glob]

Lerna allows you to specify a glob or an array of globs in your `lerna.json` that your current branch needs to match to be publishable.
Expand Down
1 change: 1 addition & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ shallow_clone: true

environment:
NO_UPDATE_NOTIFIER: "1"
NODE_NO_WARNINGS: "1"
matrix:
- nodejs_version: "10"
- nodejs_version: "8"
Expand Down
15 changes: 15 additions & 0 deletions commands/publish/__tests__/git-commit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,18 @@ test("multiline message", async () => {
expect(subject).toBe("foo");
expect(body).toBe("bar");
});

test("amend", async () => {
const cwd = await initFixture("root-manifest-only");

await fs.outputFile(path.join(cwd, "packages", "pkg-4", "index.js"), "hello");
await execa("git", ["add", "."], { cwd });
await gitCommit(`foo${EOL}${EOL}bar`, { cwd, amend: true });

const subject = await execa.stdout("git", ["log", "-1", "--pretty=format:%s"], { cwd });
const body = await execa.stdout("git", ["log", "-1", "--pretty=format:%b"], { cwd });

// It should ignore any message.
expect(subject).toBe("Init commit");
expect(body).toBe("");
});
29 changes: 29 additions & 0 deletions commands/publish/__tests__/publish-command.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const gitTag = require("@lerna-test/git-tag");
const gitCommit = require("@lerna-test/git-commit");
const initFixture = require("@lerna-test/init-fixture")(__dirname);
const showCommit = require("@lerna-test/show-commit");
const getCommitMessage = require("@lerna-test/get-commit-message");

// file under test
const lernaPublish = require("@lerna-test/command-runner")(require("../command"));
Expand Down Expand Up @@ -169,6 +170,34 @@ describe("PublishCommand", () => {
});
});

describe("--amend", () => {
it("commits changes on the previous commit", async () => {
const testDir = await initFixture("normal");
await lernaPublish(testDir)("--amend");

const message = await getCommitMessage(testDir);
expect(message).toMatch("Init commit");
});

it("ignores custom messages", async () => {
const testDir = await initFixture("normal");
await lernaPublish(testDir)("--message", "chore: Release %v :rocket:", "--amend");

const message = await getCommitMessage(testDir);
expect(message).toMatch("Init commit");
});
});

describe("--amend --independent", () => {
it("commits changes with a custom message", async () => {
const testDir = await initFixture("independent");
await lernaPublish(testDir)("--amend");

const message = await getCommitMessage(testDir);
expect(message).toMatch("Init commit");
});
});

describe("when local clone is behind upstream", () => {
it("throws an error during interactive publish", async () => {
const testDir = await initFixture("normal");
Expand Down
5 changes: 5 additions & 0 deletions commands/publish/command.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ exports.builder = yargs => {
type: "string",
requiresArg: true,
},
amend: {
describe: "Amend the existing commit, instead of generating a new one.",
type: "boolean",
default: false,
},
"npm-tag": {
describe: "Publish packages with the specified npm dist-tag",
type: "string",
Expand Down
6 changes: 5 additions & 1 deletion commands/publish/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,17 @@ class PublishCommand extends Command {
tempTag: false,
yes: false,
allowBranch: false,
amend: false,
});
}

initialize() {
this.gitRemote = this.options.gitRemote || "origin";
this.gitEnabled = !(this.options.canary || this.options.skipGit);

// Set the 'amend' flag so it can be passed to child commands.
this.execOpts.amend = this.options.amend === true;

// https://docs.npmjs.com/misc/config#save-prefix
this.savePrefix = this.options.exact ? "" : "^";

Expand Down Expand Up @@ -205,7 +209,7 @@ class PublishCommand extends Command {
tasks.push(() => this.publishPackagesToNpm());
}

if (this.gitEnabled) {
if (this.gitEnabled && !this.options.amend) {
tasks.push(() => this.pushToRemote());
}

Expand Down
4 changes: 3 additions & 1 deletion commands/publish/lib/git-commit.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ function gitCommit(message, opts) {
log.silly("gitCommit", message);
const args = ["commit", "--no-verify"];

if (message.indexOf(EOL) > -1) {
if (opts && opts.amend === true) {
args.push("--amend", "--no-edit");
} else if (message.indexOf(EOL) > -1) {
// Use tempfile to allow multi\nline strings.
args.push("-F", tempWrite.sync(message, "lerna-commit.txt"));
} else {
Expand Down

0 comments on commit ef5f0db

Please sign in to comment.