summaryrefslogtreecommitdiff
path: root/.github/workflows/reviewers.yml
blob: 797fa9e919119bfe00d6109de310e2b406501dc7 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# This workflow will request reviews from the maintainers of each package
# listed in the PR's most recent eval comparison artifact.

name: Reviewers

on:
  pull_request:
    paths:
      - .github/workflows/reviewers.yml
  pull_request_target:
    types: [ready_for_review]
  workflow_call:
    secrets:
      OWNER_APP_PRIVATE_KEY:
        required: true

concurrency:
  group: reviewers-${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

permissions: {}

defaults:
  run:
    shell: bash

jobs:
  request:
    runs-on: ubuntu-24.04-arm
    timeout-minutes: 20
    steps:
      - name: Check out the PR at the base commit
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
        with:
          path: trusted
          sparse-checkout: ci

      - name: Install Nix
        uses: cachix/install-nix-action@f0fe604f8a612776892427721526b4c7cfb23aba # v31
        with:
          extra_nix_config: sandbox = true

      - name: Build the requestReviews derivation
        run: nix-build trusted/ci -A requestReviews

      # See ./codeowners-v2.yml, reuse the same App because we need the same permissions
      # Can't use the token received from permissions above, because it can't get enough permissions
      - uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
        if: github.event_name == 'pull_request_target' && vars.OWNER_APP_ID
        id: app-token
        with:
          app-id: ${{ vars.OWNER_APP_ID }}
          private-key: ${{ secrets.OWNER_APP_PRIVATE_KEY }}
          permission-administration: read
          permission-members: read
          permission-pull-requests: write

      - name: Log current API rate limits (github.token)
        env:
          GH_TOKEN: ${{ github.token }}
        run: gh api /rate_limit | jq

      # In the regular case, this workflow is called via workflow_call from the eval workflow directly.
      # In the more special case, when a PR is undrafted an eval run will have started already.
      - name: Wait for comparison to be done
        uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
        id: eval
        with:
          script: |
            const run_id = (await github.rest.actions.listWorkflowRuns({
              owner: context.repo.owner,
              repo: context.repo.repo,
              workflow_id: 'pr.yml',
              event: context.eventName,
              head_sha: context.payload.pull_request.head.sha
            })).data.workflow_runs[0].id

            core.setOutput('run-id', run_id)

            // Waiting 120 * 5 sec = 10 min. max.
            // The extreme case is an Eval run that just started when the PR is undrafted.
            // Eval takes max 5-6 minutes, normally.
            for (let i = 0; i < 120; i++) {
              const result = await github.rest.actions.listWorkflowRunArtifacts({
                owner: context.repo.owner,
                repo: context.repo.repo,
                run_id,
                name: 'comparison'
              })
              if (result.data.total_count > 0) return
              await new Promise(resolve => setTimeout(resolve, 5000))
            }
            throw new Error("No comparison artifact found.")

      - name: Log current API rate limits (github.token)
        env:
          GH_TOKEN: ${{ github.token }}
        run: gh api /rate_limit | jq

      - name: Download the comparison results
        uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
        with:
          run-id: ${{ steps.eval.outputs.run-id }}
          github-token: ${{ github.token }}
          pattern: comparison
          path: comparison
          merge-multiple: true

      - name: Log current API rate limits (app-token)
        if: ${{ steps.app-token.outputs.token }}
        env:
          GH_TOKEN: ${{ steps.app-token.outputs.token }}
        run: gh api /rate_limit | jq

      - name: Log current API rate limits (github.token)
        env:
          GH_TOKEN: ${{ github.token }}
        run: gh api /rate_limit | jq

      - name: Requesting maintainer reviews
        if: ${{ steps.app-token.outputs.token }}
        env:
          GH_TOKEN: ${{ github.token }}
          REPOSITORY: ${{ github.repository }}
          NUMBER: ${{ github.event.number }}
          AUTHOR: ${{ github.event.pull_request.user.login }}
          # Don't request reviewers on draft PRs
          DRY_MODE: ${{ github.event.pull_request.draft && '1' || '' }}
        run: |
          # maintainers.json contains GitHub IDs. Look up handles to request reviews from.
          # There appears to be no API to request reviews based on GitHub IDs
          jq -r 'keys[]' comparison/maintainers.json \
            | while read -r id; do gh api /user/"$id" --jq .login; done \
            | GH_TOKEN=${{ steps.app-token.outputs.token }} result/bin/request-reviewers.sh "$REPOSITORY" "$NUMBER" "$AUTHOR"

      - name: Log current API rate limits (app-token)
        if: ${{ steps.app-token.outputs.token }}
        env:
          GH_TOKEN: ${{ steps.app-token.outputs.token }}
        run: gh api /rate_limit | jq

      - name: Log current API rate limits (github.token)
        env:
          GH_TOKEN: ${{ github.token }}
        run: gh api /rate_limit | jq