Skip to content

Commit

Permalink
workflows: add README
Browse files Browse the repository at this point in the history
This introduces some basic concepts used in these workflows and a common
terminology.

At the same time we remove some of the comments from various workflow
files, because they are assumed to be "general knowledge" through the
README.
  • Loading branch information
wolfgangwalther committed Jan 8, 2025
1 parent aafcc11 commit 648f47e
Show file tree
Hide file tree
Showing 14 changed files with 38 additions and 43 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# GitHub Actions Workflows

Some architectural notes about key decisions and concepts in our workflows:

- 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.

- 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.

- 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**.

- 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.

- 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.

## Terminology

- **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`.
- **head commit**: The HEAD commit in the pull request's branch. Same as `github.event.pull_request.head.sha`.
- **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`.
- **target commit**: The base branch's parent of the "test merge commit" to compare against.
5 changes: 1 addition & 4 deletions .github/workflows/check-maintainers-sorted.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ on:
paths:
- 'maintainers/maintainer-list.nix'

permissions:
contents: read
permissions: {}

jobs:
nixos:
Expand All @@ -15,7 +14,6 @@ jobs:
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
# pull_request_target checks out the base branch by default
ref: refs/pull/${{ github.event.pull_request.number }}/merge
# Only these directories to perform the check
sparse-checkout: |
Expand All @@ -24,7 +22,6 @@ jobs:
- uses: cachix/install-nix-action@08dcb3a5e62fa31e2da3d490afc4176ef55ecd72 # v30
with:
# explicitly enable sandbox
extra_nix_config: sandbox = true

- name: Check that maintainer-list.nix is sorted
Expand Down
6 changes: 1 addition & 5 deletions .github/workflows/check-nix-format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ name: Check that Nix files are formatted

on:
pull_request_target:
# See the comment at the same location in ./nixpkgs-vet.yml
types: [opened, synchronize, reopened, edited]

permissions:
contents: read
permissions: {}

jobs:
get-merge-commit:
Expand All @@ -26,7 +24,6 @@ jobs:
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
# pull_request_target checks out the base branch by default
ref: ${{ needs.get-merge-commit.outputs.mergedSha }}
# Fetches the merge commit and its parents
fetch-depth: 2
Expand All @@ -49,7 +46,6 @@ jobs:
- uses: cachix/install-nix-action@08dcb3a5e62fa31e2da3d490afc4176ef55ecd72 # v30
with:
# explicitly enable sandbox
extra_nix_config: sandbox = true
nix_path: nixpkgs=${{ env.url }}

Expand Down
5 changes: 1 addition & 4 deletions .github/workflows/check-nixf-tidy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ on:
pull_request_target:
types: [opened, synchronize, reopened, edited]

permissions:
contents: read
permissions: {}

jobs:
nixos:
Expand All @@ -15,7 +14,6 @@ jobs:
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
# pull_request_target checks out the base branch by default
ref: refs/pull/${{ github.event.pull_request.number }}/merge
# Fetches the merge commit and its parents
fetch-depth: 2
Expand All @@ -38,7 +36,6 @@ jobs:
- uses: cachix/install-nix-action@08dcb3a5e62fa31e2da3d490afc4176ef55ecd72 # v30
with:
# explicitly enable sandbox
extra_nix_config: sandbox = true
nix_path: nixpkgs=${{ env.url }}

Expand Down
1 change: 0 additions & 1 deletion .github/workflows/check-shell.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ jobs:
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
# pull_request_target checks out the base branch by default
ref: refs/pull/${{ github.event.pull_request.number }}/merge

- uses: cachix/install-nix-action@08dcb3a5e62fa31e2da3d490afc4176ef55ecd72 # v30
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/codeowners-v2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ on:
pull_request_target:
types: [opened, ready_for_review, synchronize, reopened, edited]

# We don't need any default GitHub token
permissions: {}

env:
Expand Down
6 changes: 1 addition & 5 deletions .github/workflows/editorconfig-v2.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
name: "Checking EditorConfig v2"

on:
# avoids approving first time contributors
pull_request_target:

permissions:
pull-requests: read
contents: read
permissions: {}

jobs:
get-merge-commit:
Expand All @@ -33,7 +30,6 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
# pull_request_target checks out the base branch by default
ref: ${{ needs.get-merge-commit.outputs.mergedSha }}

- uses: cachix/install-nix-action@08dcb3a5e62fa31e2da3d490afc4176ef55ecd72 # v30
Expand Down
5 changes: 1 addition & 4 deletions .github/workflows/eval-lib-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ on:
paths:
- 'lib/**'

permissions:
contents: read
permissions: {}

jobs:
get-merge-commit:
Expand All @@ -20,12 +19,10 @@ jobs:
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
# pull_request_target checks out the base branch by default
ref: ${{ needs.get-merge-commit.outputs.mergedSha }}

- uses: cachix/install-nix-action@08dcb3a5e62fa31e2da3d490afc4176ef55ecd72 # v30
with:
# explicitly enable sandbox
extra_nix_config: sandbox = true

