workflows/{check,reviewers}: don't run on staging-like PRs (#418496)

authored by Wolfgang Walther and committed by GitHub 767223d2 c3293bfb

+150 -27
+5 -2
.github/workflows/build.yml
··· 3 3 on: 4 4 workflow_call: 5 5 inputs: 6 + baseBranch: 7 + required: true 8 + type: string 6 9 mergedSha: 7 10 required: true 8 11 type: string ··· 63 66 - name: Build NixOS manual 64 67 if: | 65 68 contains(matrix.builds, 'manual-nixos') && !cancelled() && 66 - (github.base_ref == 'master' || startsWith(github.base_ref, 'release-')) 69 + contains(fromJSON(inputs.baseBranch).type, 'primary') 67 70 run: nix-build untrusted/ci -A manual-nixos --argstr system ${{ matrix.system }} --out-link nixos-manual 68 71 69 72 - name: Build Nixpkgs manual ··· 81 84 - name: Upload NixOS manual 82 85 if: | 83 86 contains(matrix.builds, 'manual-nixos') && !cancelled() && 84 - (github.base_ref == 'master' || startsWith(github.base_ref, 'release-')) 87 + contains(fromJSON(inputs.baseBranch).type, 'primary') 85 88 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 86 89 with: 87 90 name: nixos-manual-${{ matrix.system }}
+9 -5
.github/workflows/check.yml
··· 2 2 3 3 on: 4 4 workflow_call: 5 + inputs: 6 + baseBranch: 7 + required: true 8 + type: string 9 + headBranch: 10 + required: true 11 + type: string 5 12 6 13 permissions: {} 7 14 ··· 12 19 jobs: 13 20 no-channel-base: 14 21 name: no channel base 15 - if: | 16 - startsWith(github.base_ref, 'nixos-') || 17 - startsWith(github.base_ref, 'nixpkgs-') 22 + if: contains(fromJSON(inputs.baseBranch).type, 'channel') 18 23 runs-on: ubuntu-24.04-arm 19 24 steps: 20 25 - run: | ··· 29 34 cherry-pick: 30 35 if: | 31 36 github.event_name == 'pull_request' || 32 - startsWith(github.base_ref, 'release-') || 33 - (startsWith(github.base_ref, 'staging-') && github.base_ref != 'staging-next') 37 + (fromJSON(inputs.baseBranch).stable && !contains(fromJSON(inputs.headBranch).type, 'development')) 34 38 permissions: 35 39 pull-requests: write 36 40 runs-on: ubuntu-24.04-arm
+7 -18
.github/workflows/labels.yml
··· 9 9 schedule: 10 10 - cron: '07,17,27,37,47,57 * * * *' 11 11 workflow_call: 12 + inputs: 13 + headBranch: 14 + required: true 15 + type: string 12 16 workflow_dispatch: 13 17 inputs: 14 18 updatedWithin: ··· 275 279 name: Labels from touched files 276 280 if: | 277 281 github.event_name == 'pull_request_target' && 278 - (github.event.pull_request.head.repo.owner.login != 'NixOS' || !( 279 - github.head_ref == 'haskell-updates' || 280 - github.head_ref == 'python-updates' || 281 - github.head_ref == 'staging-next' || 282 - startsWith(github.head_ref, 'staging-next-') 283 - )) 282 + !contains(fromJSON(inputs.headBranch).type, 'development') 284 283 with: 285 284 repo-token: ${{ secrets.GITHUB_TOKEN }} 286 285 configuration-path: .github/labeler.yml # default ··· 290 289 name: Labels from touched files (no sync) 291 290 if: | 292 291 github.event_name == 'pull_request_target' && 293 - (github.event.pull_request.head.repo.owner.login != 'NixOS' || !( 294 - github.head_ref == 'haskell-updates' || 295 - github.head_ref == 'python-updates' || 296 - github.head_ref == 'staging-next' || 297 - startsWith(github.head_ref, 'staging-next-') 298 - )) 292 + !contains(fromJSON(inputs.headBranch).type, 'development') 299 293 with: 300 294 repo-token: ${{ secrets.GITHUB_TOKEN }} 301 295 configuration-path: .github/labeler-no-sync.yml ··· 308 302 # the backport labels. 309 303 if: | 310 304 github.event_name == 'pull_request_target' && 311 - (github.event.pull_request.head.repo.owner.login == 'NixOS' && ( 312 - github.head_ref == 'haskell-updates' || 313 - github.head_ref == 'python-updates' || 314 - github.head_ref == 'staging-next' || 315 - startsWith(github.head_ref, 'staging-next-') 316 - )) 305 + contains(fromJSON(inputs.headBranch).type, 'development') 317 306 with: 318 307 repo-token: ${{ secrets.GITHUB_TOKEN }} 319 308 configuration-path: .github/labeler-development-branches.yml
+34 -2
.github/workflows/pr.yml
··· 22 22 prepare: 23 23 runs-on: ubuntu-24.04-arm 24 24 outputs: 25 + baseBranch: ${{ steps.branches.outputs.base }} 26 + headBranch: ${{ steps.branches.outputs.head }} 25 27 mergedSha: ${{ steps.get-merge-commit.outputs.mergedSha }} 26 28 targetSha: ${{ steps.get-merge-commit.outputs.targetSha }} 27 29 systems: ${{ steps.systems.outputs.systems }} ··· 30 32 with: 31 33 sparse-checkout: | 32 34 .github/actions 35 + ci/supportedBranches.js 33 36 ci/supportedSystems.json 34 37 - name: Check if the PR can be merged and get the test merge commit 35 38 uses: ./.github/actions/get-merge-commit ··· 40 43 run: | 41 44 echo "systems=$(jq -c <ci/supportedSystems.json)" >> "$GITHUB_OUTPUT" 42 45 46 + - name: Determine branch type 47 + id: branches 48 + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 49 + with: 50 + script: | 51 + const { classify } = require('./ci/supportedBranches.js') 52 + const { base, head } = context.payload.pull_request 53 + 54 + const baseClassification = classify(base.ref) 55 + core.setOutput('base', baseClassification) 56 + core.info('base classification:', baseClassification) 57 + 58 + const headClassification = 59 + (base.repo.full_name == head.repo.full_name) ? 60 + classify(head.ref) : 61 + // PRs from forks are always considered WIP. 62 + { type: ['wip'] } 63 + core.setOutput('head', headClassification) 64 + core.info('head classification:', headClassification) 65 + 43 66 check: 44 67 name: Check 68 + needs: [prepare] 45 69 uses: ./.github/workflows/check.yml 46 70 permissions: 47 71 # cherry-picks 48 72 pull-requests: write 73 + with: 74 + baseBranch: ${{ needs.prepare.outputs.baseBranch }} 75 + headBranch: ${{ needs.prepare.outputs.headBranch }} 49 76 50 77 lint: 51 78 name: Lint ··· 71 98 72 99 labels: 73 100 name: Labels 74 - needs: [eval] 101 + needs: [prepare, eval] 75 102 uses: ./.github/workflows/labels.yml 76 103 permissions: 77 104 issues: write 78 105 pull-requests: write 106 + with: 107 + headBranch: ${{ needs.prepare.outputs.headBranch }} 79 108 80 109 reviewers: 81 110 name: Reviewers 82 111 needs: [prepare, eval] 83 - if: needs.prepare.outputs.targetSha 112 + if: | 113 + needs.prepare.outputs.targetSha && 114 + !contains(fromJSON(needs.prepare.outputs.headBranch).type, 'development') 84 115 uses: ./.github/workflows/reviewers.yml 85 116 secrets: 86 117 OWNER_APP_PRIVATE_KEY: ${{ secrets.OWNER_APP_PRIVATE_KEY }} ··· 92 123 secrets: 93 124 CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} 94 125 with: 126 + baseBranch: ${{ needs.prepare.outputs.baseBranch }} 95 127 mergedSha: ${{ needs.prepare.outputs.mergedSha }} 96 128 97 129 # This job's only purpose is to serve as a target for the "Required Status Checks" branch ruleset.
+4
ci/.editorconfig
··· 1 + # TODO: Move to top-level via staging PR 2 + [*.js] 3 + indent_style = space 4 + indent_size = 2
+29
ci/README.md
··· 20 20 21 21 - `BASE_BRANCH`: The base branch to use, e.g. master or release-24.05 22 22 - `REPOSITORY`: The repository from which to fetch the base branch. Defaults to <https://github.com/NixOS/nixpkgs.git>. 23 + 24 + # Branch classification 25 + 26 + For the purposes of CI, branches in the NixOS/nixpkgs repository are classified as follows: 27 + 28 + - **Channel** branches 29 + - `nixos-` or `nixpkgs-` prefix 30 + - Are only updated from `master` or `release-` branches, when hydra passes. 31 + - Otherwise not worked on, Pull Requests are not allowed. 32 + - Long-lived, no deletion, no force push. 33 + - **Primary development** branches 34 + - `release-` prefix and `master` 35 + - Pull Requests required. 36 + - Long-lived, no deletion, no force push. 37 + - **Secondary development** branches 38 + - `staging-` prefix, `haskell-updates` and `python-updates` 39 + - Pull Requests normally required, except when merging development branches into each other. 40 + - Long-lived, no deletion, no force push. 41 + - **Work-In-Progress** branches 42 + - `backport-`, `revert-` and `wip-` prefixes. 43 + - Deprecated: All other branches, not matched by channel/development. 44 + - Pull Requests are optional. 45 + - Short-lived, force push allowed, deleted after merge. 46 + 47 + Some branches also have a version component, which is either `unstable` or `YY.MM`. 48 + 49 + `ci/supportedBranches.js` is a script imported by CI to classify the base and head branches of a Pull Request. 50 + This classification will then be used to skip certain jobs. 51 + This script can also be run locally to print basic test cases.
+62
ci/supportedBranches.js
··· 1 + #!/usr/bin/env nix-shell 2 + /* 3 + #!nix-shell -i node -p nodejs 4 + */ 5 + 6 + const typeConfig = { 7 + master: ['development', 'primary'], 8 + release: ['development', 'primary'], 9 + staging: ['development', 'secondary'], 10 + 'staging-next': ['development', 'secondary'], 11 + 'haskell-updates': ['development', 'secondary'], 12 + 'python-updates': ['development', 'secondary'], 13 + nixos: ['channel'], 14 + nixpkgs: ['channel'], 15 + } 16 + 17 + function split(branch) { 18 + return { ...branch.match(/(?<prefix>.+?)(-(?<version>\d{2}\.\d{2}|unstable)(?:-(?<suffix>.*))?)?$/).groups } 19 + } 20 + 21 + function classify(branch) { 22 + const { prefix, version } = split(branch) 23 + return { 24 + stable: (version ?? 'unstable') !== 'unstable', 25 + type: typeConfig[prefix] ?? [ 'wip' ] 26 + } 27 + } 28 + 29 + module.exports = { classify } 30 + 31 + // If called directly via CLI, runs the following tests: 32 + if (!module.parent) { 33 + console.log('split(branch)') 34 + function testSplit(branch) { 35 + console.log(branch, split(branch)) 36 + } 37 + testSplit('master') 38 + testSplit('release-25.05') 39 + testSplit('staging-next') 40 + testSplit('staging-25.05') 41 + testSplit('staging-next-25.05') 42 + testSplit('nixpkgs-25.05-darwin') 43 + testSplit('nixpkgs-unstable') 44 + testSplit('haskell-updates') 45 + testSplit('backport-123-to-release-25.05') 46 + 47 + console.log('') 48 + 49 + console.log('classify(branch)') 50 + function testClassify(branch) { 51 + console.log(branch, classify(branch)) 52 + } 53 + testClassify('master') 54 + testClassify('release-25.05') 55 + testClassify('staging-next') 56 + testClassify('staging-25.05') 57 + testClassify('staging-next-25.05') 58 + testClassify('nixpkgs-25.05-darwin') 59 + testClassify('nixpkgs-unstable') 60 + testClassify('haskell-updates') 61 + testClassify('backport-123-to-release-25.05') 62 + }