From 959eed1f2ac3a848dfeefe7dbbde869ddef53b53 Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Sun, 8 Jun 2025 12:12:06 +0200 Subject: [PATCH] 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