- name: Building Nixpkgs lib-tests
Expand Down
12 changes: 9 additions & 3 deletions .github/workflows/eval.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ on:
- haskell-updates
- python-updates

permissions:
contents: read
permissions: {}

jobs:
get-merge-commit:
Expand All @@ -23,7 +22,6 @@ jobs:
name: Attributes
runs-on: ubuntu-24.04
needs: get-merge-commit
# Skip this and dependent steps if the PR can't be merged
if: needs.get-merge-commit.outputs.mergedSha
outputs:
targetSha: ${{ steps.targetSha.outputs.targetSha }}
Expand All @@ -45,6 +43,8 @@ jobs:
- name: Install Nix
uses: cachix/install-nix-action@08dcb3a5e62fa31e2da3d490afc4176ef55ecd72 # v30
with:
extra_nix_config: sandbox = true

- name: Evaluate the list of all attributes and get the systems matrix
id: systems
Expand All @@ -71,6 +71,8 @@ jobs:

- name: Install Nix
uses: cachix/install-nix-action@08dcb3a5e62fa31e2da3d490afc4176ef55ecd72 # v30
with:
extra_nix_config: sandbox = true

- name: Query nixpkgs with aliases enabled to check for basic syntax errors
run: |
Expand Down Expand Up @@ -106,6 +108,8 @@ jobs:

- name: Install Nix
uses: cachix/install-nix-action@08dcb3a5e62fa31e2da3d490afc4176ef55ecd72 # v30
with:
extra_nix_config: sandbox = true

- name: Evaluate the ${{ matrix.system }} output paths for all derivation attributes
env:
Expand Down Expand Up @@ -145,6 +149,8 @@ jobs:

- name: Install Nix
uses: cachix/install-nix-action@08dcb3a5e62fa31e2da3d490afc4176ef55ecd72 # v30
with:
extra_nix_config: sandbox = true

- name: Combine all output paths and eval stats
run: |
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/get-merge-commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ on:
description: "The merge commit SHA"
value: ${{ jobs.resolve-merge-commit.outputs.mergedSha }}

# We need a token to query the API, but it doesn't need any special permissions
permissions: {}

jobs:
Expand Down
5 changes: 1 addition & 4 deletions .github/workflows/manual-nixos-v2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ on:
paths:
- 'nixos/**'

permissions:
contents: read
permissions: {}

jobs:
nixos:
Expand All @@ -17,12 +16,10 @@ jobs:
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
# pull_request_target checks out the base branch by default
ref: refs/pull/${{ github.event.pull_request.number }}/merge

- uses: cachix/install-nix-action@08dcb3a5e62fa31e2da3d490afc4176ef55ecd72 # v30
with:
# explicitly enable sandbox
extra_nix_config: sandbox = true

- uses: cachix/cachix-action@ad2ddac53f961de1989924296a1f236fcfbaa4fc # v15
Expand Down
5 changes: 1 addition & 4 deletions .github/workflows/manual-nixpkgs-v2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ on:
- 'lib/**'
- 'pkgs/tools/nix/nixdoc/**'

permissions:
contents: read
permissions: {}

jobs:
nixpkgs:
Expand All @@ -19,12 +18,10 @@ jobs:
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
# pull_request_target checks out the base branch by default
ref: refs/pull/${{ github.event.pull_request.number }}/merge

- uses: cachix/install-nix-action@08dcb3a5e62fa31e2da3d490afc4176ef55ecd72 # v30
with:
# explicitly enable sandbox
extra_nix_config: sandbox = true

- uses: cachix/cachix-action@ad2ddac53f961de1989924296a1f236fcfbaa4fc # v15
Expand Down
7 changes: 2 additions & 5 deletions .github/workflows/nix-parse-v2.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
name: "Check whether nix files are parseable v2"

on:
# avoids approving first time contributors
pull_request_target:

permissions:
pull-requests: read
contents: read
permissions: {}

jobs:
get-merge-commit:
Expand All @@ -32,12 +29,12 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
# pull_request_target checks out the base branch by default
ref: ${{ needs.get-merge-commit.outputs.mergedSha }}
if: ${{ env.CHANGED_FILES && env.CHANGED_FILES != '' }}

- uses: cachix/install-nix-action@08dcb3a5e62fa31e2da3d490afc4176ef55ecd72 # v30
with:
extra_nix_config: sandbox = true
nix_path: nixpkgs=channel:nixpkgs-unstable

- name: Parse all changed or added nix files
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/nixpkgs-vet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
name: Vet nixpkgs

on:
# Using pull_request_target instead of pull_request avoids having to approve first time contributors.
pull_request_target:
# This workflow depends on the base branch of the PR, but changing the base branch is not included in the default trigger events, which would be `opened`, `synchronize` or `reopened`.
# Instead it causes an `edited` event, so we need to add it explicitly here.
Expand Down Expand Up @@ -34,7 +33,6 @@ jobs:
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
# pull_request_target checks out the base branch by default
ref: ${{ needs.get-merge-commit.outputs.mergedSha }}
# Fetches the merge commit and its parents
fetch-depth: 2
Expand Down

0 comments on commit 648f47e

Please sign in to comment.