name: Comment on an issue

on:
  workflow_run:
    workflows:
      - "Check code formatting"
      - "Check for private emails used in PRs"
      - "PR Request Release Note"
    types:
      - completed

permissions:
  contents: read

jobs:
  pr-comment:
    runs-on: ubuntu-latest
    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@v4
        with:
          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-id != ''
        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) => {

              // 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.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() &&
          steps.download-artifact.outputs.artifact-id != ''
        run: cat comments
