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..8326ff8 100644 --- a/index.js +++ b/index.js @@ -1,8 +1,18 @@ const core = require("@actions/core"); const github = require("@actions/github"); -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); 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",