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

Add --allow-branch option to restrict publish to designated branches #1026

Merged
merged 3 commits into from
Sep 26, 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
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,28 @@ to certain guidelines, such as projects which use [commitizen](https://github.co
If the message contains `%s`, it will be replaced with the new global version version number prefixed with a "v".
Note that this only applies when using the default "fixed" versioning mode, as there is no "global" version when using `--independent`.

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

Lerna allows you to specify a glob in your `lerna.json` that your current branch needs to match to be publishable.
You can use this flag to override this setting.
If your `lerna.json` contains something like this:

```json
{
"command": {
"publish": {
"allowBranch": "master"
}
}
}
```

and you are not on the branch `master` lerna will prevent you from publishing. To force a publish despite this config, pass the `--allow-branch` flag:

```sh
$ lerna publish --allow-branch my-new-feature
```

### updated

```sh
Expand Down
19 changes: 18 additions & 1 deletion src/commands/PublishCommand.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { EOL } from "os";
import async from "async";
import chalk from "chalk";
import dedent from "dedent";
import minimatch from "minimatch";
import path from "path";
import semver from "semver";
import writeJsonFile from "write-json-file";
Expand Down Expand Up @@ -128,7 +130,13 @@ export const builder = {
describe: "Create a temporary tag while publishing.",
type: "boolean",
default: undefined,
}
},
"allow-branch": {
group: "Command Options:",
describe: "Specify which branches to allow publishing from.",
type: "string",
default: undefined,
},
};

export default class PublishCommand extends Command {
Expand All @@ -140,6 +148,7 @@ export default class PublishCommand extends Command {
skipNpm: false,
tempTag: false,
yes: false,
allowBranch: false,
});
}

Expand Down Expand Up @@ -206,6 +215,14 @@ export default class PublishCommand extends Command {
throw new Error("Detached git HEAD, please checkout a branch to publish changes.");
}

const currentBranch = GitUtilities.getCurrentBranch(this.execOpts);
if (this.options.allowBranch && !minimatch(currentBranch, this.options.allowBranch)) {
throw new Error(dedent`
Branch ${currentBranch} is not allowed to be published.
Use --allow-branch ${currentBranch} to override.
`);
}

if (!this.repository.isIndependent() && !this.options.canary) {
this.updateVersionInLernaJson();
}
Expand Down
61 changes: 61 additions & 0 deletions test/PublishCommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -934,4 +934,65 @@ describe("PublishCommand", () => {
});
});
});


describe('allow branch', () => {
describe("cli", () => {
let testDir;

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

it("should reject a non matching branch", async () => {
try {
await run(testDir)("--allow-branch", "develop");
} catch (err) {
expect(err).toEqual(expect.stringMatching(/not allowed to be published/));
}
});

it("should accept an exactly matching branch", async () => {
expect(await run(testDir)("--allow-branch", "master")).toEqual(
expect.objectContaining({ exitCode: 0 })
);
});

it("should accept a branch that matches by wildcard", async () => {
GitUtilities.getCurrentBranch.mockReturnValueOnce("feature/awesome");
expect(await run(testDir)("--allow-branch", "feature/*")).toEqual(
expect.objectContaining({ exitCode: 0 })
);
});
});

describe("lerna.json", () => {
let testDir;

beforeEach(async () => {
testDir = await initFixture("PublishCommand/allow-branch-lerna");
});

it("should reject a non matching branch", async () => {
try {
await run(testDir)();
} catch (err) {
expect(err).toEqual(expect.stringMatching(/not allowed to be published/));
}
});

it("should accept a matching branch", async () => {
GitUtilities.getCurrentBranch.mockReturnValueOnce("lerna");
expect(await run(testDir)()).toEqual(
expect.objectContaining({ exitCode: 0 })
);
});

it("should prioritize cli over defaults", async () => {
expect(await run(testDir)("--allow-branch", "master")).toEqual(
expect.objectContaining({ exitCode: 0 })
);
});
});
});
});
9 changes: 9 additions & 0 deletions test/fixtures/PublishCommand/allow-branch-lerna/lerna.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"lerna": "__TEST_VERSION__",
"version": "1.0.0",
"command": {
"publish": {
"allowBranch": "lerna"
}
}
}
3 changes: 3 additions & 0 deletions test/fixtures/PublishCommand/allow-branch-lerna/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "allow-branch-lerna"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "package-1",
"version": "1.0.0"
}