From 8156efe75c98ef4c759665fa01bb681fa3b635f0 Mon Sep 17 00:00:00 2001 From: Zach Himsel Date: Wed, 31 May 2023 11:58:57 -0400 Subject: [PATCH 1/2] Support running multiple instances without collision This uses a combination of three Github-set env vars that, together, are guaranteed to be unique within the scope of a repo and all its workflows: - GITHUB_WORKFLOW: the name of the workflow (or file path, if no name is given) - GITHUB_JOB: the ID of the job - GITHUB_ACTION: the ID of the step (or a formatted name of the repo where the action resides, i.e. `__mheap_github-action-required-labels`) Without this, running multiple instances of this action with comments enabled would result in them clobbering each others' comments. --- README.md | 6 ++++++ index.js | 10 +++++++++- index.test.js | 4 +++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0939b60..1dabaa6 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,12 @@ The following tokens are available for use in custom messages: labels: "community-reviewed, team-reviewed, codeowner-reviewed" ``` +### Preventing comment collisions + +This action uses a combination of the workflow name/path, job ID, and step ID to add an invisible "match token" to the beginning of any comments it creates. That way, it can later know which comments it owns when modifying them, while supporting multiple "instances" of this action to be run at the same time within a repo. + +However, note that if any of those three identifiers change, any "in flight" comments on open PRs may be orphaned (since the final match token will have changed between runs). If you rename any of those identifiers, you will have to delete any orphaned comments manually. + ### Controlling failure You can set `exit_type` to success then inspect `outputs.status` to see if the action passed or failed. This is useful when you want to perform additional actions if a label is not present, but not fail the entire build. diff --git a/index.js b/index.js index 362569d..21eb9d8 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,15 @@ const core = require("@actions/core"); const github = require("@actions/github"); -const matchToken = `\n`; +// Use a guaranteed-unique (but persistent) string to match "our" comment +// https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables +const matchTokenId = [ + process.env.GITHUB_WORKFLOW, + process.env.GITHUB_JOB, + process.env.GITHUB_ACTION, +].join('/'); +const matchToken = `\n`; + async function action() { try { const token = core.getInput("token", { required: true }); diff --git a/index.test.js b/index.test.js index c9342e4..91c6e2a 100644 --- a/index.test.js +++ b/index.test.js @@ -6,7 +6,8 @@ const mockedEnv = require("mocked-env"); const nock = require("nock"); nock.disableNetConnect(); -const matchToken = `\n`; +// note: these need to match the mocked env vars below +const matchToken = `\n`; describe("Required Labels", () => { let restore; @@ -14,6 +15,7 @@ describe("Required Labels", () => { beforeEach(() => { restore = mockedEnv({ GITHUB_WORKFLOW: "demo-workflow", + GITHUB_JOB: "demo-job", GITHUB_ACTION: "required-labels", GITHUB_ACTOR: "mheap", GITHUB_REPOSITORY: "mheap/missing-repo", From 8a9dc86927143036b74cfde9b945f8bcb6cb4dbc Mon Sep 17 00:00:00 2001 From: Michael Heap Date: Thu, 8 Jun 2023 17:19:56 +0100 Subject: [PATCH 2/2] Generate matchToken inside action() --- index.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/index.js b/index.js index 21eb9d8..8326ff8 100644 --- a/index.js +++ b/index.js @@ -1,16 +1,18 @@ const core = require("@actions/core"); const github = require("@actions/github"); -// Use a guaranteed-unique (but persistent) string to match "our" comment -// https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables -const matchTokenId = [ - process.env.GITHUB_WORKFLOW, - process.env.GITHUB_JOB, - process.env.GITHUB_ACTION, -].join('/'); -const matchToken = `\n`; - +let matchToken; async function action() { + // Use a guaranteed-unique (but persistent) string to match "our" comment + // https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables + const matchTokenId = [ + process.env.GITHUB_WORKFLOW, + process.env.GITHUB_JOB, + process.env.GITHUB_ACTION, + ].join("/"); + + matchToken = `\n`; + try { const token = core.getInput("token", { required: true }); const octokit = github.getOctokit(token);