Skip to content

Commit 73a4ae3

Browse files
authored
workflows: small refactors (NixOS#371216)
2 parents dc17588 + 9ea7422 commit 73a4ae3

23 files changed

+384
-428
lines changed

.github/workflows/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# GitHub Actions Workflows
2+
3+
Some architectural notes about key decisions and concepts in our workflows:
4+
5+
- Instead of `pull_request` we use [`pull_request_target`](https://docs.github.com/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request_target) for all PR-related workflows. This has the advantage that those workflows will run without prior approval for external contributors.
6+
7+
- Running on `pull_request_target` also optionally provides us with a GH_TOKEN with elevated privileges (write access), which we need to do things like adding labels, requesting reviewers or pushing branches. **Note about security:** We need to be careful to limit the scope of elevated privileges as much as possible. Thus they should be lowered to the minimum with `permissions: {}` in every workflow by default.
8+
9+
- By definition `pull_request_target` runs in the context of the **base** of the pull request. This means, that the workflow files to run will be taken from the base branch, not the PR, and actions/checkout will not checkout the PR, but the base branch, by default. To protect our secrets, we need to make sure to **never execute code** from the pull request and always evaluate or build nix code from the pull request with the **sandbox enabled**.
10+
11+
- To test the pull request's contents, we checkout the "test merge commit". This is a temporary commit that GitHub creates automatically as "what would happen, if this PR was merged into the base branch now?". The checkout could be done via the virtual branch `refs/pull/<pr-number>/merge`, but doing so would cause failures when this virtual branch doesn't exist (anymore). This can happen when the PR has conflicts, in which case the virtual branch is not created, or when the PR is getting merged while workflows are still running, in which case the branch won't exist anymore at the time of checkout. Thus, we use the `get-merge-commit.yml` workflow to check whether the PR is mergeable and the test merge commit exists and only then run the relevant jobs.
12+
13+
- Various workflows need to make comparisons against the base branch. In this case, we checkout the parent of the "test merge commit" for best results. Note, that this is not necessarily the same as the default commit that actions/checkout would use, which is also a commit from the base branch (see above), but might be older.
14+
15+
## Terminology
16+
17+
- **base commit**: The pull_request_target event's context commit, i.e. the base commit given by GitHub Actions. Same as `github.event.pull_request.base.sha`.
18+
- **head commit**: The HEAD commit in the pull request's branch. Same as `github.event.pull_request.head.sha`.
19+
- **merge commit**: The temporary "test merge commit" that GitHub Actions creates and updates for the pull request. Same as `refs/pull/${{ github.event.pull_request.number }}/merge`.
20+
- **target commit**: The base branch's parent of the "test merge commit" to compare against.

.github/workflows/backport.yml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
name: Backport
2-
on:
3-
pull_request_target:
4-
types: [closed, labeled]
5-
61
# WARNING:
72
# When extending this action, be aware that $GITHUB_TOKEN allows write access to
83
# the GitHub repository. This means that it should not evaluate user input in a
94
# way that allows code injection.
105

6+
name: Backport
7+
8+
on:
9+
pull_request_target:
10+
types: [closed, labeled]
11+
1112
permissions: {}
1213

1314
jobs:
@@ -23,10 +24,12 @@ jobs:
2324
with:
2425
app-id: ${{ vars.BACKPORT_APP_ID }}
2526
private-key: ${{ secrets.BACKPORT_PRIVATE_KEY }}
27+
2628
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
2729
with:
2830
ref: ${{ github.event.pull_request.head.sha }}
2931
token: ${{ steps.app-token.outputs.token }}
32+
3033
- name: Create backport PRs
3134
uses: korthout/backport-action@be567af183754f6a5d831ae90f648954763f17f5 # v3.1.0
3235
with:

.github/workflows/basic-eval.yml

Lines changed: 0 additions & 31 deletions
This file was deleted.
Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
name: "Check cherry-picks"
2+
23
on:
34
pull_request_target:
45
branches:
5-
- 'release-**'
6-
- 'staging-**'
7-
- '!staging-next'
6+
- 'release-**'
7+
- 'staging-**'
8+
- '!staging-next'
89

910
permissions: {}
1011

@@ -14,13 +15,14 @@ jobs:
1415
runs-on: ubuntu-24.04
1516
if: github.repository_owner == 'NixOS'
1617
steps:
17-
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
18-
with:
19-
fetch-depth: 0
20-
filter: blob:none
21-
- name: Check cherry-picks
22-
env:
23-
BASE_SHA: ${{ github.event.pull_request.base.sha }}
24-
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
25-
run: |
26-
./maintainers/scripts/check-cherry-picks.sh "$BASE_SHA" "$HEAD_SHA"
18+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
19+
with:
20+
fetch-depth: 0
21+
filter: blob:none
22+
23+
- name: Check cherry-picks
24+
env:
25+
BASE_SHA: ${{ github.event.pull_request.base.sha }}
26+
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
27+
run: |
28+
./maintainers/scripts/check-cherry-picks.sh "$BASE_SHA" "$HEAD_SHA"

.github/workflows/check-maintainers-sorted.yaml renamed to .github/workflows/check-maintainers-sorted.yml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,25 @@ on:
44
pull_request_target:
55
paths:
66
- 'maintainers/maintainer-list.nix'
7-
permissions:
8-
contents: read
7+
8+
permissions: {}
99

1010
jobs:
1111
nixos:
1212
name: maintainer-list-check
1313
runs-on: ubuntu-24.04
14-
if: github.repository_owner == 'NixOS'
1514
steps:
1615
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
1716
with:
18-
# pull_request_target checks out the base branch by default
1917
ref: refs/pull/${{ github.event.pull_request.number }}/merge
2018
# Only these directories to perform the check
2119
sparse-checkout: |
2220
lib
2321
maintainers
22+
2423
- uses: cachix/install-nix-action@08dcb3a5e62fa31e2da3d490afc4176ef55ecd72 # v30
2524
with:
26-
# explicitly enable sandbox
2725
extra_nix_config: sandbox = true
26+
2827
- name: Check that maintainer-list.nix is sorted
2928
run: nix-instantiate --eval maintainers/scripts/check-maintainers-sorted.nix

.github/workflows/check-nix-format.yml

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
# https://github.com/NixOS/rfcs/pull/166.
44
# Because of this, this action is not yet enabled for all files -- only for
55
# those who have opted in.
6+
67
name: Check that Nix files are formatted
78

89
on:
910
pull_request_target:
10-
# See the comment at the same location in ./nixpkgs-vet.yml
1111
types: [opened, synchronize, reopened, edited]
12-
permissions:
13-
contents: read
12+
13+
permissions: {}
1414

1515
jobs:
1616
get-merge-commit:
@@ -24,31 +24,34 @@ jobs:
2424
steps:
2525
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
2626
with:
27-
# pull_request_target checks out the base branch by default
2827
ref: ${{ needs.get-merge-commit.outputs.mergedSha }}
2928
# Fetches the merge commit and its parents
3029
fetch-depth: 2
31-
- name: Checking out base branch
30+
31+
- name: Checking out target branch
3232
run: |
33-
base=$(mktemp -d)
34-
baseRev=$(git rev-parse HEAD^1)
35-
git worktree add "$base" "$baseRev"
36-
echo "baseRev=$baseRev" >> "$GITHUB_ENV"
37-
echo "base=$base" >> "$GITHUB_ENV"
33+
target=$(mktemp -d)
34+
targetRev=$(git rev-parse HEAD^1)
35+
git worktree add "$target" "$targetRev"
36+
echo "targetRev=$targetRev" >> "$GITHUB_ENV"
37+
echo "target=$target" >> "$GITHUB_ENV"
38+
3839
- name: Get Nixpkgs revision for nixfmt
3940
run: |
4041
# pin to a commit from nixpkgs-unstable to avoid e.g. building nixfmt
4142
# from staging
4243
# This should not be a URL, because it would allow PRs to run arbitrary code in CI!
4344
rev=$(jq -r .rev ci/pinned-nixpkgs.json)
4445
echo "url=https://github.com/NixOS/nixpkgs/archive/$rev.tar.gz" >> "$GITHUB_ENV"
46+
4547
- uses: cachix/install-nix-action@08dcb3a5e62fa31e2da3d490afc4176ef55ecd72 # v30
4648
with:
47-
# explicitly enable sandbox
4849
extra_nix_config: sandbox = true
4950
nix_path: nixpkgs=${{ env.url }}
51+
5052
- name: Install nixfmt
5153
run: "nix-env -f '<nixpkgs>' -iAP nixfmt-rfc-style"
54+
5255
- name: Check that Nix files are formatted according to the RFC style
5356
run: |
5457
unformattedFiles=()
@@ -78,12 +81,12 @@ jobs:
7881
esac
7982
8083
# Ignore files that weren't already formatted
81-
if [[ -n "$source" ]] && ! nixfmt --check ${{ env.base }}/"$source" 2>/dev/null; then
82-
echo "Ignoring file $file because it's not formatted in the base commit"
84+
if [[ -n "$source" ]] && ! nixfmt --check ${{ env.target }}/"$source" 2>/dev/null; then
85+
echo "Ignoring file $file because it's not formatted in the target commit"
8386
elif ! nixfmt --check "$dest"; then
8487
unformattedFiles+=("$dest")
8588
fi
86-
done < <(git diff -z --name-status ${{ env.baseRev }} -- '*.nix')
89+
done < <(git diff -z --name-status ${{ env.targetRev }} -- '*.nix')
8790
8891
if (( "${#unformattedFiles[@]}" > 0 )); then
8992
echo "Some new/changed Nix files are not properly formatted"

.github/workflows/check-nixf-tidy.yml

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ name: Check changed Nix files with nixf-tidy (experimental)
33
on:
44
pull_request_target:
55
types: [opened, synchronize, reopened, edited]
6-
permissions:
7-
contents: read
6+
7+
permissions: {}
88

99
jobs:
1010
nixos:
@@ -14,32 +14,35 @@ jobs:
1414
steps:
1515
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
1616
with:
17-
# pull_request_target checks out the base branch by default
1817
ref: refs/pull/${{ github.event.pull_request.number }}/merge
1918
# Fetches the merge commit and its parents
2019
fetch-depth: 2
21-
- name: Checking out base branch
20+
21+
- name: Checking out target branch
2222
run: |
23-
base=$(mktemp -d)
24-
baseRev=$(git rev-parse HEAD^1)
25-
git worktree add "$base" "$baseRev"
26-
echo "baseRev=$baseRev" >> "$GITHUB_ENV"
27-
echo "base=$base" >> "$GITHUB_ENV"
23+
target=$(mktemp -d)
24+
targetRev=$(git rev-parse HEAD^1)
25+
git worktree add "$target" "$targetRev"
26+
echo "targetRev=$targetRev" >> "$GITHUB_ENV"
27+
echo "target=$target" >> "$GITHUB_ENV"
28+
2829
- name: Get Nixpkgs revision for nixf
2930
run: |
3031
# pin to a commit from nixpkgs-unstable to avoid e.g. building nixf
3132
# from staging
3233
# This should not be a URL, because it would allow PRs to run arbitrary code in CI!
3334
rev=$(jq -r .rev ci/pinned-nixpkgs.json)
3435
echo "url=https://github.com/NixOS/nixpkgs/archive/$rev.tar.gz" >> "$GITHUB_ENV"
36+
3537
- uses: cachix/install-nix-action@08dcb3a5e62fa31e2da3d490afc4176ef55ecd72 # v30
3638
with:
37-
# explicitly enable sandbox
3839
extra_nix_config: sandbox = true
3940
nix_path: nixpkgs=${{ env.url }}
41+
4042
- name: Install nixf and jq
4143
# provided jq is incompatible with our expression
4244
run: "nix-env -f '<nixpkgs>' -iAP nixf jq"
45+
4346
- name: Check that Nix files pass nixf-tidy
4447
run: |
4548
# Filtering error messages we don't like
@@ -85,8 +88,8 @@ jobs:
8588
continue
8689
esac
8790
88-
if [[ -n "$source" ]] && [[ "$(nixf_wrapper ${{ env.base }}/"$source")" != '[]' ]] 2>/dev/null; then
89-
echo "Ignoring file $file because it doesn't pass nixf-tidy in the base commit"
91+
if [[ -n "$source" ]] && [[ "$(nixf_wrapper ${{ env.target }}/"$source")" != '[]' ]] 2>/dev/null; then
92+
echo "Ignoring file $file because it doesn't pass nixf-tidy in the target commit"
9093
echo # insert blank line
9194
else
9295
nixf_report="$(nixf_wrapper "$dest")"
@@ -113,7 +116,7 @@ jobs:
113116
failedFiles+=("$dest")
114117
fi
115118
fi
116-
done < <(git diff -z --name-status ${{ env.baseRev }} -- '*.nix')
119+
done < <(git diff -z --name-status ${{ env.targetRev }} -- '*.nix')
117120
118121
if [[ -n "$DONT_REPORT_ERROR" ]]; then
119122
echo "Edited the PR but didn't change the base branch, only the description/title."

.github/workflows/check-shell.yml

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,25 @@ on:
99
permissions: {}
1010

1111
jobs:
12-
x86_64-linux:
13-
name: shell-check-x86_64-linux
14-
runs-on: ubuntu-24.04
15-
steps:
16-
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
17-
with:
18-
# pull_request_target checks out the base branch by default
19-
ref: refs/pull/${{ github.event.pull_request.number }}/merge
20-
- uses: cachix/install-nix-action@08dcb3a5e62fa31e2da3d490afc4176ef55ecd72 # v30
21-
- name: Build shell
22-
run: nix-build shell.nix
12+
shell-check:
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
include:
17+
- runner: ubuntu-24.04
18+
system: x86_64-linux
19+
- runner: macos-14
20+
system: aarch64-darwin
21+
22+
name: shell-check-${{ matrix.system }}
23+
runs-on: ${{ matrix.runner }}
2324

24-
aarch64-darwin:
25-
name: shell-check-aarch64-darwin
26-
runs-on: macos-14
2725
steps:
2826
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
2927
with:
30-
# pull_request_target checks out the base branch by default
3128
ref: refs/pull/${{ github.event.pull_request.number }}/merge
29+
3230
- uses: cachix/install-nix-action@08dcb3a5e62fa31e2da3d490afc4176ef55ecd72 # v30
31+
3332
- name: Build shell
3433
run: nix-build shell.nix

0 commit comments

Comments
 (0)