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/2] 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/2] 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 + ); +});