From ab4da6f0d1951461ff9d490fa88747926bcabf51 Mon Sep 17 00:00:00 2001 From: floze-the-genius <88098863+floze-the-genius@users.noreply.github.com> Date: Sun, 19 Jul 2026 01:07:51 +0400 Subject: [PATCH 1/3] Fix validation of cow JSON location --- .github/scripts/validate-pr.js | 3 ++- .github/scripts/validation-helpers.js | 3 +++ .github/scripts/validation-helpers.test.js | 17 +++++++++++++++++ .github/workflows/validate-pr.yml | 3 +++ package.json | 4 ++++ 5 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 .github/scripts/validation-helpers.js create mode 100644 .github/scripts/validation-helpers.test.js diff --git a/.github/scripts/validate-pr.js b/.github/scripts/validate-pr.js index 45545fc..dcb283a 100644 --- a/.github/scripts/validate-pr.js +++ b/.github/scripts/validate-pr.js @@ -1,4 +1,5 @@ import { Octokit } from "@octokit/rest"; +import { isCowJsonFile } from "./validation-helpers.js"; // Environment variables const token = process.env.GITHUB_TOKEN; @@ -45,7 +46,7 @@ async function run() { pull_number: pr_number }); - const jsonFiles = files.filter(f => f.filename.endsWith(".json")); + const jsonFiles = files.filter(f => isCowJsonFile(f.filename)); const imageFiles = files.filter(f => f.filename.startsWith("images/")); const requiredKeys = ["name", "breed", "image"]; diff --git a/.github/scripts/validation-helpers.js b/.github/scripts/validation-helpers.js new file mode 100644 index 0000000..0dabbdc --- /dev/null +++ b/.github/scripts/validation-helpers.js @@ -0,0 +1,3 @@ +export function isCowJsonFile(filename) { + return filename.startsWith("cows/") && filename.endsWith(".json"); +} diff --git a/.github/scripts/validation-helpers.test.js b/.github/scripts/validation-helpers.test.js new file mode 100644 index 0000000..6bd598f --- /dev/null +++ b/.github/scripts/validation-helpers.test.js @@ -0,0 +1,17 @@ +import assert from "node:assert/strict"; +import test from "node:test"; + +import { isCowJsonFile } from "./validation-helpers.js"; + +test("accepts JSON files in the cows directory", () => { + assert.equal(isCowJsonFile("cows/moonlight.json"), true); +}); + +test("rejects JSON files outside the cows directory", () => { + assert.equal(isCowJsonFile("moonlight.json"), false); + assert.equal(isCowJsonFile("examples/moonlight.json"), false); +}); + +test("rejects non-JSON files", () => { + assert.equal(isCowJsonFile("cows/moonlight.png"), false); +}); diff --git a/.github/workflows/validate-pr.yml b/.github/workflows/validate-pr.yml index 77677bd..932f772 100644 --- a/.github/workflows/validate-pr.yml +++ b/.github/workflows/validate-pr.yml @@ -28,6 +28,9 @@ jobs: - name: Install dependencies run: npm ci + - name: Run validator tests + run: npm test + - name: Validate pull request run: node .github/scripts/validate-pr.js env: diff --git a/package.json b/package.json index 51b9359..a910655 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,10 @@ "name": "fantasy-cow", "version": "1.0.0", "description": "A small project that teaches how to create a first Pull Request.", + "type": "module", + "scripts": { + "test": "node --test .github/scripts/*.test.js" + }, "dependencies": { "@octokit/rest": "^22.0.0" } From 8701e059574808edfa29a5e54880bc0f22bbcbd5 Mon Sep 17 00:00:00 2001 From: floze-the-genius <88098863+floze-the-genius@users.noreply.github.com> Date: Sun, 19 Jul 2026 01:10:55 +0400 Subject: [PATCH 2/3] Allow validator maintenance pull requests --- .github/scripts/validate-pr.js | 10 +++++++- .github/scripts/validation-helpers.js | 12 ++++++++++ .github/scripts/validation-helpers.test.js | 28 +++++++++++++++++++++- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/.github/scripts/validate-pr.js b/.github/scripts/validate-pr.js index dcb283a..1cc5257 100644 --- a/.github/scripts/validate-pr.js +++ b/.github/scripts/validate-pr.js @@ -1,5 +1,8 @@ import { Octokit } from "@octokit/rest"; -import { isCowJsonFile } from "./validation-helpers.js"; +import { + isCowJsonFile, + isValidatorMaintenancePullRequest +} from "./validation-helpers.js"; // Environment variables const token = process.env.GITHUB_TOKEN; @@ -46,6 +49,11 @@ async function run() { pull_number: pr_number }); + if (isValidatorMaintenancePullRequest(files)) { + console.log("✅ Validator maintenance PR detected; cow submission checks skipped."); + process.exit(0); + } + const jsonFiles = files.filter(f => isCowJsonFile(f.filename)); const imageFiles = files.filter(f => f.filename.startsWith("images/")); const requiredKeys = ["name", "breed", "image"]; diff --git a/.github/scripts/validation-helpers.js b/.github/scripts/validation-helpers.js index 0dabbdc..9ca60ae 100644 --- a/.github/scripts/validation-helpers.js +++ b/.github/scripts/validation-helpers.js @@ -1,3 +1,15 @@ export function isCowJsonFile(filename) { return filename.startsWith("cows/") && filename.endsWith(".json"); } + +export function isValidatorMaintenancePullRequest(files) { + const allowedFiles = new Set([ + ".github/workflows/validate-pr.yml", + "package-lock.json", + "package.json" + ]); + + return files.length > 0 && files.every(({ filename }) => + filename.startsWith(".github/scripts/") || allowedFiles.has(filename) + ); +} diff --git a/.github/scripts/validation-helpers.test.js b/.github/scripts/validation-helpers.test.js index 6bd598f..3376faf 100644 --- a/.github/scripts/validation-helpers.test.js +++ b/.github/scripts/validation-helpers.test.js @@ -1,7 +1,10 @@ import assert from "node:assert/strict"; import test from "node:test"; -import { isCowJsonFile } from "./validation-helpers.js"; +import { + isCowJsonFile, + isValidatorMaintenancePullRequest +} from "./validation-helpers.js"; test("accepts JSON files in the cows directory", () => { assert.equal(isCowJsonFile("cows/moonlight.json"), true); @@ -15,3 +18,26 @@ test("rejects JSON files outside the cows directory", () => { test("rejects non-JSON files", () => { assert.equal(isCowJsonFile("cows/moonlight.png"), false); }); + +test("identifies validator maintenance pull requests", () => { + const files = [ + { filename: ".github/scripts/validate-pr.js" }, + { filename: ".github/scripts/validation-helpers.test.js" }, + { filename: ".github/workflows/validate-pr.yml" }, + { filename: "package.json" } + ]; + + assert.equal(isValidatorMaintenancePullRequest(files), true); +}); + +test("does not skip cow submissions or unrelated changes", () => { + assert.equal(isValidatorMaintenancePullRequest([]), false); + assert.equal( + isValidatorMaintenancePullRequest([{ filename: "cows/moonlight.json" }]), + false + ); + assert.equal( + isValidatorMaintenancePullRequest([{ filename: "README.md" }]), + false + ); +}); From 35d1e0f3168809e8d1e25ac88d31540bd174eda7 Mon Sep 17 00:00:00 2001 From: floze-the-genius <88098863+floze-the-genius@users.noreply.github.com> Date: Thu, 13 Aug 2026 11:51:05 +0400 Subject: [PATCH 3/3] Narrow validator fix to cow directory --- .github/scripts/validate-pr.js | 13 ++----- .github/scripts/validation-helpers.js | 15 -------- .github/scripts/validation-helpers.test.js | 43 ---------------------- .github/workflows/validate-pr.yml | 3 -- package.json | 4 -- 5 files changed, 3 insertions(+), 75 deletions(-) delete mode 100644 .github/scripts/validation-helpers.js delete mode 100644 .github/scripts/validation-helpers.test.js diff --git a/.github/scripts/validate-pr.js b/.github/scripts/validate-pr.js index 1cc5257..9fb7628 100644 --- a/.github/scripts/validate-pr.js +++ b/.github/scripts/validate-pr.js @@ -1,8 +1,4 @@ import { Octokit } from "@octokit/rest"; -import { - isCowJsonFile, - isValidatorMaintenancePullRequest -} from "./validation-helpers.js"; // Environment variables const token = process.env.GITHUB_TOKEN; @@ -49,12 +45,9 @@ async function run() { pull_number: pr_number }); - if (isValidatorMaintenancePullRequest(files)) { - console.log("✅ Validator maintenance PR detected; cow submission checks skipped."); - process.exit(0); - } - - const jsonFiles = files.filter(f => isCowJsonFile(f.filename)); + const jsonFiles = files.filter( + f => f.filename.startsWith("cows/") && f.filename.endsWith(".json") + ); const imageFiles = files.filter(f => f.filename.startsWith("images/")); const requiredKeys = ["name", "breed", "image"]; diff --git a/.github/scripts/validation-helpers.js b/.github/scripts/validation-helpers.js deleted file mode 100644 index 9ca60ae..0000000 --- a/.github/scripts/validation-helpers.js +++ /dev/null @@ -1,15 +0,0 @@ -export function isCowJsonFile(filename) { - return filename.startsWith("cows/") && filename.endsWith(".json"); -} - -export function isValidatorMaintenancePullRequest(files) { - const allowedFiles = new Set([ - ".github/workflows/validate-pr.yml", - "package-lock.json", - "package.json" - ]); - - return files.length > 0 && files.every(({ filename }) => - filename.startsWith(".github/scripts/") || allowedFiles.has(filename) - ); -} diff --git a/.github/scripts/validation-helpers.test.js b/.github/scripts/validation-helpers.test.js deleted file mode 100644 index 3376faf..0000000 --- a/.github/scripts/validation-helpers.test.js +++ /dev/null @@ -1,43 +0,0 @@ -import assert from "node:assert/strict"; -import test from "node:test"; - -import { - isCowJsonFile, - isValidatorMaintenancePullRequest -} from "./validation-helpers.js"; - -test("accepts JSON files in the cows directory", () => { - assert.equal(isCowJsonFile("cows/moonlight.json"), true); -}); - -test("rejects JSON files outside the cows directory", () => { - assert.equal(isCowJsonFile("moonlight.json"), false); - assert.equal(isCowJsonFile("examples/moonlight.json"), false); -}); - -test("rejects non-JSON files", () => { - assert.equal(isCowJsonFile("cows/moonlight.png"), false); -}); - -test("identifies validator maintenance pull requests", () => { - const files = [ - { filename: ".github/scripts/validate-pr.js" }, - { filename: ".github/scripts/validation-helpers.test.js" }, - { filename: ".github/workflows/validate-pr.yml" }, - { filename: "package.json" } - ]; - - assert.equal(isValidatorMaintenancePullRequest(files), true); -}); - -test("does not skip cow submissions or unrelated changes", () => { - assert.equal(isValidatorMaintenancePullRequest([]), false); - assert.equal( - isValidatorMaintenancePullRequest([{ filename: "cows/moonlight.json" }]), - false - ); - assert.equal( - isValidatorMaintenancePullRequest([{ filename: "README.md" }]), - false - ); -}); diff --git a/.github/workflows/validate-pr.yml b/.github/workflows/validate-pr.yml index 932f772..77677bd 100644 --- a/.github/workflows/validate-pr.yml +++ b/.github/workflows/validate-pr.yml @@ -28,9 +28,6 @@ jobs: - name: Install dependencies run: npm ci - - name: Run validator tests - run: npm test - - name: Validate pull request run: node .github/scripts/validate-pr.js env: diff --git a/package.json b/package.json index a910655..51b9359 100644 --- a/package.json +++ b/package.json @@ -2,10 +2,6 @@ "name": "fantasy-cow", "version": "1.0.0", "description": "A small project that teaches how to create a first Pull Request.", - "type": "module", - "scripts": { - "test": "node --test .github/scripts/*.test.js" - }, "dependencies": { "@octokit/rest": "^22.0.0" }