name: Comment on an issue on: workflow_run: workflows: - "Check code formatting" - "Check for private emails used in PRs" types: - completed permissions: contents: read jobs: pr-comment: runs-on: ubuntu-latest permissions: pull-requests: write if: > github.event.workflow_run.event == 'pull_request' steps: - name: 'Download artifact' uses: actions/download-artifact@6b208ae046db98c579e8a3aa621ab581ff575935 # v4.1.1 with: github-token: ${{ secrets.ISSUE_WRITE_DOWNLOAD_ARTIFACT }} run-id: ${{ github.event.workflow_run.id }} name: workflow-args - name: 'Comment on PR' uses: actions/github-script@v3 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | var fs = require('fs'); const comments = JSON.parse(fs.readFileSync('./comments')); if (!comments || comments.length == 0) { return; } let runInfo = await github.actions.getWorkflowRun({ owner: context.repo.owner, repo: context.repo.repo, run_id: context.payload.workflow_run.id }); console.log(runInfo); // Query to find the number of the pull request that triggered this job. // The associated pull requests are based off of the branch name, so if // you create a pull request for a branch, close it, and then create // another pull request with the same branch, then this query will return // two associated pull requests. This is why we have to fetch all the // associated pull requests and then iterate through them to find the // one that is open. const gql_query = ` query($repo_owner : String!, $repo_name : String!, $branch: String!) { repository(owner: $repo_owner, name: $repo_name) { ref (qualifiedName: $branch) { associatedPullRequests(first: 100) { nodes { baseRepository { owner { login } } number state } } } } } ` const gql_variables = { repo_owner: runInfo.data.head_repository.owner.login, repo_name: runInfo.data.head_repository.name, branch: runInfo.data.head_branch } const gql_result = await github.graphql(gql_query, gql_variables); console.log(gql_result); // If the branch for the PR was deleted before this job has a chance // to run, then the ref will be null. This can happen if someone: // 1. Rebase the PR, which triggers some workflow. // 2. Immediately merges the PR and deletes the branch. // 3. The workflow finishes and triggers this job. if (!gql_result.repository.ref) { console.log("Ref has been deleted"); return; } console.log(gql_result.repository.ref.associatedPullRequests.nodes); var pr_number = 0; gql_result.repository.ref.associatedPullRequests.nodes.forEach((pr) => { if (pr.baseRepository.owner.login = context.repo.owner && pr.state == 'OPEN') { pr_number = pr.number; } }); if (pr_number == 0) { console.log("Error retrieving pull request number"); return; } await comments.forEach(function (comment) { if (comment.id) { // Security check: Ensure that this comment was created by // the github-actions bot, so a malicious input won't overwrite // a user's comment. github.issues.getComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: comment.id }).then((old_comment) => { console.log(old_comment); if (old_comment.data.user.login != "github-actions[bot]") { console.log("Invalid comment id: " + comment.id); return; } github.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: pr_number, comment_id: comment.id, body: comment.body }); }); } else { github.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: pr_number, body: comment.body }); } }); - name: Dump comments file if: always() run: cat comments