Skip to content

Commit

Permalink
Option to add a comment on failure (#36)
Browse files Browse the repository at this point in the history
  • Loading branch information
mheap committed Oct 20, 2022
1 parent a0c3d80 commit 4ae53dd
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 6 deletions.
11 changes: 11 additions & 0 deletions README.md
Expand Up @@ -65,6 +65,17 @@ To force an API call, set the `GITHUB_TOKEN` environment variable like so:
labels: "do not merge"
```

### Post a comment when the check fails

```yaml
- uses: mheap/github-action-required-labels@v2
with:
mode: exactly
count: 1
labels: "semver:patch, semver:minor, semver:major"
add_comment: true
```

### Require multiple labels

```yaml
Expand Down
4 changes: 4 additions & 0 deletions action.yml
Expand Up @@ -16,6 +16,10 @@ inputs:
count:
description: "The required number of labels to match"
required: true
comment:
description: "Add a comment to the PR if required labels are missing"
default: "false"
required: false
exit_type:
description: "The exit type of the action. One of: failure, success, neutral"
required: false
32 changes: 26 additions & 6 deletions index.js
Expand Up @@ -55,8 +55,9 @@ Toolkit.run(async (tools) => {
let intersection = allowedLabels.filter((x) => appliedLabels.includes(x));

if (mode === "exactly" && intersection.length !== count) {
tools.outputs.status = "failure";
tools.exit[exitType](
await exitWithError(
tools,
exitType,
`Label error. Requires exactly ${count} of: ${allowedLabels.join(
", "
)}. Found: ${appliedLabels.join(", ")}`
Expand All @@ -65,8 +66,9 @@ Toolkit.run(async (tools) => {
}

if (mode === "minimum" && intersection.length < count) {
tools.outputs.status = "failure";
tools.exit[exitType](
await exitWithError(
tools,
exitType,
`Label error. Requires at least ${count} of: ${allowedLabels.join(
", "
)}. Found: ${appliedLabels.join(", ")}`
Expand All @@ -75,8 +77,9 @@ Toolkit.run(async (tools) => {
}

if (mode === "maximum" && intersection.length > count) {
tools.outputs.status = "failure";
tools.exit[exitType](
await exitWithError(
tools,
exitType,
`Label error. Requires at most ${count} of: ${allowedLabels.join(
", "
)}. Found: ${appliedLabels.join(", ")}`
Expand All @@ -87,3 +90,20 @@ Toolkit.run(async (tools) => {
tools.outputs.status = "success";
tools.exit.success("Complete");
});

async function exitWithError(tools, exitType, message) {
if (tools.inputs.add_comment) {
if (process.env.GITHUB_TOKEN) {
await tools.github.issues.createComment({
...tools.context.issue,
body: message,
});
} else {
throw new Error(
"The GITHUB_TOKEN environment variable must be set to add a comment"
);
}
}
tools.outputs.status = "failure";
tools.exit[exitType](message);
}
78 changes: 78 additions & 0 deletions index.test.js
@@ -1,6 +1,8 @@
const { Toolkit } = require("actions-toolkit");
const core = require("@actions/core");
const mockedEnv = require("mocked-env");
const nock = require("nock");
nock.disableNetConnect();

describe("Required Labels", () => {
let action, tools;
Expand Down Expand Up @@ -44,6 +46,82 @@ describe("Required Labels", () => {
restore();
restoreTest();
jest.resetModules();

if (!nock.isDone()) {
throw new Error(
`Not all nock interceptors were used: ${JSON.stringify(
nock.pendingMocks()
)}`
);
}
nock.cleanAll();
});

describe("interacts with the API", () => {
it("fetches the labels from the API", async () => {
restoreTest = mockPr(tools, [], {
INPUT_LABELS: "enhancement",
INPUT_MODE: "exactly",
INPUT_COUNT: "1",
GITHUB_TOKEN: "mock-token-here-abc",
});

nock("https://api.github.com")
.get("/repos/mheap/missing-repo/issues/28/labels")
.reply(200, [{ name: "enhancement" }, { name: "bug" }]);

await action(tools);
expect(core.setOutput).toBeCalledTimes(1);
expect(core.setOutput).toBeCalledWith("status", "success");
expect(tools.exit.success).toBeCalledTimes(1);
expect(tools.exit.success).toBeCalledWith("Complete");
});

it("fetches the labels from the API (and fails)", async () => {
restoreTest = mockPr(tools, ["enhancement"], {
INPUT_LABELS: "enhancement",
INPUT_MODE: "exactly",
INPUT_COUNT: "1",
GITHUB_TOKEN: "mock-token-here-abc",
});

nock("https://api.github.com")
.get("/repos/mheap/missing-repo/issues/28/labels")
.reply(200, [{ name: "bug" }]);

await action(tools);
expect(core.setOutput).toBeCalledTimes(1);
expect(core.setOutput).toBeCalledWith("status", "failure");
expect(tools.exit.failure).toBeCalledTimes(1);
expect(tools.exit.failure).toBeCalledWith(
"Label error. Requires exactly 1 of: enhancement. Found: bug"
);
});

it("posts a comment when enabled", async () => {
restoreTest = mockPr(tools, ["enhancement"], {
INPUT_LABELS: "enhancement",
INPUT_MODE: "exactly",
INPUT_COUNT: "1",
INPUT_ADD_COMMENT: "true",
GITHUB_TOKEN: "mock-token-here-abc",
});

nock("https://api.github.com")
.get("/repos/mheap/missing-repo/issues/28/labels")
.reply(200, [{ name: "bug" }]);

nock("https://api.github.com")
.post("/repos/mheap/missing-repo/issues/28/comments", {
body: "Label error. Requires exactly 1 of: enhancement. Found: bug",
})
.reply(201);

await action(tools);
expect(tools.exit.failure).toBeCalledWith(
"Label error. Requires exactly 1 of: enhancement. Found: bug"
);
});
});

describe("success", () => {
Expand Down
67 changes: 67 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Expand Up @@ -15,6 +15,7 @@
},
"devDependencies": {
"jest": "^28.1.1",
"nock": "^13.2.9",
"prettier": "^2.7.1"
},
"license": "MIT"
Expand Down

0 comments on commit 4ae53dd

Please sign in to comment.