name: Comment on an issue

on:
  workflow_run:
    workflows:
      - "Check code formatting"
      - "Check for private emails used in PRs"
      - "PR Request Release Note"
      - "Code lint"
      - "CI Checks"
      - "Test Issue Write"
      - "Check LLVM ABI annotations"
    types:
      - completed

permissions:
  contents: read

jobs:
  pr-comment:
    runs-on: ubuntu-24.04
    permissions:
      pull-requests: write
    if: >
      github.event.workflow_run.event == 'pull_request' &&
      (
        github.event.workflow_run.conclusion == 'success' ||
        github.event.workflow_run.conclusion == 'failure'
      )
    steps:
      - name: Fetch Sources
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
          sparse-checkout: |
            .github/workflows/unprivileged-download-artifact/action.yml
          sparse-checkout-cone-mode: false
      - name: 'Download artifact'
        uses: ./.github/workflows/unprivileged-download-artifact
        id: download-artifact
        with:
          run-id: ${{ github.event.workflow_run.id }}
          artifact-name: workflow-args

      - name: 'Comment on PR'
        if: steps.download-artifact.outputs.artifact-ids != ''
        uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            var fs = require('fs');
            var comments = []
            for (local_file of fs.readdirSync('.')) {
              if (local_file.startsWith("comments")) {
                comments.push(...JSON.parse(fs.readFileSync(local_file)))
              }
            }
            if (!comments || comments.length == 0) {
              return;
            }

            let runInfo = await github.rest.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) => {

              // The largest PR number is the one we care about.  The only way
              // to have more than one associated pull requests is if all the
              // old pull requests are in the closed state.
              if (pr.baseRepository.owner.login = context.repo.owner && pr.number > pr_number) {
                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.rest.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.rest.issues.updateComment({
                    owner: context.repo.owner,
                    repo: context.repo.repo,
                    issue_number: pr_number,
                    comment_id: comment.id,
                    body: comment.body
                  });
                });
              } else {
                github.rest.issues.createComment({
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  issue_number: pr_number,
                  body: comment.body
                });
              }
            });

      - name: Dump comments file
        if: >-
          always() &&
          steps.download-artifact.outputs.artifact-ids != ''
        run: cat comments*
