Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# THIS IS A BAD FORK

> [!CAUTION]
> This is a fork of the awesome [nix-diff-action](https://github.com/natsukium/nix-diff-action). My fork contains changes that fit my workflow, but break expected behaviour for others. To make it worse, these changes are not gated by configuration options. To make it even worse, some of these changes are vibecoded. **DO NOT USE IN PRODUCTION**. Instead, use the original [nix-diff-action](https://github.com/natsukium/nix-diff-action).

Below this line is the original README.md content at the time of forking.

---

# nix-diff-action

A GitHub Action to compare Nix derivations between base and PR branches using [dix](https://github.com/faukah/dix).
Expand Down
31 changes: 30 additions & 1 deletion dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -62022,6 +62022,35 @@ const hasPackageChanges = (diff) => {
if (!diff || diff.trim() === "") return false;
return diff.split(/\r?\n/).length > 5;
};
var isNixpkgsMinorUpdateLine = (line) => {
const match$3 = line.match(/^\[([A-Z.]+)\]\s+(\S+)\s+(.+?)\s+->\s+(.+)$/);
if (!match$3) return false;
if (match$3[1] !== "U.") return false;
const packageName = match$3[2];
if (!packageName.startsWith("nixos-system-") && packageName !== "darwin-system") return false;
const beforeVersion = match$3[3].trim();
const afterVersion = match$3[4].trim();
if (beforeVersion.includes(",") || afterVersion.includes(",")) return false;
if (!beforeVersion.endsWith(".drv") || !afterVersion.endsWith(".drv")) return false;
const extractMajorMinor = (version$1) => {
const versionMatch = version$1.match(/^(\d+\.\d+)\..+\.drv$/);
return versionMatch ? versionMatch[1] : null;
};
const beforeMajorMinor = extractMajorMinor(beforeVersion);
const afterMajorMinor = extractMajorMinor(afterVersion);
return beforeMajorMinor !== null && afterMajorMinor !== null && beforeMajorMinor === afterMajorMinor;
};
const filterNixpkgsMinorUpdates = (diff) => {
if (!diff || diff.trim() === "") return diff;
const filteredLines = diff.split(/\r?\n/).filter((line) => !isNixpkgsMinorUpdateLine(line));
const output = [];
for (let i = 0; i < filteredLines.length; i += 1) {
const line = filteredLines[i];
if (line.trim() === "CHANGED" && filteredLines[i + 1]?.trim() === "") continue;
output.push(line);
}
return output.join("\n");
};
var NIX_DIFF_ACTION_MARKER_BASE = "<!-- nix-diff-action";
var getNixDiffActionMarker = (displayName) => displayName ? `${NIX_DIFF_ACTION_MARKER_BASE}:${displayName} -->` : `${NIX_DIFF_ACTION_MARKER_BASE} -->`;
var MAX_COMMENT_LENGTH = 6e4;
Expand Down Expand Up @@ -68149,7 +68178,7 @@ var processNixOutput = (config, baseFlakeRef, prFlakeRef, baseSha, headSha, buil
});
yield* logInfo(`Base path: ${basePath}`);
yield* logInfo(`PR path: ${prPath}`);
const diff = yield* nix.getDixDiff(basePath, prPath, worktreePath);
const diff = filterNixpkgsMinorUpdates(yield* nix.getDixDiff(basePath, prPath, worktreePath));
return {
displayName: config.displayName,
attributePath: config.attribute,
Expand Down
2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

72 changes: 71 additions & 1 deletion src/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { parseCommentStrategy, parseAttributes, validateDirectory } from "./prog
import { processDiffResults } from "./programs/full.js";
import { GitService, sanitizeBranchName } from "./services/git.js";
import { NixService } from "./services/nix.js";
import { hasDixChanges, hasPackageChanges } from "./services/utils.js";
import { hasDixChanges, hasPackageChanges, filterNixpkgsMinorUpdates } from "./services/utils.js";
import { createArtifactName } from "./services/artifact.js";

describe("parseAttributes", () => {
Expand Down Expand Up @@ -632,6 +632,76 @@ describe("createArtifactName", () => {
});
});

describe("filterNixpkgsMinorUpdates", () => {
test("removes nixos-system entries when major/minor is unchanged", () => {
const diff = `<<< /nix/store/old-nixos-system-eule-26.05.20251225.3e2499d.drv
>>> /nix/store/new-nixos-system-eule-26.05.20251228.c0b0e0f.drv

CHANGED
[U.] nixos-system-eule 26.05.20251225.3e2499d.drv -> 26.05.20251228.c0b0e0f.drv
[U.] hello 1.0.drv -> 1.1.drv

SIZE: 10.0 MiB -> 10.0 MiB
DIFF: 100 KiB`;
const result = filterNixpkgsMinorUpdates(diff);
expect(result).not.toContain("nixos-system-eule 26.05.20251225.3e2499d.drv");
expect(result).toContain("[U.] hello 1.0.drv -> 1.1.drv");
});

test("removes darwin-system entries when major/minor is unchanged", () => {
const diff = `<<< /nix/store/old-darwin-system-26.05.c2b3620.drv
>>> /nix/store/new-darwin-system-26.05.d9a1b77.drv

CHANGED
[U.] darwin-system 26.05.c2b3620.drv -> 26.05.d9a1b77.drv

SIZE: 260 MiB -> 260 MiB
DIFF: 32 bytes`;
const result = filterNixpkgsMinorUpdates(diff);
expect(result).not.toContain("darwin-system 26.05.c2b3620.drv");
});

test("keeps nixos-system entries when major/minor changes", () => {
const diff = `<<< /nix/store/old-nixos-system-eule-25.11.20251101.aaaaaaa.drv
>>> /nix/store/new-nixos-system-eule-26.05.20251228.bbbbbbb.drv

CHANGED
[U.] nixos-system-eule 25.11.20251101.aaaaaaa.drv -> 26.05.20251228.bbbbbbb.drv

SIZE: 10.0 MiB -> 12.0 MiB
DIFF: 200 KiB`;
const result = filterNixpkgsMinorUpdates(diff);
expect(result).toContain("nixos-system-eule 25.11.20251101.aaaaaaa.drv");
});

test("keeps nixos-system entries when status is not [U.]", () => {
const diff = `<<< /nix/store/old-nixos-system-eule-26.05.20251225.3e2499d.drv
>>> /nix/store/new-nixos-system-eule-26.05.20251228.c0b0e0f.drv

CHANGED
[D.] nixos-system-eule 26.05.20251225.3e2499d.drv -> 26.05.20251228.c0b0e0f.drv

SIZE: 10.0 MiB -> 10.0 MiB
DIFF: 100 KiB`;
const result = filterNixpkgsMinorUpdates(diff);
expect(result).toContain("[D.] nixos-system-eule");
});

test("removes empty CHANGED section after filtering", () => {
const diff = `<<< /nix/store/old-nixos-system-eule-26.05.20251225.3e2499d.drv
>>> /nix/store/new-nixos-system-eule-26.05.20251228.c0b0e0f.drv

CHANGED
[U.] nixos-system-eule 26.05.20251225.3e2499d.drv -> 26.05.20251228.c0b0e0f.drv

SIZE: 10.0 MiB -> 10.0 MiB
DIFF: -248 bytes`;
const result = filterNixpkgsMinorUpdates(diff);
expect(result).not.toContain("\nCHANGED\n");
expect(result).toContain("SIZE: 10.0 MiB -> 10.0 MiB");
});
});

describe("hasDixChanges", () => {
test("returns false for undefined", () => {
expect(hasDixChanges(undefined)).toBe(false);
Expand Down
4 changes: 3 additions & 1 deletion src/programs/full.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
postComment,
setDiffOutput,
} from "./shared.js";
import { filterNixpkgsMinorUpdates } from "../services/utils.js";

// Error type aliases for better readability
type DiffError = NixPathInfoError | NixBuildError | NixDixError;
Expand Down Expand Up @@ -75,7 +76,8 @@ const processNixOutput = (
yield* Effect.logInfo(`Base path: ${basePath}`);
yield* Effect.logInfo(`PR path: ${prPath}`);

const diff = yield* nix.getDixDiff(basePath, prPath, worktreePath);
const rawDiff = yield* nix.getDixDiff(basePath, prPath, worktreePath);
const diff = filterNixpkgsMinorUpdates(rawDiff);

return {
displayName: config.displayName,
Expand Down
52 changes: 52 additions & 0 deletions src/services/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,58 @@ export const hasPackageChanges = (diff: string | undefined): boolean => {
return lines.length > 5;
};

// WARNING: Shamefully vibecoded
const isNixpkgsMinorUpdateLine = (line: string): boolean => {
const match = line.match(/^\[([A-Z.]+)\]\s+(\S+)\s+(.+?)\s+->\s+(.+)$/);
if (!match) return false;

const status = match[1];
if (status !== "U.") return false;

const packageName = match[2];
if (!packageName.startsWith("nixos-system-") && packageName !== "darwin-system") {
return false;
}

const beforeVersion = match[3].trim();
const afterVersion = match[4].trim();

if (beforeVersion.includes(",") || afterVersion.includes(",")) return false;
if (!beforeVersion.endsWith(".drv") || !afterVersion.endsWith(".drv")) return false;

const extractMajorMinor = (version: string): string | null => {
const versionMatch = version.match(/^(\d+\.\d+)\..+\.drv$/);
return versionMatch ? versionMatch[1] : null;
};

const beforeMajorMinor = extractMajorMinor(beforeVersion);
const afterMajorMinor = extractMajorMinor(afterVersion);

return (
beforeMajorMinor !== null && afterMajorMinor !== null && beforeMajorMinor === afterMajorMinor
);
};

// WARNING: Shamefully vibecoded
export const filterNixpkgsMinorUpdates = (diff: string): string => {
if (!diff || diff.trim() === "") return diff;

const lines = diff.split(/\r?\n/);
const filteredLines = lines.filter((line) => !isNixpkgsMinorUpdateLine(line));
const output: string[] = [];

for (let i = 0; i < filteredLines.length; i += 1) {
const line = filteredLines[i];
if (line.trim() === "CHANGED" && filteredLines[i + 1]?.trim() === "") {
continue;
}

output.push(line);
}

return output.join("\n");
};

// Git utilities
export { sanitizeBranchName } from "./git.js";

Expand Down