Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at 25.05-beta 281 lines 11 kB view raw
1name: Eval 2 3on: 4 pull_request: 5 paths: 6 - .github/workflows/eval.yml 7 pull_request_target: 8 types: [opened, ready_for_review, synchronize, reopened] 9 push: 10 # Keep this synced with ci/request-reviews/dev-branches.txt 11 branches: 12 - master 13 - staging 14 - release-* 15 - staging-* 16 - haskell-updates 17 - python-updates 18 19permissions: {} 20 21jobs: 22 get-merge-commit: 23 uses: ./.github/workflows/get-merge-commit.yml 24 25 outpaths: 26 name: Outpaths 27 runs-on: ubuntu-24.04-arm 28 needs: [ get-merge-commit ] 29 strategy: 30 fail-fast: false 31 matrix: 32 system: ${{ fromJSON(needs.get-merge-commit.outputs.systems) }} 33 steps: 34 - name: Enable swap 35 run: | 36 sudo fallocate -l 10G /swap 37 sudo chmod 600 /swap 38 sudo mkswap /swap 39 sudo swapon /swap 40 41 - name: Check out the PR at the test merge commit 42 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 43 with: 44 ref: ${{ needs.get-merge-commit.outputs.mergedSha }} 45 path: nixpkgs 46 47 - name: Install Nix 48 uses: cachix/install-nix-action@526118121621777ccd86f79b04685a9319637641 # v31 49 with: 50 extra_nix_config: sandbox = true 51 52 - name: Evaluate the ${{ matrix.system }} output paths for all derivation attributes 53 env: 54 MATRIX_SYSTEM: ${{ matrix.system }} 55 run: | 56 nix-build nixpkgs/ci -A eval.singleSystem \ 57 --argstr evalSystem "$MATRIX_SYSTEM" \ 58 --arg chunkSize 10000 59 # If it uses too much memory, slightly decrease chunkSize 60 61 - name: Upload the output paths and eval stats 62 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 63 with: 64 name: intermediate-${{ matrix.system }} 65 path: result/* 66 67 process: 68 name: Process 69 runs-on: ubuntu-24.04-arm 70 needs: [ outpaths, get-merge-commit ] 71 outputs: 72 targetRunId: ${{ steps.targetRunId.outputs.targetRunId }} 73 steps: 74 - name: Download output paths and eval stats for all systems 75 uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 76 with: 77 pattern: intermediate-* 78 path: intermediate 79 80 - name: Check out the PR at the test merge commit 81 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 82 with: 83 ref: ${{ needs.get-merge-commit.outputs.mergedSha }} 84 fetch-depth: 2 85 path: nixpkgs 86 87 - name: Install Nix 88 uses: cachix/install-nix-action@526118121621777ccd86f79b04685a9319637641 # v31 89 with: 90 extra_nix_config: sandbox = true 91 92 - name: Combine all output paths and eval stats 93 run: | 94 nix-build nixpkgs/ci -A eval.combine \ 95 --arg resultsDir ./intermediate \ 96 -o prResult 97 98 - name: Upload the combined results 99 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 100 with: 101 name: result 102 path: prResult/* 103 104 - name: Get target run id 105 if: needs.get-merge-commit.outputs.targetSha 106 id: targetRunId 107 run: | 108 # Get the latest eval.yml workflow run for the PR's target commit 109 if ! run=$(gh api --method GET /repos/"$REPOSITORY"/actions/workflows/eval.yml/runs \ 110 -f head_sha="$TARGET_SHA" -f event=push \ 111 --jq '.workflow_runs | sort_by(.run_started_at) | .[-1]') \ 112 || [[ -z "$run" ]]; then 113 echo "Could not find an eval.yml workflow run for $TARGET_SHA, cannot make comparison" 114 exit 1 115 fi 116 echo "Comparing against $(jq .html_url <<< "$run")" 117 runId=$(jq .id <<< "$run") 118 conclusion=$(jq -r .conclusion <<< "$run") 119 120 while [[ "$conclusion" == null || "$conclusion" == "" ]]; do 121 echo "Workflow not done, waiting 10 seconds before checking again" 122 sleep 10 123 conclusion=$(gh api /repos/"$REPOSITORY"/actions/runs/"$runId" --jq '.conclusion') 124 done 125 126 if [[ "$conclusion" != "success" ]]; then 127 echo "Workflow was not successful (conclusion: $conclusion), cannot make comparison" 128 exit 1 129 fi 130 131 echo "targetRunId=$runId" >> "$GITHUB_OUTPUT" 132 env: 133 REPOSITORY: ${{ github.repository }} 134 TARGET_SHA: ${{ needs.get-merge-commit.outputs.targetSha }} 135 GH_TOKEN: ${{ github.token }} 136 137 - uses: actions/download-artifact@v4 138 if: steps.targetRunId.outputs.targetRunId 139 with: 140 name: result 141 path: targetResult 142 github-token: ${{ github.token }} 143 run-id: ${{ steps.targetRunId.outputs.targetRunId }} 144 145 - name: Compare against the target branch 146 if: steps.targetRunId.outputs.targetRunId 147 run: | 148 git -C nixpkgs worktree add ../target ${{ needs.get-merge-commit.outputs.targetSha }} 149 git -C nixpkgs diff --name-only ${{ needs.get-merge-commit.outputs.targetSha }} \ 150 | jq --raw-input --slurp 'split("\n")[:-1]' > touched-files.json 151 152 # Use the target branch to get accurate maintainer info 153 nix-build target/ci -A eval.compare \ 154 --arg beforeResultDir ./targetResult \ 155 --arg afterResultDir "$(realpath prResult)" \ 156 --arg touchedFilesJson ./touched-files.json \ 157 -o comparison 158 159 cat comparison/step-summary.md >> "$GITHUB_STEP_SUMMARY" 160 161 - name: Upload the combined results 162 if: steps.targetRunId.outputs.targetRunId 163 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 164 with: 165 name: comparison 166 path: comparison/* 167 168 # Separate job to have a very tightly scoped PR write token 169 tag: 170 name: Tag 171 runs-on: ubuntu-24.04-arm 172 needs: [ get-merge-commit, process ] 173 if: needs.process.outputs.targetRunId 174 permissions: 175 pull-requests: write 176 statuses: write 177 steps: 178 # See ./codeowners-v2.yml, reuse the same App because we need the same permissions 179 # Can't use the token received from permissions above, because it can't get enough permissions 180 - uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6 181 if: vars.OWNER_APP_ID 182 id: app-token 183 with: 184 app-id: ${{ vars.OWNER_APP_ID }} 185 private-key: ${{ secrets.OWNER_APP_PRIVATE_KEY }} 186 permission-administration: read 187 permission-members: read 188 permission-pull-requests: write 189 190 - name: Download process result 191 uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 192 with: 193 name: comparison 194 path: comparison 195 196 - name: Install Nix 197 uses: cachix/install-nix-action@526118121621777ccd86f79b04685a9319637641 # v31 198 199 # Important: This workflow job runs with extra permissions, 200 # so we need to make sure to not run untrusted code from PRs 201 - name: Check out Nixpkgs at the base commit 202 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 203 with: 204 ref: ${{ needs.get-merge-commit.outputs.targetSha }} 205 path: base 206 sparse-checkout: ci 207 208 - name: Build the requestReviews derivation 209 run: nix-build base/ci -A requestReviews 210 211 - name: Labelling pull request 212 if: ${{ github.event_name == 'pull_request_target' && github.repository_owner == 'NixOS' }} 213 run: | 214 # Get all currently set rebuild labels 215 gh api \ 216 /repos/"$REPOSITORY"/issues/"$NUMBER"/labels \ 217 --jq '.[].name | select(startswith("10.rebuild"))' \ 218 | sort > before 219 220 # And the labels that should be there 221 jq -r '.labels[]' comparison/changed-paths.json \ 222 | sort > after 223 224 # Remove the ones not needed anymore 225 while read -r toRemove; do 226 echo "Removing label $toRemove" 227 gh api \ 228 --method DELETE \ 229 /repos/"$REPOSITORY"/issues/"$NUMBER"/labels/"$toRemove" 230 done < <(comm -23 before after) 231 232 # And add the ones that aren't set already 233 while read -r toAdd; do 234 echo "Adding label $toAdd" 235 gh api \ 236 --method POST \ 237 /repos/"$REPOSITORY"/issues/"$NUMBER"/labels \ 238 -f "labels[]=$toAdd" 239 done < <(comm -13 before after) 240 241 env: 242 GH_TOKEN: ${{ github.token }} 243 REPOSITORY: ${{ github.repository }} 244 NUMBER: ${{ github.event.number }} 245 246 - name: Add eval summary to commit statuses 247 if: ${{ github.event_name == 'pull_request_target' && github.repository_owner == 'NixOS' }} 248 run: | 249 description=$(jq -r ' 250 "Package: added " + (.attrdiff.added | length | tostring) + 251 ", removed " + (.attrdiff.removed | length | tostring) + 252 ", changed " + (.attrdiff.changed | length | tostring) + 253 ", Rebuild: linux " + (.rebuildCountByKernel.linux | tostring) + 254 ", darwin " + (.rebuildCountByKernel.darwin | tostring) 255 ' <comparison/changed-paths.json) 256 target_url="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID?pr=$NUMBER" 257 gh api --method POST \ 258 -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" \ 259 "/repos/$GITHUB_REPOSITORY/statuses/$PR_HEAD_SHA" \ 260 -f "context=Eval / Summary" -f "state=success" -f "description=$description" -f "target_url=$target_url" 261 env: 262 GH_TOKEN: ${{ github.token }} 263 PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} 264 NUMBER: ${{ github.event.number }} 265 266 - name: Requesting maintainer reviews 267 if: ${{ steps.app-token.outputs.token && github.repository_owner == 'NixOS' }} 268 run: | 269 # maintainers.json contains GitHub IDs. Look up handles to request reviews from. 270 # There appears to be no API to request reviews based on GitHub IDs 271 jq -r 'keys[]' comparison/maintainers.json \ 272 | while read -r id; do gh api /user/"$id" --jq .login; done \ 273 | GH_TOKEN=${{ steps.app-token.outputs.token }} result/bin/request-reviewers.sh "$REPOSITORY" "$NUMBER" "$AUTHOR" 274 275 env: 276 GH_TOKEN: ${{ github.token }} 277 REPOSITORY: ${{ github.repository }} 278 NUMBER: ${{ github.event.number }} 279 AUTHOR: ${{ github.event.pull_request.user.login }} 280 # Don't request reviewers on draft PRs 281 DRY_MODE: ${{ github.event.pull_request.draft && '1' || '' }}