Commit 927521a6 authored by Silvan Mosberger's avatar Silvan Mosberger Committed by Silvan Mosberger
Browse files

workflows/check-nix-format: Enforce formatting on all files

Changes the Nix format checking workflow to now strictly enforce
formatting of all Nix files using the treefmt setup introduced
in the pre-previous commit.

This is in [accordance with the approved RFC 166](https://github.com/NixOS/rfcs/blob/master/rfcs/0166-nix-formatting.md#reformat-nixpkgs).

Note that the "skip treewide" thing is no longer necessary, already
before, because there's nothing that would fail for treewide changes.
Previously the problem was that the GitHub API would be bombarded.
parent 5a8296d7
Loading
Loading
Loading
Loading
+13 −69
Original line number Diff line number Diff line
# 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.
# NOTE: Formatting with the RFC-style nixfmt command is not yet stable.
# See https://github.com/NixOS/rfcs/pull/166.

name: Check that Nix files are formatted

@@ -20,80 +17,27 @@ jobs:
    name: nixfmt-check
    runs-on: ubuntu-24.04
    needs: get-merge-commit
    if: "needs.get-merge-commit.outputs.mergedSha && !contains(github.event.pull_request.title, '[skip treewide]')"
    if: needs.get-merge-commit.outputs.mergedSha
    steps:
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
        with:
          ref: ${{ needs.get-merge-commit.outputs.mergedSha }}
          # Fetches the merge commit and its parents
          fetch-depth: 2

      - name: Checking out target branch
        run: |
          target=$(mktemp -d)
          targetRev=$(git rev-parse HEAD^1)
          git worktree add "$target" "$targetRev"
          echo "targetRev=$targetRev" >> "$GITHUB_ENV"
          echo "target=$target" >> "$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@02a151ada4993995686f9ed4f1be7cfbb229e56f # v31
        with:
          extra_nix_config: sandbox = true
          nix_path: nixpkgs=${{ env.url }}

      - name: Install nixfmt
        run: "nix-env -f '<nixpkgs>' -iAP nixfmt-rfc-style"

      - name: Check that Nix files are formatted according to the RFC style
      - name: Check that Nix files are formatted
        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.target }}/"$source" 2>/dev/null; then
              echo "Ignoring file $file because it's not formatted in the target commit"
            elif ! nixfmt --check "$dest"; then
              unformattedFiles+=("$dest")
            fi
          done < <(git diff -z --name-status ${{ env.targetRev }} -- '*.nix')

          if (( "${#unformattedFiles[@]}" > 0 )); then
            echo "Some new/changed Nix files are not properly formatted"
            echo "Please format them using the Nixpkgs-specific \`nixfmt\` by going to the Nixpkgs root directory, running \`nix-shell\`, then:"
            echo
            echo "nixfmt ${unformattedFiles[*]@Q}"
            echo
          # Note that it's fine to run this on untrusted code because:
          # - There's no secrets accessible here
          # - The build is sandboxed
          if ! nix-build ci -A fmt.check; then
            echo "Some Nix files are not properly formatted"
            echo "Please format them by going to the Nixpkgs root directory and running one of:"
            echo "  nix-shell --run treefmt"
            echo "  nix develop --command treefmt"
            echo "  nix fmt"
            echo "Make sure your branch is up to date with master; rebase if not."
            echo "If you're having trouble, please ping @NixOS/nix-formatting"
            exit 1
+9 −0
Original line number Diff line number Diff line
@@ -49,10 +49,19 @@ let
        # See https://github.com/NixOS/nixfmt
        programs.nixfmt.enable = true;
      };
      fs = pkgs.lib.fileset;
      nixFilesSrc = fs.toSource {
        root = ../.;
        fileset = fs.difference (fs.unions [
          (fs.fileFilter (file: file.hasExt "nix") ../.)
          ../.git-blame-ignore-revs
        ]) (fs.maybeMissing ../.git);
      };
    in
    {
      shell = treefmtEval.config.build.devShell;
      pkg = treefmtEval.config.build.wrapper;
      check = treefmtEval.config.build.check nixFilesSrc;
    };

in