# This file was copied mostly from check-maintainers-sorted.yaml. # NOTE: Formatting with the RFC-style nixfmt command is not yet stable. See # https://github.com/NixOS/rfcs/pull/166. # Because of this, this action is not yet enabled for all files -- only for # those who have opted in. name: Check that Nix files are formatted on: pull_request_target: # See the comment at the same location in ./check-by-name.yml types: [opened, synchronize, reopened, edited] permissions: contents: read jobs: nixos: name: nixfmt-check runs-on: ubuntu-latest if: "!contains(github.event.pull_request.title, '[skip treewide]')" steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 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 - name: Checking out base branch run: | base=$(mktemp -d) baseRev=$(git rev-parse HEAD^1) git worktree add "$base" "$baseRev" echo "baseRev=$baseRev" >> "$GITHUB_ENV" echo "base=$base" >> "$GITHUB_ENV" - name: Get Nixpkgs revision for nixfmt run: | # pin to a commit from nixpkgs-unstable to avoid e.g. building nixfmt # from staging # This should not be a URL, because it would allow PRs to run arbitrary code in CI! rev=$(jq -r .rev ci/pinned-nixpkgs.json) echo "url=https://github.com/NixOS/nixpkgs/archive/$rev.tar.gz" >> "$GITHUB_ENV" - uses: cachix/install-nix-action@ba0dd844c9180cbf77aa72a116d6fbc515d0e87b # v27 with: # explicitly enable sandbox extra_nix_config: sandbox = true nix_path: nixpkgs=${{ env.url }} - name: Install nixfmt run: "nix-env -f '' -iAP nixfmt-rfc-style" - name: Check that Nix files are formatted according to the RFC style run: | unformattedFiles=() # TODO: Make this more parallel # Loop through all Nix files touched by the PR while readarray -d '' -n 2 entry && (( ${#entry[@]} != 0 )); do type=${entry[0]} file=${entry[1]} case $type in A*) source="" dest=$file ;; M*) source=$file dest=$file ;; C*|R*) source=$file read -r -d '' dest ;; *) echo "Ignoring file $file with type $type" continue esac # Ignore files that weren't already formatted if [[ -n "$source" ]] && ! nixfmt --check ${{ env.base }}/"$source" 2>/dev/null; then echo "Ignoring file $file because it's not formatted in the base commit" elif ! nixfmt --check "$dest"; then unformattedFiles+=("$dest") fi done < <(git diff -z --name-status ${{ env.baseRev }} -- '*.nix') if (( "${#unformattedFiles[@]}" > 0 )); then echo "Some new/changed Nix files are not properly formatted" echo "Please run the following in \`nix-shell\`:" echo "nixfmt ${unformattedFiles[*]@Q}" exit 1 fi