From 79dfea8dc827e7f9b44ed6468d012c60da1f0888 Mon Sep 17 00:00:00 2001 From: Hannes Ljungberg Date: Tue, 26 Nov 2019 13:31:26 +0100 Subject: [PATCH] Add support for creating statuses --- README.md | 12 +++++++++++- action.yml | 8 ++++++++ src/action.js | 30 +++++++++++++++++++++++++++++- src/action.test.js | 29 +++++++++++++++++++++++++++-- 4 files changed, 75 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a7f41b67..83392a54 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,17 @@ Sets if a PR should just be commented upon or approved and request changes depen The label to add to the release PR. Set to an empty string to disable. Defaults to `release`. -**Note**: Make sure that the label exists. + +### `create_status` + +Sets if a [GitHub status](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-status-checks) should +be created by the action. This is useful when wanting to restrict merging until the action runs successfully. Since GitHub creates a +check on the PR for every PR event that triggers the action isn't useful to restrict merging by the action checks. Instead use this status specified by `status_name`. +Defaults to `true`. + +### `status_name` + +The name of the status created when `create_status` is set to `true`. Defaults to `Monkey Release`. ## Outputs diff --git a/action.yml b/action.yml index 564e7dda..544a8a43 100644 --- a/action.yml +++ b/action.yml @@ -12,6 +12,14 @@ inputs: description: 'Name of the head branch' required: true default: 'dev' + create_status: + description: 'If the action state should be created as a status' + required: true + default: true + status_name: + description: 'Name of the status created by this action' + required: true + default: 'Monkey Release' release_pattern: description: | 'Pattern to validate title against. diff --git a/src/action.js b/src/action.js index c1397806..12923b23 100644 --- a/src/action.js +++ b/src/action.js @@ -163,7 +163,6 @@ async function addLabel(pullRequest) { if (pullRequest.labels && pullRequest.labels.includes(releaseLabel)) { return; } - // TODO: Handle missing label? await client.issues.addLabels({ issue_number: pullRequest.number, labels: [releaseLabel], @@ -197,6 +196,34 @@ async function review(pullRequest, event, comment) { event: event, ...github.context.repo }); + // Set status on commit + await setStatus( + pullRequest, + event === REVIEW_APPROVE ? STATUS_SUCCESS : STATUS_FAILURE, + comment + ); +} + +const STATUS_FAILURE = "failure"; +const STATUS_SUCCESS = "success"; + +async function setStatus(pullRequest, state, description) { + core.info(`Setting status ${state}..`); + const createStatus = JSON.parse( + core.getInput("create_status", { required: true }) + ); + + if (!createStatus) { + return; + } + const context = core.getInput("status_name", { required: true }); + await client.repos.createStatus({ + state, + description, + context, + sha: pullRequest.head.sha, + ...github.context.repo + }); } async function release(pullRequest) { @@ -233,5 +260,6 @@ module.exports = { addLabel, review, release, + setStatus, ValidationError }; diff --git a/src/action.test.js b/src/action.test.js index 7675508e..db921540 100644 --- a/src/action.test.js +++ b/src/action.test.js @@ -19,16 +19,19 @@ test("validate", async () => { process.env["INPUT_HEAD_BRANCH"] = "dev"; process.env["INPUT_RELEASE_LABEL"] = "Release"; process.env["INPUT_TAG_PREFIX"] = "release/"; + process.env["INPUT_CREATE_STATUS"] = "true"; + process.env["INPUT_STATUS_NAME"] = "Monkey Release"; const currentDate = moment.utc(new Date()).format("YYYY.MM.DD-1"); const prNumber = "1"; const tag = `release/${currentDate}`; + const headSha = "deadbeef"; const pullRequest = { number: prNumber, title: currentDate, body: "mybody", labels: [], base: { ref: "master" }, - head: { ref: "dev" } + head: { ref: "dev", sha: headSha } }; nock("https://api.github.com") .persist() @@ -36,6 +39,8 @@ test("validate", async () => { .reply(200) .post(`/repos/${owner}/${repo}/pulls/${prNumber}/reviews`) .reply(200) + .post(`/repos/${owner}/${repo}/statuses/${headSha}`) + .reply(200) .get(`/repos/${owner}/${repo}/releases/tags/${tag}`) .reply(404); @@ -90,11 +95,17 @@ test("addLabel", async () => { test("review", async () => { const { review } = require("./action"); + + process.env["INPUT_CREATE_STATUS"] = "true"; + process.env["INPUT_STATUS_NAME"] = "Monkey Release"; const prNumber = "5"; + const headSha = "deadbeef"; nock("https://api.github.com") .post(`/repos/${owner}/${repo}/pulls/${prNumber}/reviews`) + .reply(200) + .post(`/repos/${owner}/${repo}/statuses/${headSha}`) .reply(200); - await review({ number: prNumber }, "APPROVE", "LGTM"); + await review({ number: prNumber, head: { sha: headSha } }, "APPROVE", "LGTM"); }); test("release", async () => { @@ -232,3 +243,17 @@ test("validateRelease", async () => { .reply(500); await expect(validateRelease({ title: "hejhej" })).rejects.toThrow(Error); }); + +test("setStatus", async () => { + const { setStatus } = require("./action"); + + process.env["INPUT_CREATE_STATUS"] = "true"; + process.env["INPUT_STATUS_NAME"] = "Monkey Release"; + const headSha = "deadbeef"; + nock("https://api.github.com") + .post(`/repos/${owner}/${repo}/statuses/${headSha}`) + .reply(200); + await setStatus({ head: { sha: headSha } }, "success", "LGTM"); + process.env["INPUT_CREATE_STATUS"] = "false"; + await setStatus({ head: { sha: headSha } }, "success", "LGTM"); +});