1# This workflow will request reviews from the maintainers of each package
2# listed in the PR's most recent eval comparison artifact.
3
4name: Reviewers
5
6on:
7 pull_request:
8 paths:
9 - .github/workflows/reviewers.yml
10 pull_request_target:
11 types: [ready_for_review]
12 workflow_call:
13 secrets:
14 OWNER_APP_PRIVATE_KEY:
15 required: true
16
17concurrency:
18 group: reviewers-${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.run_id }}
19 cancel-in-progress: true
20
21permissions: {}
22
23defaults:
24 run:
25 shell: bash
26
27jobs:
28 request:
29 runs-on: ubuntu-24.04-arm
30 steps:
31 - name: Check out the PR at the base commit
32 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
33 with:
34 path: trusted
35 sparse-checkout: ci
36
37 - name: Install Nix
38 uses: cachix/install-nix-action@f0fe604f8a612776892427721526b4c7cfb23aba # v31
39 with:
40 extra_nix_config: sandbox = true
41
42 - name: Build the requestReviews derivation
43 run: nix-build trusted/ci -A requestReviews
44
45 # See ./codeowners-v2.yml, reuse the same App because we need the same permissions
46 # Can't use the token received from permissions above, because it can't get enough permissions
47 - uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
48 if: github.event_name == 'pull_request_target' && vars.OWNER_APP_ID
49 id: app-token
50 with:
51 app-id: ${{ vars.OWNER_APP_ID }}
52 private-key: ${{ secrets.OWNER_APP_PRIVATE_KEY }}
53 permission-administration: read
54 permission-members: read
55 permission-pull-requests: write
56
57 - name: Log current API rate limits (github.token)
58 env:
59 GH_TOKEN: ${{ github.token }}
60 run: gh api /rate_limit | jq
61
62 # In the regular case, this workflow is called via workflow_call from the eval workflow directly.
63 # In the more special case, when a PR is undrafted an eval run will have started already.
64 - name: Wait for comparison to be done
65 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
66 id: eval
67 with:
68 script: |
69 const run_id = (await github.rest.actions.listWorkflowRuns({
70 owner: context.repo.owner,
71 repo: context.repo.repo,
72 workflow_id: 'pr.yml',
73 event: context.eventName,
74 head_sha: context.payload.pull_request.head.sha
75 })).data.workflow_runs[0].id
76
77 core.setOutput('run-id', run_id)
78
79 // Waiting 120 * 5 sec = 10 min. max.
80 // The extreme case is an Eval run that just started when the PR is undrafted.
81 // Eval takes max 5-6 minutes, normally.
82 for (let i = 0; i < 120; i++) {
83 const result = await github.rest.actions.listWorkflowRunArtifacts({
84 owner: context.repo.owner,
85 repo: context.repo.repo,
86 run_id,
87 name: 'comparison'
88 })
89 if (result.data.total_count > 0) return
90 await new Promise(resolve => setTimeout(resolve, 5000))
91 }
92 throw new Error("No comparison artifact found.")
93
94 - name: Log current API rate limits (github.token)
95 env:
96 GH_TOKEN: ${{ github.token }}
97 run: gh api /rate_limit | jq
98
99 - name: Download the comparison results
100 uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
101 with:
102 run-id: ${{ steps.eval.outputs.run-id }}
103 github-token: ${{ github.token }}
104 pattern: comparison
105 path: comparison
106 merge-multiple: true
107
108 - name: Log current API rate limits (app-token)
109 if: ${{ steps.app-token.outputs.token }}
110 env:
111 GH_TOKEN: ${{ steps.app-token.outputs.token }}
112 run: gh api /rate_limit | jq
113
114 - name: Log current API rate limits (github.token)
115 env:
116 GH_TOKEN: ${{ github.token }}
117 run: gh api /rate_limit | jq
118
119 - name: Requesting maintainer reviews
120 if: ${{ steps.app-token.outputs.token }}
121 env:
122 GH_TOKEN: ${{ github.token }}
123 REPOSITORY: ${{ github.repository }}
124 NUMBER: ${{ github.event.number }}
125 AUTHOR: ${{ github.event.pull_request.user.login }}
126 # Don't request reviewers on draft PRs
127 DRY_MODE: ${{ github.event.pull_request.draft && '1' || '' }}
128 run: |
129 # maintainers.json contains GitHub IDs. Look up handles to request reviews from.
130 # There appears to be no API to request reviews based on GitHub IDs
131 jq -r 'keys[]' comparison/maintainers.json \
132 | while read -r id; do gh api /user/"$id" --jq .login; done \
133 | GH_TOKEN=${{ steps.app-token.outputs.token }} result/bin/request-reviewers.sh "$REPOSITORY" "$NUMBER" "$AUTHOR"
134
135 - name: Log current API rate limits (app-token)
136 if: ${{ steps.app-token.outputs.token }}
137 env:
138 GH_TOKEN: ${{ steps.app-token.outputs.token }}
139 run: gh api /rate_limit | jq
140
141 - name: Log current API rate limits (github.token)
142 env:
143 GH_TOKEN: ${{ github.token }}
144 run: gh api /rate_limit | jq