160 lines · yaml
1name: Comment on an issue2 3on:4 workflow_run:5 workflows:6 - "Check code formatting"7 - "Check for private emails used in PRs"8 - "PR Request Release Note"9 - "Code lint"10 - "CI Checks"11 types:12 - completed13 14permissions:15 contents: read16 17jobs:18 pr-comment:19 runs-on: ubuntu-24.0420 permissions:21 pull-requests: write22 if: >23 github.event.workflow_run.event == 'pull_request' &&24 (25 github.event.workflow_run.conclusion == 'success' ||26 github.event.workflow_run.conclusion == 'failure'27 )28 steps:29 - name: Fetch Sources30 uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.031 with:32 sparse-checkout: |33 .github/workflows/unprivileged-download-artifact/action.yml34 sparse-checkout-cone-mode: false35 - name: 'Download artifact'36 uses: ./.github/workflows/unprivileged-download-artifact37 id: download-artifact38 with:39 run-id: ${{ github.event.workflow_run.id }}40 artifact-name: workflow-args41 42 - name: 'Comment on PR'43 if: steps.download-artifact.outputs.artifact-id != ''44 uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.045 with:46 github-token: ${{ secrets.GITHUB_TOKEN }}47 script: |48 var fs = require('fs');49 const comments = JSON.parse(fs.readFileSync('./comments'));50 if (!comments || comments.length == 0) {51 return;52 }53 54 let runInfo = await github.rest.actions.getWorkflowRun({55 owner: context.repo.owner,56 repo: context.repo.repo,57 run_id: context.payload.workflow_run.id58 });59 60 console.log(runInfo);61 62 63 // Query to find the number of the pull request that triggered this job.64 // The associated pull requests are based off of the branch name, so if65 // you create a pull request for a branch, close it, and then create66 // another pull request with the same branch, then this query will return67 // two associated pull requests. This is why we have to fetch all the68 // associated pull requests and then iterate through them to find the69 // one that is open.70 const gql_query = `71 query($repo_owner : String!, $repo_name : String!, $branch: String!) {72 repository(owner: $repo_owner, name: $repo_name) {73 ref (qualifiedName: $branch) {74 associatedPullRequests(first: 100) {75 nodes {76 baseRepository {77 owner {78 login79 }80 }81 number82 state83 }84 }85 }86 }87 }88 `89 const gql_variables = {90 repo_owner: runInfo.data.head_repository.owner.login,91 repo_name: runInfo.data.head_repository.name,92 branch: runInfo.data.head_branch93 }94 const gql_result = await github.graphql(gql_query, gql_variables);95 console.log(gql_result);96 // If the branch for the PR was deleted before this job has a chance97 // to run, then the ref will be null. This can happen if someone:98 // 1. Rebase the PR, which triggers some workflow.99 // 2. Immediately merges the PR and deletes the branch.100 // 3. The workflow finishes and triggers this job.101 if (!gql_result.repository.ref) {102 console.log("Ref has been deleted");103 return;104 }105 console.log(gql_result.repository.ref.associatedPullRequests.nodes);106 107 var pr_number = 0;108 gql_result.repository.ref.associatedPullRequests.nodes.forEach((pr) => {109 110 // The largest PR number is the one we care about. The only way111 // to have more than one associated pull requests is if all the112 // old pull requests are in the closed state.113 if (pr.baseRepository.owner.login = context.repo.owner && pr.number > pr_number) {114 pr_number = pr.number;115 }116 });117 if (pr_number == 0) {118 console.log("Error retrieving pull request number");119 return;120 }121 122 await comments.forEach(function (comment) {123 if (comment.id) {124 // Security check: Ensure that this comment was created by125 // the github-actions bot, so a malicious input won't overwrite126 // a user's comment.127 github.rest.issues.getComment({128 owner: context.repo.owner,129 repo: context.repo.repo,130 comment_id: comment.id131 }).then((old_comment) => {132 console.log(old_comment);133 if (old_comment.data.user.login != "github-actions[bot]") {134 console.log("Invalid comment id: " + comment.id);135 return;136 }137 github.rest.issues.updateComment({138 owner: context.repo.owner,139 repo: context.repo.repo,140 issue_number: pr_number,141 comment_id: comment.id,142 body: comment.body143 });144 });145 } else {146 github.rest.issues.createComment({147 owner: context.repo.owner,148 repo: context.repo.repo,149 issue_number: pr_number,150 body: comment.body151 });152 }153 });154 155 - name: Dump comments file156 if: >-157 always() &&158 steps.download-artifact.outputs.artifact-id != ''159 run: cat comments160