From 959eed1f2ac3a848dfeefe7dbbde869ddef53b53 Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Sun, 8 Jun 2025 12:12:06 +0200 Subject: [PATCH 1/3] workflows/{pr,push}: init Those two workflows bundle all the main jobs in two event-specific wrapper workflows. This enables us to do two things later on: - Synchronize the merge commits between most of the jobs run in a PR. - Create a single "required" job to be targeted by GitHub's "required status checks to pass" feature. --- .github/workflows/README.md | 2 +- .github/workflows/build.yml | 12 +++------ .github/workflows/check.yml | 9 +------ .github/workflows/eval.yml | 29 ++++++-------------- .github/workflows/labels.yml | 2 +- .github/workflows/lint.yml | 9 +------ .github/workflows/pr.yml | 47 +++++++++++++++++++++++++++++++++ .github/workflows/push.yml | 29 ++++++++++++++++++++ .github/workflows/reviewers.yml | 5 +++- 9 files changed, 96 insertions(+), 48 deletions(-) create mode 100644 .github/workflows/pr.yml create mode 100644 .github/workflows/push.yml diff --git a/.github/workflows/README.md b/.github/workflows/README.md index 78303c2c64b8..e3be33ae6456 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -29,7 +29,7 @@ Thus, it is important how to construct the group keys: - We don't want workflows of different Pull Requests to cancel each other, so we include `github.event.pull_request.number`. The [GitHub docs](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/control-the-concurrency-of-workflows-and-jobs#example-using-a-fallback-value) show using `github.head_ref` for this purpose, but this doesn't work well with forks: Different users could have the same head branch name in their forks and run CI for their PRs at the same time. -- Sometimes, there is no `pull_request.number`. That's the case for `push` or `workflow_run` events. To ensure non-PR runs are never cancelled, we add a fallback of `github.run_id`. This is a unique value for each workflow run. +- Sometimes, there is no `pull_request.number`. To ensure non-PR runs are never cancelled, we add a fallback of `github.run_id`. This is a unique value for each workflow run. - Of course, we run multiple workflows at the same time, so we add `github.workflow` to the key. Otherwise workflows would cancel each other. diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a9efff4d4a8f..897bde43b645 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,14 +1,10 @@ name: Build on: - pull_request: - paths: - - .github/workflows/build.yml - pull_request_target: - -concurrency: - group: build-${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.run_id }} - cancel-in-progress: true + workflow_call: + secrets: + CACHIX_AUTH_TOKEN: + required: true permissions: {} diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index dfe5999df23f..966e0f5c0d52 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -1,14 +1,7 @@ name: Check on: - pull_request: - paths: - - .github/workflows/check.yml - pull_request_target: - -concurrency: - group: check-${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.run_id }} - cancel-in-progress: true + workflow_call: permissions: {} diff --git a/.github/workflows/eval.yml b/.github/workflows/eval.yml index ea96f792c294..7edac16fe2c3 100644 --- a/.github/workflows/eval.yml +++ b/.github/workflows/eval.yml @@ -1,24 +1,10 @@ name: Eval on: - pull_request: - paths: - - .github/workflows/eval.yml - - .github/workflows/reviewers.yml # needs eval results from the same event type - pull_request_target: - push: - # Keep this synced with ci/request-reviews/dev-branches.txt - branches: - - master - - staging - - release-* - - staging-* - - haskell-updates - - python-updates - -concurrency: - group: eval-${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.run_id }} - cancel-in-progress: true + workflow_call: + secrets: + OWNER_APP_PRIVATE_KEY: + required: false permissions: {} @@ -109,12 +95,12 @@ jobs: run_id = (await github.rest.actions.listWorkflowRuns({ owner: context.repo.owner, repo: context.repo.repo, - workflow_id: 'eval.yml', + workflow_id: 'push.yml', event: 'push', head_sha: targetSha })).data.workflow_runs[0].id } catch { - throw new Error(`Could not find an eval.yml workflow run for ${targetSha}.`) + throw new Error(`Could not find an push.yml workflow run for ${targetSha}.`) } core.setOutput('targetRunId', run_id) @@ -265,4 +251,5 @@ jobs: needs: [prepare, outpaths] if: needs.prepare.outputs.targetSha uses: ./.github/workflows/reviewers.yml - secrets: inherit + secrets: + OWNER_APP_PRIVATE_KEY: ${{ secrets.OWNER_APP_PRIVATE_KEY }} diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml index 2ae77cf01421..afc18b5e542b 100644 --- a/.github/workflows/labels.yml +++ b/.github/workflows/labels.yml @@ -147,7 +147,7 @@ jobs: const run_id = (await github.rest.actions.listWorkflowRuns({ ...context.repo, - workflow_id: 'eval.yml', + workflow_id: 'pr.yml', event: 'pull_request_target', // For PR events, the workflow run is still in progress with this job itself. status: prEventCondition ? 'in_progress' : 'success', diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 2c2401ecdfff..19540306148a 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,14 +1,7 @@ name: Lint on: - pull_request: - paths: - - .github/workflows/lint.yml - pull_request_target: - -concurrency: - group: lint-${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.run_id }} - cancel-in-progress: true + workflow_call: permissions: {} diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 000000000000..924a60d3752d --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,47 @@ +name: PR + +on: + pull_request: + paths: + - .github/workflows/build.yml + - .github/workflows/check.yml + - .github/workflows/eval.yml + - .github/workflows/lint.yml + - .github/workflows/pr.yml + - .github/workflows/reviewers.yml # needs eval results from the same event type + pull_request_target: + +concurrency: + group: pr-${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.run_id }} + cancel-in-progress: true + +permissions: {} + +jobs: + check: + name: Check + uses: ./.github/workflows/check.yml + permissions: + # cherry-picks + pull-requests: write + + lint: + name: Lint + uses: ./.github/workflows/lint.yml + + eval: + name: Eval + uses: ./.github/workflows/eval.yml + permissions: + # compare + issues: write + pull-requests: write + statuses: write + secrets: + OWNER_APP_PRIVATE_KEY: ${{ secrets.OWNER_APP_PRIVATE_KEY }} + + build: + name: Build + uses: ./.github/workflows/build.yml + secrets: + CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml new file mode 100644 index 000000000000..a6836b186e06 --- /dev/null +++ b/.github/workflows/push.yml @@ -0,0 +1,29 @@ +name: Push + +on: + pull_request: + paths: + - .github/workflows/push.yml + # eval is tested via pr.yml + push: + # Keep this synced with ci/request-reviews/dev-branches.txt + branches: + - master + - staging + - release-* + - staging-* + - haskell-updates + - python-updates + +permissions: {} + +jobs: + eval: + name: Eval + uses: ./.github/workflows/eval.yml + # Those are not actually used on push, but will throw an error if not set. + permissions: + # compare + issues: write + pull-requests: write + statuses: write diff --git a/.github/workflows/reviewers.yml b/.github/workflows/reviewers.yml index 894da05c32e1..b79e3a589250 100644 --- a/.github/workflows/reviewers.yml +++ b/.github/workflows/reviewers.yml @@ -10,6 +10,9 @@ on: 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 }} @@ -63,7 +66,7 @@ jobs: const run_id = (await github.rest.actions.listWorkflowRuns({ owner: context.repo.owner, repo: context.repo.repo, - workflow_id: 'eval.yml', + workflow_id: 'pr.yml', event: context.eventName, head_sha: context.payload.pull_request.head.sha })).data.workflow_runs[0].id From 008527d7cd6384b0b0f4bb6f950575685f156c78 Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Sun, 8 Jun 2025 13:12:26 +0200 Subject: [PATCH 2/3] workflows/eval: move eval-aliases back into eval We previously moved this out of the main eval workflow to avoid running it on push and/or undrafting the PR. The latter has been removed in the meantime and the former can be checked with a simple condition. Thus we move it back in, to make it part of the 4 main workflows, which will be required before merge eventually. --- .github/workflows/eval-aliases.yml | 42 ------------------------------ .github/workflows/eval.yml | 24 +++++++++++++++++ 2 files changed, 24 insertions(+), 42 deletions(-) delete mode 100644 .github/workflows/eval-aliases.yml diff --git a/.github/workflows/eval-aliases.yml b/.github/workflows/eval-aliases.yml deleted file mode 100644 index 599d82a93e51..000000000000 --- a/.github/workflows/eval-aliases.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: Eval aliases - -on: - pull_request: - paths: - - .github/workflows/eval-aliases.yml - pull_request_target: - -concurrency: - group: eval-aliases-${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.run_id }} - cancel-in-progress: true - -permissions: {} - -defaults: - run: - shell: bash - -jobs: - eval-aliases: - name: Eval nixpkgs with aliases enabled - runs-on: ubuntu-24.04-arm - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - sparse-checkout: .github/actions - - name: Check if the PR can be merged and checkout the merge commit - uses: ./.github/actions/get-merge-commit - with: - merged-as-untrusted: true - - - name: Install Nix - uses: cachix/install-nix-action@17fe5fb4a23ad6cbbe47d6b3f359611ad276644c # v31 - with: - extra_nix_config: sandbox = true - - - name: Ensure flake outputs on all systems still evaluate - run: nix flake check --all-systems --no-build ./untrusted - - - name: Query nixpkgs with aliases enabled to check for basic syntax errors - run: | - time nix-env -I ./untrusted -f ./untrusted -qa '*' --option restrict-eval true --option allow-import-from-derivation false >/dev/null diff --git a/.github/workflows/eval.yml b/.github/workflows/eval.yml index 7edac16fe2c3..5649e01df5b5 100644 --- a/.github/workflows/eval.yml +++ b/.github/workflows/eval.yml @@ -253,3 +253,27 @@ jobs: uses: ./.github/workflows/reviewers.yml secrets: OWNER_APP_PRIVATE_KEY: ${{ secrets.OWNER_APP_PRIVATE_KEY }} + + misc: + if: ${{ github.event_name != 'push' }} + runs-on: ubuntu-24.04-arm + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + sparse-checkout: .github/actions + - name: Check if the PR can be merged and checkout the merge commit + uses: ./.github/actions/get-merge-commit + with: + merged-as-untrusted: true + + - name: Install Nix + uses: cachix/install-nix-action@17fe5fb4a23ad6cbbe47d6b3f359611ad276644c # v31 + with: + extra_nix_config: sandbox = true + + - name: Ensure flake outputs on all systems still evaluate + run: nix flake check --all-systems --no-build ./untrusted + + - name: Query nixpkgs with aliases enabled to check for basic syntax errors + run: | + time nix-env -I ./untrusted -f ./untrusted -qa '*' --option restrict-eval true --option allow-import-from-derivation false >/dev/null From c08b86e962a69868205a8936c9326634f1c43c05 Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Fri, 30 May 2025 18:29:13 +0200 Subject: [PATCH 3/3] workflows/eval: use consistent naming with the other 3 PR workflows The overall idea is to use names short enough to fit into the status checks list without shortening. This change mostly happened in the commits before, here we just follow the same pattern for the remaining workflows. --- .github/workflows/eval.yml | 10 ++++------ .github/workflows/labels.yml | 5 ++--- .github/workflows/reviewers.yml | 1 - 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/.github/workflows/eval.yml b/.github/workflows/eval.yml index 5649e01df5b5..f7ce71e4dde1 100644 --- a/.github/workflows/eval.yml +++ b/.github/workflows/eval.yml @@ -14,7 +14,6 @@ defaults: jobs: prepare: - name: Prepare runs-on: ubuntu-24.04-arm outputs: mergedSha: ${{ steps.get-merge-commit.outputs.mergedSha }} @@ -35,14 +34,14 @@ jobs: run: | echo "systems=$(jq -c > "$GITHUB_OUTPUT" - outpaths: - name: Outpaths + eval: runs-on: ubuntu-24.04-arm needs: [prepare] strategy: fail-fast: false matrix: system: ${{ fromJSON(needs.prepare.outputs.systems) }} + name: ${{ matrix.system }} steps: - name: Enable swap run: | @@ -147,9 +146,8 @@ jobs: path: diff/* compare: - name: Comparison runs-on: ubuntu-24.04-arm - needs: [prepare, outpaths] + needs: [prepare, eval] if: needs.prepare.outputs.targetSha permissions: issues: write # needed to create *new* labels @@ -248,7 +246,7 @@ jobs: # No dependency on "compare", so that it can start at the same time. # We only wait for the "comparison" artifact to be available, which makes the start-to-finish time # for the eval workflow considerably faster. - needs: [prepare, outpaths] + needs: [prepare, eval] if: needs.prepare.outputs.targetSha uses: ./.github/workflows/reviewers.yml secrets: diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml index afc18b5e542b..2966ebfe031f 100644 --- a/.github/workflows/labels.yml +++ b/.github/workflows/labels.yml @@ -3,7 +3,7 @@ # access to the GitHub API. This means that it should not evaluate user input in # a way that allows code injection. -name: "Label PR" +name: Labels on: schedule: @@ -33,8 +33,7 @@ defaults: shell: bash jobs: - labels: - name: label-pr + update: runs-on: ubuntu-24.04-arm if: github.event_name != 'schedule' || github.repository_owner == 'NixOS' steps: diff --git a/.github/workflows/reviewers.yml b/.github/workflows/reviewers.yml index b79e3a589250..4beb755e2b64 100644 --- a/.github/workflows/reviewers.yml +++ b/.github/workflows/reviewers.yml @@ -26,7 +26,6 @@ defaults: jobs: request: - name: Request runs-on: ubuntu-24.04-arm steps: - name: Check out the PR at the base commit