# Workflow that runs periodically to check whether PRs have been imported into
# Gerrit and if they have been merged. The workflow adds a PR comment after
# import and after merge. PRs that are merged upstream are then closed.
name: PR Watcher
on:
  workflow_dispatch:
  schedule:
    - cron: "*/10 * * * *" # Every 10 minutes

jobs:
  check:
    name: Check Copybara Import Status
    runs-on: ubuntu-latest
    permissions:
      actions: write
    steps:
      - name: Check Pull Requests
        uses: actions/github-script@v6
        with:
          script: |
            // Get all open PRs.
            const pulls = await github.rest.pulls.list({
              owner: context.repo.owner,
              repo: context.repo.repo,
              state: 'open',
              base: 'main',
            });

            for (const pull of pulls.data) {
              const query = `query($owner:String!, $name:String!, $pullNumber:Int!, $statusContext:String!) {
                repository(owner:$owner, name:$name) {
                  pullRequest(number:$pullNumber) {
                    commits(last:1) {
                      nodes {
                        commit {
                          status {
                            context(name: $statusContext) {
                              state
                              targetUrl
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }`;

              // Query the import/copybara status check.
              const result = await github.graphql(query, {
                owner: context.repo.owner,
                name: context.repo.repo,
                pullNumber: pull.number,
                statusContext: 'import/copybara',
              });
              const nodes = result.repository.pullRequest.commits.nodes;
              const commit = nodes[0].commit;
              if (commit && commit.status && commit.status.context) {
                // Forward the status check information to the pr-manager workflow.
                await github.rest.actions.createWorkflowDispatch({
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  ref: 'main',
                  workflow_id: 'pr-manager.yml',
                  inputs: {
                    pullNumber: pull.number.toString(),
                    state: commit.status.context.state,
                    targetUrl: commit.status.context.targetUrl,
                  },
                });
              }

              // Look through all timeline events on the PR.
              // When the PR is merged upstream, it will include a backreference back to
              // the PR in the commit message.
              const timeline = github.paginate.iterator(github.rest.issues.listEventsForTimeline, {
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: pull.number,
              });
              for await (const { data: timelineData } of timeline) {
                for (const timelineItem of timelineData) {
                  if (timelineItem.event === 'referenced' && timelineItem.commit_id) {
                    try {
                      // Compare commit ids against refs/heads/main to see if they are
                      // included in the main branch.
                      const compare = await github.rest.repos.compareCommitsWithBasehead({
                        basehead: `${timelineItem.commit_id}...refs/heads/main`,
                        owner: context.repo.owner,
                        repo: context.repo.repo,
                      });
                      if (compare.data.status == "ahead" || compare.data.status == "identical") {
                        // This is a commit that has already been merged into main.
                        const commit = await github.rest.repos.getCommit({
                          owner: context.repo.owner,
                          repo: context.repo.repo,
                          ref: timelineItem.commit_id,
                        });
                        const message = commit.data.commit.message;
                        const lines = message.split('\n');
                        for (const line of lines) {
                          // Check if the commit has a footer referencing a PR.
                          const tag = 'GITHUB_PR_HEAD_SHA=';
                          if (line.startsWith(tag)) {
                            const sha = line.slice(tag.length);
                            // The merged commit footer matches the PR sha.
                            if (pull.head.sha === sha) {
                              // Close the PR.
                              await github.rest.actions.createWorkflowDispatch({
                                owner: context.repo.owner,
                                repo: context.repo.repo,
                                ref: 'main',
                                workflow_id: 'pr-manager.yml',
                                inputs: {
                                  pullNumber: pull.number.toString(),
                                  state: 'merged',
                                  targetUrl: commit.data.html_url,
                                },
                              });
                            }
                          }
                        }
                      }
                    } catch (err) {
                      // This is OK because not all commits will be comparable.
                      console.warn(err);
                    }
                  }
                }
              }
            }
