diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bbdcdd58e..405a09c46 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,6 +13,7 @@ jobs: docs: ${{ steps.changes.outputs.docs }} format: ${{ steps.changes.outputs.format }} hm: ${{ steps.changes.outputs.hm }} + parse: ${{ steps.changes.outputs.parse }} tests: ${{ steps.changes.outputs.tests }} steps: - uses: actions/checkout@v6 @@ -39,6 +40,9 @@ jobs: - 'flake.lock' - 'flake.nix' - 'home-manager/**' + parse: + - '**/*.nix' + - 'flake.lock' tests: needs: changes strategy: @@ -59,6 +63,12 @@ jobs: - name: Build docs if: github.event_name == 'schedule' || needs.changes.outputs.docs == 'true' run: nix build --show-trace .#docs-jsonModuleMaintainers + - name: Parse Nix files with latest nix + if: github.event_name == 'schedule' || needs.changes.outputs.parse == 'true' + run: nix build --show-trace .#ci-parse + - name: Parse Nix files with latest Lix + if: github.event_name == 'schedule' || needs.changes.outputs.parse == 'true' + run: nix build --show-trace .#ci-parse-lix - name: Format Check if: github.event_name == 'schedule' || needs.changes.outputs.format == 'true' run: nix fmt -- --ci @@ -93,6 +103,12 @@ jobs: echo "- ☑️ **Format Check:** Skipped (no relevant files changed)" >> $GITHUB_STEP_SUMMARY fi + if [[ "${{ needs.changes.outputs.parse }}" == "true" ]]; then + echo "- ✅ **Nix Parse (nix + Lix):** Triggered" >> $GITHUB_STEP_SUMMARY + else + echo "- ☑️ **Nix Parse (nix + Lix):** Skipped (no relevant files changed)" >> $GITHUB_STEP_SUMMARY + fi + if [[ "${{ needs.changes.outputs.hm }}" == "true" ]]; then echo "- ✅ **Home Manager Tests:** Triggered" >> $GITHUB_STEP_SUMMARY else diff --git a/ci/parse.nix b/ci/parse.nix new file mode 100644 index 000000000..0331901b1 --- /dev/null +++ b/ci/parse.nix @@ -0,0 +1,45 @@ +{ + lib, + nix, + runCommand, +}: +let + home-manager = + with lib.fileset; + toSource { + root = ../.; + fileset = (fileFilter (file: file.hasExt "nix") ../.); + }; + parseLog = "$TMPDIR/nix-parse.log"; +in +runCommand "nix-parse-${nix.name}" + { + nativeBuildInputs = [ + nix + ]; + } + '' + export NIX_STORE_DIR=$TMPDIR/store + export NIX_STATE_DIR=$TMPDIR/state + nix-store --init + + cd "${home-manager}" + + # This will only show the first parse error, not all of them. That's fine, because + # the other CI jobs will report in more detail. This job is about checking parsing + # across different implementations / versions, not about providing the best DX. + # Returning all parse errors requires significantly more resources. + if ! find . -type f -iname '*.nix' | xargs -P $(nproc) nix-instantiate --parse 2> "${parseLog}" > /dev/null; then + cat "${parseLog}" >&2 + echo "Parse failed in nix-instantiate." >&2 + exit 1 + fi + + if grep "warning" "${parseLog}"; then + cat "${parseLog}" >&2 + echo "Failing due to warnings in stderr" >&2 + exit 1 + fi + + touch $out + '' diff --git a/flake.nix b/flake.nix index 5317b569c..221adf866 100644 --- a/flake.nix +++ b/flake.nix @@ -189,6 +189,11 @@ default = hmPkg; home-manager = hmPkg; + ci-parse = pkgs.callPackage ./ci/parse.nix { nix = pkgs.nixVersions.latest; }; + ci-parse-lix = pkgs.callPackage ./ci/parse.nix { + nix = pkgs.lixPackageSets.latest.lix; + }; + create-news-entry = pkgs.writeShellScriptBin "create-news-entry" '' ./modules/misc/news/create-news-entry.sh '';