From be104087f374beaf814b7e0bb873c0e8633a984c Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 22 Apr 2024 18:48:52 +0200 Subject: [PATCH] Find the `/git-artifacts` comment even yet more reliably It _has_ happened in the past that multiple `/git-artifacts` calls were required until things worked, e.g. https://github.com/git-for-windows/git/pull/4330#issuecomment-1458893794 which did not work and was followed by https://github.com/git-for-windows/git/pull/4330#issuecomment-1458894252 which also did not work, and was followed by https://github.com/git-for-windows/git/pull/4330#issuecomment-1458894252 which pretended to work, but didn't, and was followed by https://github.com/git-for-windows/git/pull/4330#issuecomment-1458896122 which suceeded, at long last, to produce the Git Artifacts. So let's make extra sure that we are finding the correct `/git-artifacts` comment to amend. Signed-off-by: Johannes Schindelin --- GitForWindowsHelper/cascading-runs.js | 9 ++++++++- GitForWindowsHelper/issues.js | 27 +++++++++++++++++++++++++-- __tests__/index.test.js | 5 +++-- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/GitForWindowsHelper/cascading-runs.js b/GitForWindowsHelper/cascading-runs.js index 8a1866f..6bd5087 100644 --- a/GitForWindowsHelper/cascading-runs.js +++ b/GitForWindowsHelper/cascading-runs.js @@ -118,7 +118,14 @@ const cascadingRuns = async (context, req) => { const token = await getToken(context, checkRunOwner, checkRunRepo) const { getGitArtifactsCommentID, appendToIssueComment } = require('./issues') - const gitArtifactsCommentID = await getGitArtifactsCommentID(context, token, checkRunOwner, checkRunRepo, req.body.check_run.head_sha) + const gitArtifactsCommentID = await getGitArtifactsCommentID( + context, + token, + checkRunOwner, + checkRunRepo, + req.body.check_run.head_sha, + checkRun.details_url, + ) if (gitArtifactsCommentID) { await appendToIssueComment(context, token, checkRunOwner, checkRunRepo, gitArtifactsCommentID, comment) diff --git a/GitForWindowsHelper/issues.js b/GitForWindowsHelper/issues.js index 78696ed..5b1db94 100644 --- a/GitForWindowsHelper/issues.js +++ b/GitForWindowsHelper/issues.js @@ -23,14 +23,14 @@ const getIssueComment = async (context, token, owner, repo, comment_id) => { return await sendGitHubAPIRequest(context, token, 'GET', `/repos/${owner}/${repo}/issues/comments/${comment_id}`) } -const getGitArtifactsCommentID = async (context, token, owner, repo, headSHA) => { +const getGitArtifactsCommentID = async (context, token, owner, repo, headSHA, tagGitWorkflowRunURL) => { const answer = await sendGitHubAPIRequest(context, token, 'GET', `/search/issues?q=repo:${owner}/${repo}+${headSHA}+type:pr+%22git-artifacts%22`, null, { Accept: 'application/vnd.github.text-match+json' }) let commentID = false for (const item of answer.items) { for (const text_match of item.text_matches) { - if (text_match.fragment.startsWith('/git-artifacts\n\nThe tag-git workflow run was started')) { + if (text_match.fragment.startsWith('/git-artifacts')) { if (commentID !== false) return false // more than one match, maybe a trickster at play, ignore altogether else { commentID = text_match.object_url.replace(/^.*\/(\d+)$/, '$1') @@ -39,6 +39,29 @@ const getGitArtifactsCommentID = async (context, token, owner, repo, headSHA) => } } } + if (commentID === false) return false + + // ensure that this is the correct comment; It should contain the URL of the actual tag-git workflow run + const comment = await getIssueComment(context, token, owner, repo, commentID) + if (!comment) return false + const needle = `The \`tag-git\` workflow run [was started](${tagGitWorkflowRunURL})` + if (comment.body.includes(needle)) return commentID + + // nope, so let's look for other comments on the same PR + commentID = false + const comments = await sendGitHubAPIRequest( + context, + token, + 'GET', + `/repos/${owner}/${repo}/issues/${comment.issue_url.replace(/^.*\/(\d+)$/, '$1')}/comments` + ) + for (const comment2 of comments) { + if (comment2.body.startsWith(`/git-artifacts`) && comment2.body.includes(needle)) { + if (commentID !== false) return false // more than one match, maybe a trickster at play, ignore altogether + commentID = comment2.id + } + } + return commentID } diff --git a/__tests__/index.test.js b/__tests__/index.test.js index 3562813..bde187f 100644 --- a/__tests__/index.test.js +++ b/__tests__/index.test.js @@ -150,12 +150,12 @@ let mockGitHubApiRequest = jest.fn((_context, _token, method, requestPath, paylo }] } if (method === 'GET' && requestPath === '/repos/git-for-windows/git/issues/comments/1450703020') return { - body: '/git-artifacts\n\nThe tag-git workflow run [was started](https://url-to-tag-git/)' + body: '/git-artifacts\n\nThe `tag-git` workflow run [was started](https://url-to-tag-git/)' } if (method === 'PATCH' && requestPath === '/repos/git-for-windows/git/issues/comments/1450703020') { expect(payload.body).toEqual(`/git-artifacts -The tag-git workflow run [was started](https://url-to-tag-git/) +The \`tag-git\` workflow run [was started](https://url-to-tag-git/) git-artifacts-x86_64 run already exists at . The \`git-artifacts-i686\` workflow run [was started](dispatched-workflow-git-artifacts.yml). @@ -635,6 +635,7 @@ test('a completed `tag-git` run triggers `git-artifacts` runs', async () => { name: 'tag-git', head_sha: 'c8edb521bdabec14b07e9142e48cab77a40ba339', conclusion: 'success', + details_url: 'https://url-to-tag-git/', output: { title: 'Tag Git v2.40.0-rc1.windows.1 @c8edb521bdabec14b07e9142e48cab77a40ba339', summary: 'Tag Git v2.40.0-rc1.windows.1 @c8edb521bdabec14b07e9142e48cab77a40ba339',