Skip to content

Commit ed25e74

Browse files
committed
Add --exists $LABEL to label command
This allows CI builds to check for existence of a label without grepping for text in the label output.
1 parent 16ef1a7 commit ed25e74

7 files changed

Lines changed: 60 additions & 4 deletions

File tree

docs/pages/blog/using-shipit.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ For example,. the following will only run the test:visual script when the PR has
5858
```bash
5959
export PATH=$(npm bin):$PATH
6060

61-
if [ `auto label --pr $PR_NUMBER | grep -c '^Visual'` -ne 0 ];
61+
if auto label --pr $PR_NUMBER --exists Visual;
6262
then
6363
npm run test:visual
6464
fi

docs/pages/docs/extras/label.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ The following will only run the test:visual script when the PR has has the
66
```bash
77
export PATH=$(npm bin):$PATH
88

9-
if [ auto label --pr $PR_NUMBER | grep -c '^Visual' -ne 0 ];
9+
if auto label --pr $PR_NUMBER --exists Visual;
1010
then
1111
npm run test:visual
1212
fi

packages/cli/src/parse-args.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,12 @@ export const commands: AutoCommand[] = [
272272
"Get the labels for a pull request. Doesn't do much, but the return value lets you write you own scripts based off of the PR labels!",
273273
options: [
274274
{ ...pr, description: `${pr.description} (defaults to last merged PR)` },
275+
{
276+
name: "exists",
277+
type: String,
278+
group: "main",
279+
description: "Checks for existence of a specific label",
280+
},
275281
],
276282
examples: ["{green $} auto label --pr 123"],
277283
},

packages/cli/src/run.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import Auto, {
1515
IShipItOptions,
1616
IVersionOptions,
1717
INextOptions,
18+
LabelExistsError,
1819
} from "@auto-it/core";
1920
import endent from "endent";
2021
import on from "await-to-js";
@@ -115,7 +116,7 @@ export async function run(command: string, args: ApiOptions) {
115116
`);
116117
console.log("");
117118
auto.logger.verbose.error(error);
118-
} else {
119+
} else if (!(error instanceof LabelExistsError)) {
119120
console.log(error);
120121
}
121122

packages/core/src/__tests__/auto.test.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,33 @@ describe("Auto", () => {
314314
expect(console.log).toHaveBeenCalledWith("foo");
315315
});
316316

317+
test("should check for a given label", async () => {
318+
const auto = new Auto(defaults);
319+
auto.logger = dummyLog();
320+
await auto.loadConfig();
321+
322+
const getLabels = jest.fn();
323+
auto.git!.getLabels = getLabels;
324+
getLabels.mockReturnValueOnce(["foo"]);
325+
jest.spyOn(console, "log").mockImplementation();
326+
327+
await auto.label({ pr: 13, exists: "foo" });
328+
expect(console.log).toHaveBeenCalledWith("foo");
329+
});
330+
331+
test("should throw if a check for a label fails", async () => {
332+
const auto = new Auto(defaults);
333+
auto.logger = dummyLog();
334+
await auto.loadConfig();
335+
336+
const getLabels = jest.fn();
337+
auto.git!.getLabels = getLabels;
338+
getLabels.mockReturnValueOnce(["bar"]);
339+
jest.spyOn(console, "log").mockImplementation();
340+
341+
await expect(auto.label({ pr: 13, exists: "foo" })).rejects.toThrow();
342+
});
343+
317344
test("should get labels for last merged PR", async () => {
318345
const auto = new Auto(defaults);
319346
auto.logger = dummyLog();

packages/core/src/auto-args.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ export interface ICreateLabelsOptions {
1414
export interface ILabelOptions {
1515
/** PR to get the labels for */
1616
pr?: number;
17+
18+
/** Label to check for */
19+
exists?: string;
1720
}
1821

1922
export interface IPRCheckOptions {

packages/core/src/auto.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,17 @@ function escapeRegExp(str: string) {
303303
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
304304
}
305305

306+
/** The Error that gets thrown when a label existence check fails */
307+
export class LabelExistsError extends Error {
308+
/**
309+
* @param label - the label we were checking existence for
310+
*/
311+
constructor(label: string) {
312+
super(`The label ${label} does not exist`);
313+
Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain
314+
}
315+
}
316+
306317
/**
307318
* The "auto" node API. Its public interface matches the
308319
* commands you can run from the CLI
@@ -751,7 +762,7 @@ export default class Auto {
751762
/**
752763
* Get the labels on a specific PR. Defaults to the labels of the last merged PR
753764
*/
754-
async label({ pr }: ILabelOptions = {}) {
765+
async label({ pr, exists }: ILabelOptions = {}) {
755766
if (!this.git) {
756767
throw this.createErrorMessage();
757768
}
@@ -779,6 +790,14 @@ export default class Auto {
779790
}
780791
}
781792

793+
if (exists) {
794+
if (labels.indexOf(exists) === -1) {
795+
throw new LabelExistsError(exists);
796+
}
797+
798+
return;
799+
}
800+
782801
if (labels.length) {
783802
console.log(labels.join("\n"));
784803
}

0 commit comments

Comments
 (0)