From 3869ba41274265150be6f9e233ae5f8f35f867ee Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Sat, 16 Dec 2023 03:01:03 +0100 Subject: [PATCH 1/8] workflows/check-by-name: Move tool fetching into script This part of the CI can also be reproduced locally --- .github/workflows/check-by-name.yml | 36 +-------------- .../scripts/fetch-tool.sh | 45 +++++++++++++++++++ 2 files changed, 47 insertions(+), 34 deletions(-) create mode 100755 pkgs/test/nixpkgs-check-by-name/scripts/fetch-tool.sh diff --git a/.github/workflows/check-by-name.yml b/.github/workflows/check-by-name.yml index 294775fa1c8e2..43237d36bee1b 100644 --- a/.github/workflows/check-by-name.yml +++ b/.github/workflows/check-by-name.yml @@ -79,40 +79,8 @@ jobs: echo "headSha=$(git rev-parse HEAD^2)" >> "$GITHUB_ENV" - uses: cachix/install-nix-action@7ac1ec25491415c381d9b62f0657c7a028df52a7 # v24 - - name: Determining channel to use for dependencies - run: | - echo "Determining the preferred channel to use for PR base branch $GITHUB_BASE_REF" - if [[ "$GITHUB_BASE_REF" =~ ^(release|staging|staging-next)-([0-9][0-9]\.[0-9][0-9])$ ]]; then - # Use the release channel for all PRs to release-XX.YY, staging-XX.YY and staging-next-XX.YY - channel=nixos-${BASH_REMATCH[2]} - echo "PR is for a release branch, preferred channel is $channel" - else - # Use the nixos-unstable channel for all other PRs - channel=nixos-unstable - echo "PR is for a non-release branch, preferred channel is $channel" - fi - # Check that the channel exists. It doesn't exist for fresh release branches - if ! curl -fSs "https://channels.nixos.org/$channel"; then - # Fall back to nixos-unstable, makes sense for fresh release branches - echo "Preferred channel $channel could not be fetched, falling back to nixos-unstable" - channel=nixos-unstable - fi - echo "channel=$channel" >> "$GITHUB_ENV" - - name: Fetching latest version of channel - run: | - echo "Fetching latest version of channel $channel" - # This is probably the easiest way to get Nix to output the path to a downloaded channel! - nixpkgs=$(nix-instantiate --find-file nixpkgs -I nixpkgs=channel:"$channel") - # This file only exists in channels - rev=$(<"$nixpkgs"/.git-revision) - echo "Channel $channel is at revision $rev" - echo "nixpkgs=$nixpkgs" >> "$GITHUB_ENV" - echo "rev=$rev" >> "$GITHUB_ENV" - - name: Fetching pre-built nixpkgs-check-by-name from the channel - run: | - echo "Fetching pre-built nixpkgs-check-by-name from channel $channel at revision $rev" - # Passing --max-jobs 0 makes sure that we won't build anything - nix-build "$nixpkgs" -A tests.nixpkgs-check-by-name --max-jobs 0 + - name: Fetching the tool + run: pkgs/test/nixpkgs-check-by-name/scripts/fetch-tool.sh "$GITHUB_BASE_REF" result - name: Running nixpkgs-check-by-name run: | echo "Checking whether the check succeeds on the base branch $GITHUB_BASE_REF" diff --git a/pkgs/test/nixpkgs-check-by-name/scripts/fetch-tool.sh b/pkgs/test/nixpkgs-check-by-name/scripts/fetch-tool.sh new file mode 100755 index 0000000000000..fc4df11e747e6 --- /dev/null +++ b/pkgs/test/nixpkgs-check-by-name/scripts/fetch-tool.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +# Fetches the prebuilt nixpkgs-check-by-name to use from +# the NixOS channel corresponding to the given base branch + +set -euo pipefail + +if (( $# < 2 )); then + echo >&2 "Usage: $0 BASE_BRANCH OUTPUT_PATH" + echo >&2 "BASE_BRANCH: The base branch to use, e.g. master or release-23.11" + echo >&2 "OUTPUT_PATH: The output symlink path for the tool" + exit 1 +fi +baseBranch=$1 +output=$2 + +echo >&2 -n "Determining the channel to use for PR base branch $baseBranch.. " +if [[ "$baseBranch" =~ ^(release|staging|staging-next)-([0-9][0-9]\.[0-9][0-9])$ ]]; then + # Use the release channel for all PRs to release-XX.YY, staging-XX.YY and staging-next-XX.YY + preferredChannel=nixos-${BASH_REMATCH[2]} +else + # Use the nixos-unstable channel for all other PRs + preferredChannel=nixos-unstable +fi + +# Check that the channel exists. It doesn't exist for fresh release branches +if curl -fSs "https://channels.nixos.org/$preferredChannel"; then + channel=$preferredChannel + echo >&2 "$channel" +else + # Fall back to nixos-unstable, makes sense for fresh release branches + channel=nixos-unstable + echo >&2 -e "\e[33mWarning: Preferred channel $preferredChannel could not be fetched, using fallback: $channel\e[0m" +fi + +echo >&2 -n "Fetching latest version of channel $channel.. " +# This is probably the easiest way to get Nix to output the path to a downloaded channel! +nixpkgs=$(nix-instantiate --find-file nixpkgs -I nixpkgs=channel:"$channel") +echo >&2 "$nixpkgs" + +# This file only exists in channels +echo >&2 -e "Git revision of channel $channel is \e[34m$(<"$nixpkgs/.git-revision")\e[0m" + +echo >&2 -n "Fetching the prebuilt version of nixpkgs-check-by-name.. " +nix-build -o "$output" "$nixpkgs" -A tests.nixpkgs-check-by-name -j 0 >/dev/null +realpath >&2 "$output" From c6267887db1379c3854c4f604b121b6ff7560a7a Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Sat, 16 Dec 2023 03:02:33 +0100 Subject: [PATCH 2/8] workflows/check-by-name: Why the mergeability check needs to be inline --- .github/workflows/check-by-name.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/check-by-name.yml b/.github/workflows/check-by-name.yml index 43237d36bee1b..0fce2c37746ce 100644 --- a/.github/workflows/check-by-name.yml +++ b/.github/workflows/check-by-name.yml @@ -20,6 +20,9 @@ jobs: # The default of 6 hours is definitely too long timeout-minutes: 10 steps: + # This step has to be in this file, + # because it's needed to determine which revision of the repository to fetch, + # and we can only use other files from the repository once it's fetched. - name: Resolving the merge commit env: GH_TOKEN: ${{ github.token }} From 92238ac52d13f6af1158eb8ae0b1132c79cdef33 Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Sat, 16 Dec 2023 03:13:12 +0100 Subject: [PATCH 3/8] tests.nixpkgs-check-by-name: Create script to run locally Due to the check soon depending on the base branch (see `--base`), the CI check can't reasonably share all code with a local check. We can still make a script to run it locally, just not sharing all code. --- pkgs/by-name/README.md | 11 ++-- .../scripts/run-local.sh | 66 +++++++++++++++++++ 2 files changed, 71 insertions(+), 6 deletions(-) create mode 100755 pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh diff --git a/pkgs/by-name/README.md b/pkgs/by-name/README.md index a7cdc57201df2..948003bb55730 100644 --- a/pkgs/by-name/README.md +++ b/pkgs/by-name/README.md @@ -112,12 +112,11 @@ There's some limitations as to which packages can be defined using this structur CI performs [certain checks](../test/nixpkgs-check-by-name/README.md#validity-checks) on the `pkgs/by-name` structure. This is done using the [`nixpkgs-check-by-name` tool](../test/nixpkgs-check-by-name). -The version of this tool used is the one that corresponds to the NixOS channel of the PR base branch. -See [here](../../.github/workflows/check-by-name.yml) for details. -The tool can be run locally using +You can locally emulate the CI check using -```bash -nix-build -A tests.nixpkgs-check-by-name -result/bin/nixpkgs-check-by-name . ``` +$ ./pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh master +``` + +See [here](../../.github/workflows/check-by-name.yml) for more info. diff --git a/pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh b/pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh new file mode 100755 index 0000000000000..a1debe73f8ad8 --- /dev/null +++ b/pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +# shellcheck disable=SC2016 + +set -euo pipefail + +cleanup_commands=() +cleanup() { + echo -n >&2 "Cleaning up.. " + # Run all cleanup commands in inverse order + for (( i=${#cleanup_commands[@]}-1; i>=0; i-- )); do + eval "${cleanup_commands[i]}" + done + echo >&2 "Done" +} +trap cleanup exit + +tmp=$(mktemp -d) +cleanup_commands+=('rmdir "$tmp"') + +repo=https://github.com/NixOS/nixpkgs.git + +if (( $# != 0 )); then + baseBranch=$1 + shift +else + echo >&2 "Usage: $0 BASE_BRANCH [REPOSITORY]" + echo >&2 "BASE_BRANCH: The base branch to use, e.g. master or release-23.11" + echo >&2 "REPOSITORY: The repository to fetch the base branch from, defaults to $repo" + exit 1 +fi + +if (( $# != 0 )); then + repo=$1 + shift +fi + +if [[ -n "$(git status --porcelain)" ]]; then + echo >&2 -e "\e[33mWarning: Dirty tree, uncommitted changes won't be taken into account\e[0m" +fi +headSha=$(git rev-parse HEAD) +echo >&2 -e "Using HEAD commit \e[34m$headSha\e[0m" + +echo >&2 -n "Creating Git worktree for the HEAD commit in $tmp/merged.. " +git worktree add --detach -q "$tmp/merged" HEAD +cleanup_commands+=('git worktree remove --force "$tmp/merged"') +echo >&2 "Done" + +echo >&2 -n "Fetching base branch $baseBranch to compare against.. " +git fetch -q "$repo" refs/heads/"$baseBranch" +baseSha=$(git rev-parse FETCH_HEAD) +echo >&2 -e "\e[34m$baseSha\e[0m" + +echo >&2 -n "Creating Git worktree for the base branch in $tmp/base.. " +git worktree add -q "$tmp/base" "$baseSha" +cleanup_commands+=('git worktree remove --force "$tmp/base"') +echo >&2 "Done" + +echo >&2 -n "Merging base branch into the HEAD commit in $tmp/merged.. " +git -C "$tmp/merged" merge -q --no-edit "$baseSha" +echo >&2 -e "\e[34m$(git -C "$tmp/merged" rev-parse HEAD)\e[0m" + +"$tmp/merged/pkgs/test/nixpkgs-check-by-name/scripts/fetch-tool.sh" "$baseBranch" "$tmp/tool" +cleanup_commands+=('rm "$tmp/tool"') + +echo >&2 "Running nixpkgs-check-by-name.." +"$tmp/tool/bin/nixpkgs-check-by-name" "$tmp/merged" From 9e03178865ea627413005b3fe82d3b287209d12f Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Tue, 19 Dec 2023 23:13:11 +0100 Subject: [PATCH 4/8] tests.nixpkgs-check-by-name: Add documentation for scripts --- .../nixpkgs-check-by-name/scripts/README.md | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 pkgs/test/nixpkgs-check-by-name/scripts/README.md diff --git a/pkgs/test/nixpkgs-check-by-name/scripts/README.md b/pkgs/test/nixpkgs-check-by-name/scripts/README.md new file mode 100644 index 0000000000000..41b3012b7d953 --- /dev/null +++ b/pkgs/test/nixpkgs-check-by-name/scripts/README.md @@ -0,0 +1,26 @@ +# CI-related Scripts + +This directory contains scripts used and related to the CI running the `pkgs/by-name` checks in Nixpkgs. See also the [CI GitHub Action](../../../../.github/workflows/check-by-name.yml). + +## `./run-local.sh BASE_BRANCH [REPOSITORY]` + +Runs the `pkgs/by-name` check on the HEAD commit, closely matching what CI does. + +Note that this can't do exactly the same as CI, +because CI needs to rely on GitHub's server-side Git history to compute the mergeability of PRs before the check can be started. +In turn when running locally, we don't want to have to push commits to test them, +and we can also rely on the local Git history to do the mergeability check. + +Arguments: +- `BASE_BRANCH`: The base branch to use, e.g. master or release-23.11 +- `REPOSITORY`: The repository to fetch the base branch from, defaults to https://github.com/NixOS/nixpkgs.git + +## `./fetch-tool.sh BASE_BRANCH OUTPUT_PATH` + +Fetches the Hydra-prebuilt nixpkgs-check-by-name to use from the NixOS channel corresponding to the given base branch. + +This script is used both by [`./run-local.sh`](#run-local-sh-base-branch-repository) and CI. + +Arguments: +- `BASE_BRANCH`: The base branch to use, e.g. master or release-23.11 +- `OUTPUT_PATH`: The output symlink path for the tool From 1ad45e503f3acdcb3df214b58d289511ddf2eff8 Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Sat, 16 Dec 2023 03:13:35 +0100 Subject: [PATCH 5/8] workflows/check-by-name: Slim down and prepare for --base Now that we have a script to run the check locally, there's no real need to output the information to reproduce anymore, which allows cleaning up the CI workflow. Furthermore, this prepares the CI workflow to be passed `--base`, as introduced recently. --- .github/workflows/check-by-name.yml | 92 ++++------------------------- 1 file changed, 11 insertions(+), 81 deletions(-) diff --git a/.github/workflows/check-by-name.yml b/.github/workflows/check-by-name.yml index 0fce2c37746ce..c006ffc78f56b 100644 --- a/.github/workflows/check-by-name.yml +++ b/.github/workflows/check-by-name.yml @@ -1,5 +1,7 @@ # Checks pkgs/by-name (see pkgs/by-name/README.md) # using the nixpkgs-check-by-name tool (see pkgs/test/nixpkgs-check-by-name) +# +# When you make changes to this workflow, also update pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh adequately name: Check pkgs/by-name # The pre-built tool is fetched from a channel, @@ -75,92 +77,20 @@ jobs: ref: ${{ env.mergedSha }} # Fetches the merge commit and its parents fetch-depth: 2 - - name: Determining PR git hashes + - name: Checking out base branch run: | - # For pull_request_target this is the same as $GITHUB_SHA - echo "baseSha=$(git rev-parse HEAD^1)" >> "$GITHUB_ENV" - - echo "headSha=$(git rev-parse HEAD^2)" >> "$GITHUB_ENV" + base=$(mktemp -d) + git worktree add "$base" "$(git rev-parse HEAD^1)" + echo "base=$base" >> "$GITHUB_ENV" - uses: cachix/install-nix-action@7ac1ec25491415c381d9b62f0657c7a028df52a7 # v24 - name: Fetching the tool run: pkgs/test/nixpkgs-check-by-name/scripts/fetch-tool.sh "$GITHUB_BASE_REF" result - name: Running nixpkgs-check-by-name run: | - echo "Checking whether the check succeeds on the base branch $GITHUB_BASE_REF" - git checkout -q "$baseSha" - if baseOutput=$(result/bin/nixpkgs-check-by-name . 2>&1); then - baseSuccess=1 + if result/bin/nixpkgs-check-by-name .; then + exit 0 else - baseSuccess= + exitCode=$? + echo "To run locally: ./pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh $GITHUB_BASE_REF https://github.com/$GITHUB_REPOSITORY.git" + exit "$exitCode" fi - printf "%s\n" "$baseOutput" - - echo "Checking whether the check would succeed after merging this pull request" - git checkout -q "$mergedSha" - if mergedOutput=$(result/bin/nixpkgs-check-by-name . 2>&1); then - mergedSuccess=1 - exitCode=0 - else - mergedSuccess= - exitCode=1 - fi - printf "%s\n" "$mergedOutput" - - resultToEmoji() { - if [[ -n "$1" ]]; then - echo ":heavy_check_mark:" - else - echo ":x:" - fi - } - - # Print a markdown summary in GitHub actions - { - echo "| Nixpkgs version | Check result |" - echo "| --- | --- |" - echo "| Latest base commit | $(resultToEmoji "$baseSuccess") |" - echo "| After merging this PR | $(resultToEmoji "$mergedSuccess") |" - echo "" - - if [[ -n "$baseSuccess" ]]; then - if [[ -n "$mergedSuccess" ]]; then - echo "The check succeeds on both the base branch and after merging this PR" - else - echo "The check succeeds on the base branch, but would fail after merging this PR:" - echo "\`\`\`" - echo "$mergedOutput" - echo "\`\`\`" - echo "" - fi - else - if [[ -n "$mergedSuccess" ]]; then - echo "The check fails on the base branch, but this PR fixes it, nicely done!" - else - echo "The check fails on both the base branch and after merging this PR, unknown if only this PRs changes would satisfy the check, the base branch needs to be fixed first." - echo "" - echo "Failure on the base branch:" - echo "\`\`\`" - echo "$baseOutput" - echo "\`\`\`" - echo "" - echo "Failure after merging this PR:" - echo "\`\`\`" - echo "$mergedOutput" - echo "\`\`\`" - echo "" - fi - fi - - echo "### Details" - echo "- nixpkgs-check-by-name tool:" - echo " - Channel: $channel" - echo " - Nixpkgs commit: [$rev](https://github.com/${GITHUB_REPOSITORY}/commit/$rev)" - echo " - Store path: \`$(realpath result)\`" - echo "- Tested Nixpkgs:" - echo " - Base branch: $GITHUB_BASE_REF" - echo " - Latest base branch commit: [$baseSha](https://github.com/${GITHUB_REPOSITORY}/commit/$baseSha)" - echo " - Latest PR commit: [$headSha](https://github.com/${GITHUB_REPOSITORY}/commit/$headSha)" - echo " - Merge commit: [$mergedSha](https://github.com/${GITHUB_REPOSITORY}/commit/$mergedSha)" - } >> "$GITHUB_STEP_SUMMARY" - - exit "$exitCode" From 1968beeabd763cec23ab7164342a4193214791c7 Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Tue, 19 Dec 2023 23:12:41 +0100 Subject: [PATCH 6/8] check-by-name: Pass --base in CI and local running script This enables the ratchet checks for pkgs/by-name, allowing gradual migrations! --- .github/workflows/check-by-name.yml | 2 +- pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/check-by-name.yml b/.github/workflows/check-by-name.yml index c006ffc78f56b..a761f6cae09bb 100644 --- a/.github/workflows/check-by-name.yml +++ b/.github/workflows/check-by-name.yml @@ -87,7 +87,7 @@ jobs: run: pkgs/test/nixpkgs-check-by-name/scripts/fetch-tool.sh "$GITHUB_BASE_REF" result - name: Running nixpkgs-check-by-name run: | - if result/bin/nixpkgs-check-by-name .; then + if result/bin/nixpkgs-check-by-name --base "$base" .; then exit 0 else exitCode=$? diff --git a/pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh b/pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh index a1debe73f8ad8..060f83469f4df 100755 --- a/pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh +++ b/pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh @@ -63,4 +63,4 @@ echo >&2 -e "\e[34m$(git -C "$tmp/merged" rev-parse HEAD)\e[0m" cleanup_commands+=('rm "$tmp/tool"') echo >&2 "Running nixpkgs-check-by-name.." -"$tmp/tool/bin/nixpkgs-check-by-name" "$tmp/merged" +"$tmp/tool/bin/nixpkgs-check-by-name" --base "$tmp/base" "$tmp/merged" From f882df781ca7eab4ee66fa31dda445937ccaedd3 Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Thu, 21 Dec 2023 23:09:50 +0100 Subject: [PATCH 7/8] maintainers/scripts/check-by-name.sh: Introduce symlink alias --- .github/workflows/check-by-name.yml | 2 +- maintainers/scripts/README.md | 4 ++++ maintainers/scripts/check-by-name.sh | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) create mode 120000 maintainers/scripts/check-by-name.sh diff --git a/.github/workflows/check-by-name.yml b/.github/workflows/check-by-name.yml index a761f6cae09bb..06fefcb6759ba 100644 --- a/.github/workflows/check-by-name.yml +++ b/.github/workflows/check-by-name.yml @@ -91,6 +91,6 @@ jobs: exit 0 else exitCode=$? - echo "To run locally: ./pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh $GITHUB_BASE_REF https://github.com/$GITHUB_REPOSITORY.git" + echo "To run locally: ./maintainers/scripts/check-by-name.sh $GITHUB_BASE_REF https://github.com/$GITHUB_REPOSITORY.git" exit "$exitCode" fi diff --git a/maintainers/scripts/README.md b/maintainers/scripts/README.md index 2b99a4e751141..f8fc7aff955d3 100644 --- a/maintainers/scripts/README.md +++ b/maintainers/scripts/README.md @@ -9,6 +9,10 @@ What follows is a (very incomplete) overview of available scripts. ## Metadata +### `check-by-name.sh` + +An alias for `pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh`, see [documentation](../../pkgs/test/nixpkgs-check-by-name/scripts/README.md). + ### `get-maintainer.sh` `get-maintainer.sh [selector] value` returns a JSON object describing diff --git a/maintainers/scripts/check-by-name.sh b/maintainers/scripts/check-by-name.sh new file mode 120000 index 0000000000000..545dbedf0a317 --- /dev/null +++ b/maintainers/scripts/check-by-name.sh @@ -0,0 +1 @@ +../../pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh \ No newline at end of file From e130ee33a11ae90585e9f9c09b189c3ccfe70632 Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Thu, 21 Dec 2023 23:05:14 +0100 Subject: [PATCH 8/8] pkgs/test/nixpkgs-check-by-name/scripts: Various improvements - trace function, avoids littering `echo >&2` all throughout - Avoid `eval`, remove unneeded shellcheck Co-Authored-By: Victor Engmark --- .../scripts/fetch-tool.sh | 26 +++++---- .../scripts/run-local.sh | 57 ++++++++++--------- 2 files changed, 43 insertions(+), 40 deletions(-) diff --git a/pkgs/test/nixpkgs-check-by-name/scripts/fetch-tool.sh b/pkgs/test/nixpkgs-check-by-name/scripts/fetch-tool.sh index fc4df11e747e6..19a48b6fb1fd5 100755 --- a/pkgs/test/nixpkgs-check-by-name/scripts/fetch-tool.sh +++ b/pkgs/test/nixpkgs-check-by-name/scripts/fetch-tool.sh @@ -2,18 +2,20 @@ # Fetches the prebuilt nixpkgs-check-by-name to use from # the NixOS channel corresponding to the given base branch -set -euo pipefail +set -o pipefail -o errexit -o nounset + +trace() { echo >&2 "$@"; } if (( $# < 2 )); then - echo >&2 "Usage: $0 BASE_BRANCH OUTPUT_PATH" - echo >&2 "BASE_BRANCH: The base branch to use, e.g. master or release-23.11" - echo >&2 "OUTPUT_PATH: The output symlink path for the tool" + trace "Usage: $0 BASE_BRANCH OUTPUT_PATH" + trace "BASE_BRANCH: The base branch to use, e.g. master or release-23.11" + trace "OUTPUT_PATH: The output symlink path for the tool" exit 1 fi baseBranch=$1 output=$2 -echo >&2 -n "Determining the channel to use for PR base branch $baseBranch.. " +trace -n "Determining the channel to use for PR base branch $baseBranch.. " if [[ "$baseBranch" =~ ^(release|staging|staging-next)-([0-9][0-9]\.[0-9][0-9])$ ]]; then # Use the release channel for all PRs to release-XX.YY, staging-XX.YY and staging-next-XX.YY preferredChannel=nixos-${BASH_REMATCH[2]} @@ -25,21 +27,21 @@ fi # Check that the channel exists. It doesn't exist for fresh release branches if curl -fSs "https://channels.nixos.org/$preferredChannel"; then channel=$preferredChannel - echo >&2 "$channel" + trace "$channel" else # Fall back to nixos-unstable, makes sense for fresh release branches channel=nixos-unstable - echo >&2 -e "\e[33mWarning: Preferred channel $preferredChannel could not be fetched, using fallback: $channel\e[0m" + trace -e "\e[33mWarning: Preferred channel $preferredChannel could not be fetched, using fallback: $channel\e[0m" fi -echo >&2 -n "Fetching latest version of channel $channel.. " +trace -n "Fetching latest version of channel $channel.. " # This is probably the easiest way to get Nix to output the path to a downloaded channel! nixpkgs=$(nix-instantiate --find-file nixpkgs -I nixpkgs=channel:"$channel") -echo >&2 "$nixpkgs" +trace "$nixpkgs" # This file only exists in channels -echo >&2 -e "Git revision of channel $channel is \e[34m$(<"$nixpkgs/.git-revision")\e[0m" +trace -e "Git revision of channel $channel is \e[34m$(<"$nixpkgs/.git-revision")\e[0m" -echo >&2 -n "Fetching the prebuilt version of nixpkgs-check-by-name.. " +trace -n "Fetching the prebuilt version of nixpkgs-check-by-name.. " nix-build -o "$output" "$nixpkgs" -A tests.nixpkgs-check-by-name -j 0 >/dev/null -realpath >&2 "$output" +realpath "$output" >&2 diff --git a/pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh b/pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh index 060f83469f4df..72d3e8dc3de39 100755 --- a/pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh +++ b/pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh @@ -1,21 +1,25 @@ #!/usr/bin/env bash -# shellcheck disable=SC2016 -set -euo pipefail +set -o pipefail -o errexit -o nounset -cleanup_commands=() +trace() { echo >&2 "$@"; } + +tmp=$(mktemp -d) cleanup() { - echo -n >&2 "Cleaning up.. " - # Run all cleanup commands in inverse order - for (( i=${#cleanup_commands[@]}-1; i>=0; i-- )); do - eval "${cleanup_commands[i]}" - done - echo >&2 "Done" + # Don't exit early if anything fails to cleanup + set +o errexit + + trace -n "Cleaning up.. " + + [[ -e "$tmp/base" ]] && git worktree remove --force "$tmp/base" + [[ -e "$tmp/merged" ]] && git worktree remove --force "$tmp/merged" + + rm -rf "$tmp" + + trace "Done" } trap cleanup exit -tmp=$(mktemp -d) -cleanup_commands+=('rmdir "$tmp"') repo=https://github.com/NixOS/nixpkgs.git @@ -23,9 +27,9 @@ if (( $# != 0 )); then baseBranch=$1 shift else - echo >&2 "Usage: $0 BASE_BRANCH [REPOSITORY]" - echo >&2 "BASE_BRANCH: The base branch to use, e.g. master or release-23.11" - echo >&2 "REPOSITORY: The repository to fetch the base branch from, defaults to $repo" + trace "Usage: $0 BASE_BRANCH [REPOSITORY]" + trace "BASE_BRANCH: The base branch to use, e.g. master or release-23.11" + trace "REPOSITORY: The repository to fetch the base branch from, defaults to $repo" exit 1 fi @@ -35,32 +39,29 @@ if (( $# != 0 )); then fi if [[ -n "$(git status --porcelain)" ]]; then - echo >&2 -e "\e[33mWarning: Dirty tree, uncommitted changes won't be taken into account\e[0m" + trace -e "\e[33mWarning: Dirty tree, uncommitted changes won't be taken into account\e[0m" fi headSha=$(git rev-parse HEAD) -echo >&2 -e "Using HEAD commit \e[34m$headSha\e[0m" +trace -e "Using HEAD commit \e[34m$headSha\e[0m" -echo >&2 -n "Creating Git worktree for the HEAD commit in $tmp/merged.. " +trace -n "Creating Git worktree for the HEAD commit in $tmp/merged.. " git worktree add --detach -q "$tmp/merged" HEAD -cleanup_commands+=('git worktree remove --force "$tmp/merged"') -echo >&2 "Done" +trace "Done" -echo >&2 -n "Fetching base branch $baseBranch to compare against.. " +trace -n "Fetching base branch $baseBranch to compare against.. " git fetch -q "$repo" refs/heads/"$baseBranch" baseSha=$(git rev-parse FETCH_HEAD) -echo >&2 -e "\e[34m$baseSha\e[0m" +trace -e "\e[34m$baseSha\e[0m" -echo >&2 -n "Creating Git worktree for the base branch in $tmp/base.. " +trace -n "Creating Git worktree for the base branch in $tmp/base.. " git worktree add -q "$tmp/base" "$baseSha" -cleanup_commands+=('git worktree remove --force "$tmp/base"') -echo >&2 "Done" +trace "Done" -echo >&2 -n "Merging base branch into the HEAD commit in $tmp/merged.. " +trace -n "Merging base branch into the HEAD commit in $tmp/merged.. " git -C "$tmp/merged" merge -q --no-edit "$baseSha" -echo >&2 -e "\e[34m$(git -C "$tmp/merged" rev-parse HEAD)\e[0m" +trace -e "\e[34m$(git -C "$tmp/merged" rev-parse HEAD)\e[0m" "$tmp/merged/pkgs/test/nixpkgs-check-by-name/scripts/fetch-tool.sh" "$baseBranch" "$tmp/tool" -cleanup_commands+=('rm "$tmp/tool"') -echo >&2 "Running nixpkgs-check-by-name.." +trace "Running nixpkgs-check-by-name.." "$tmp/tool/bin/nixpkgs-check-by-name" --base "$tmp/base" "$tmp/merged"