From 6647850423c2376e380236f8fb92e978948304ba Mon Sep 17 00:00:00 2001 From: Ethan Sharabi <1780255+ethanshar@users.noreply.github.com> Date: Tue, 29 Oct 2024 12:15:51 +0200 Subject: [PATCH] Update label-waiting-for-response workflow --- .../workflows/label-waiting-for-response.yml | 150 ++++++++++++++---- 1 file changed, 122 insertions(+), 28 deletions(-) diff --git a/.github/workflows/label-waiting-for-response.yml b/.github/workflows/label-waiting-for-response.yml index f34d940386..825bfec6f8 100644 --- a/.github/workflows/label-waiting-for-response.yml +++ b/.github/workflows/label-waiting-for-response.yml @@ -1,44 +1,138 @@ -name: Label Issues Awaiting User Response +name: Auto Label Issues on: issue_comment: types: [created] + workflow_dispatch: + inputs: + label-all-issues: + description: 'Add label to all open issues' + type: boolean + default: false + required: false jobs: - label-waiting-response: + add-label-single: runs-on: ubuntu-latest + if: | + github.event_name == 'issue_comment' && + github.event.issue.user.login != github.event.comment.user.login + steps: - - name: Check if commenter is a maintainer - uses: actions/github-script@v6 + - name: Check if commenter is maintainer + id: check-maintainer + uses: actions/github-script@v7 with: - github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const issue = context.issue; - const commentAuthor = context.payload.comment.user.login; - - // Get all repository collaborators with 'maintain' or higher permissions - const collaborators = await github.repos.listCollaborators({ - owner: issue.owner, - repo: issue.repo, - affiliation: 'direct', + const response = await github.rest.repos.getCollaboratorPermissionLevel({ + owner: context.repo.owner, + repo: context.repo.repo, + username: context.payload.comment.user.login + }); + + const isMaintianer = ['admin', 'write'].includes(response.data.permission); + return isMaintianer; + + - name: Add waiting-for-response label + if: steps.check-maintainer.outputs.result == 'true' + uses: actions/github-script@v7 + with: + script: | + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + labels: ['waiting-for-response'] }); - // Check if the comment author is a collaborator with maintainer permissions - const isMaintainer = collaborators.data.some(collab => - collab.login === commentAuthor && (collab.permissions.maintain || collab.permissions.admin) - ); + add-label-all: + runs-on: ubuntu-latest + if: | + github.event_name == 'workflow_dispatch' && + github.event.inputs.label-all-issues == 'true' + + steps: + - name: Process all open issues + uses: actions/github-script@v7 + with: + script: | + async function isMaintianer(username) { + try { + const response = await github.rest.repos.getCollaboratorPermissionLevel({ + owner: context.repo.owner, + repo: context.repo.repo, + username: username + }); + return ['admin', 'write'].includes(response.data.permission); + } catch (error) { + console.error(`Error checking permissions for ${username}:`, error); + return false; + } + } - if (isMaintainer) { - // Apply 'waiting-for-response' label if not already present - const labels = await github.issues.listLabelsOnIssue({ - ...issue, - }); - const hasLabel = labels.data.some(label => label.name === 'waiting-for-response'); - - if (!hasLabel) { - await github.issues.addLabels({ - ...issue, - labels: ['waiting-for-response'], + async function getLastComment(issueNumber) { + try { + const comments = await github.paginate(github.rest.issues.listComments, { + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issueNumber, + per_page: 100 }); + + // Return the most recent comment, or null if no comments + return comments.length > 0 ? comments[comments.length - 1] : null; + } catch (error) { + console.error(`Error fetching comments for issue #${issueNumber}:`, error); + return null; } } + + // Get all open issues + const issues = await github.paginate(github.rest.issues.listForRepo, { + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + per_page: 100 + }); + + for (const issue of issues) { + try { + console.log(`Processing issue #${issue.number}...`); + + // Get the last comment + const lastComment = await getLastComment(issue.number); + + // Skip if no comments + if (!lastComment) { + console.log(`No comments found on issue #${issue.number}, skipping`); + continue; + } + + // Check if last commenter is a maintainer + const lastCommenterIsMaintainer = await isMaintianer(lastComment.user.login); + + // Skip if last commenter is not a maintainer + if (!lastCommenterIsMaintainer) { + console.log(`Last comment on issue #${issue.number} is not from a maintainer, skipping`); + continue; + } + + // Skip if last commenter is the issue author + if (lastComment.user.login === issue.user.login) { + console.log(`Last comment on issue #${issue.number} is from the issue author, skipping`); + continue; + } + + // Add the label + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + labels: ['waiting-for-response'] + }); + + console.log(`Added label to issue #${issue.number}`); + } catch (error) { + console.error(`Error processing issue #${issue.number}:`, error); + } + } \ No newline at end of file