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
323 changes: 323 additions & 0 deletions .github/workflows/json-validation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,323 @@
---
name: JSON Linting & Validation

on:
push:
branches:
- develop
- main
- 'claude/**'
paths:
- '**.json'
- '!package-lock.json'
- 'schemas/**/*.schema.json'
- '.github/workflows/json-validation.yml'
- 'scripts/json-validation/**'
pull_request:
paths:
- '**.json'
- '!package-lock.json'
- 'schemas/**/*.schema.json'
- '.github/workflows/json-validation.yml'
- 'scripts/json-validation/**'
workflow_dispatch:
inputs:
glob:
description: 'Glob pattern for JSON files'
required: false
default: '**/*.json'
schema:
description: 'Path to schema file (optional)'
required: false
read-only:
description: 'Read-only mode (no file modifications)'
required: false
type: boolean
default: false

permissions:
contents: read
pull-requests: write

jobs:
format-check:
name: Format Check (Prettier)
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Check JSON formatting
run: npx prettier --check "**/*.json" "!package-lock.json" "!**/node_modules/**"

- name: Generate formatting report
if: failure()
run: |
echo "# JSON Formatting Issues" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "The following files need formatting:" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo '```bash' >> $GITHUB_STEP_SUMMARY
echo "npx prettier --write \"**/*.json\"" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
Comment on lines +60 to +72

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

Prettier format-check is likely affected by the ESM/CommonJS config issue

The format-check job runs:

- name: Check JSON formatting
  run: npx prettier --check "**/*.json" "!package-lock.json" "!**/node_modules/**"

Given "type": "module" in package.json and the reported error about require not being defined in ESM scope during JSON validation, Prettier is probably loading a JS config that still uses module.exports/require, causing failures. (prettier.io)

Since your JSON validator script already uses --no-config to avoid these config issues for JSON, you can mirror that here:

-        run: npx prettier --check "**/*.json" "!package-lock.json" "!**/node_modules/**"
+        run: npx prettier --check --no-config "**/*.json" "!package-lock.json" "!**/node_modules/**"

That keeps the JSON formatting check stable even if the main Prettier config remains CommonJS-oriented.

After adding --no-config, please re-run the workflow to confirm the format-check job no longer fails due to the Prettier config; if you prefer using the shared config, you’ll instead need to convert it to an ESM-compatible form per Prettier’s configuration docs. (prettier.io)



---

🏁 Script executed:

```shell
#!/bin/bash
# 1. Check workflow file structure and all Prettier invocations
echo "=== Workflow file content ==="
cat .github/workflows/json-validation.yml

echo -e "\n=== package.json 'type' field ==="
grep -A2 -B2 '"type"' package.json || echo "No 'type' field found"

echo -e "\n=== Prettier config files ==="
fd -e js -e json -e cjs -e mjs 'prettier' . -g 'prettier*' 2>/dev/null | head -20

echo -e "\n=== Look for validate-json script ==="
fd 'validate-json' . 2>/dev/null

echo -e "\n=== All npx prettier invocations in workflows ==="
rg -n 'npx prettier' .github/workflows/ -A2 -B1

Length of output: 429


🏁 Script executed:

#!/bin/bash
# Clone repository and inspect files
echo "=== Workflow file content ==="
cat .github/workflows/json-validation.yml

echo -e "\n=== package.json 'type' field ==="
grep -A2 -B2 '"type"' package.json || echo "No 'type' field found"

echo -e "\n=== Prettier config files ==="
find . -maxdepth 2 -name 'prettier*' -o -name '.prettierrc*' 2>/dev/null

echo -e "\n=== validate-json.js content ==="
cat scripts/json-validation/validate-json.js 2>/dev/null || cat git/scripts/json-validation/validate-json.js 2>/dev/null || echo "File not found"

echo -e "\n=== All npx prettier invocations in workflows ==="
rg -n 'npx prettier' .github/workflows/ -A2 -B1

Length of output: 24843


🏁 Script executed:

#!/bin/bash
# Check prettier config file syntax
echo "=== prettier.config.js content ==="
cat prettier.config.js

echo -e "\n=== Check if config uses CommonJS require/module.exports ==="
grep -n 'require\|module\.exports\|export' prettier.config.js || echo "No CommonJS patterns found"

Length of output: 4383


Add --no-config to Prettier invocations to resolve ESM/CommonJS config conflict

The prettier.config.js uses CommonJS (require(), module.exports) while package.json specifies "type": "module" (ESM). When Prettier runs without --no-config, it attempts to load the CommonJS config in an ESM context, causing failures. Your validate-json.js script already handles this correctly with --no-config.

Add the flag to both Prettier calls in this workflow:

Line 61 (format-check job):

-        run: npx prettier --check "**/*.json" "!package-lock.json" "!**/node_modules/**"
+        run: npx prettier --check --no-config "**/*.json" "!package-lock.json" "!**/node_modules/**"

Line 223 (validate-changed-files job):

-          npx prettier --check $(cat /tmp/changed-files.txt | tr '\n' ' ')
+          npx prettier --check --no-config $(cat /tmp/changed-files.txt | tr '\n' ' ')

Alternatively, convert prettier.config.js to ESM syntax (import/export) to align with your module setup.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
.github/workflows/json-validation.yml lines 60-72: Prettier is invoked without
--no-config which can cause an ESM/CommonJS config load error; update both
Prettier calls in this workflow (the one at ~line 61 in the format-check job and
the one at ~line 223 in the validate-changed-files job) to include the
--no-config flag (or alternatively convert prettier.config.js to ESM exports) so
Prettier ignores the CommonJS config and avoids the ESM load failure.


syntax-validation:
name: Syntax Validation
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Validate JSON syntax
run: node scripts/json-validation/validate-json.js --validate-only --strict --glob "**/*.json"

- name: Upload syntax errors
if: failure()
uses: actions/upload-artifact@v4
with:
name: syntax-errors
path: reports/jsonlint.log
retention-days: 7

schema-validation:
name: Schema Validation
runs-on: ubuntu-latest
needs: syntax-validation

strategy:
fail-fast: false
matrix:
validation:
- name: 'Frontmatter Schema'
glob: '.github/automation/schemas/frontmatter.schema.json'
schema: 'https://json-schema.org/draft/2020-12/schema'
spec: 'draft2020'
- name: 'CodeRabbit Overrides'
glob: 'schemas/coderabbit-overrides.v2.json'
schema: 'https://json-schema.org/draft-07/schema'
spec: 'draft7'
- name: 'Metrics Config'
glob: '.github/metrics/metrics.config.json'
schema: null
spec: 'draft2020'
- name: 'WordPress Schemas'
glob: 'schemas/wp/*.schema.json'
schema: 'https://json-schema.org/draft-07/schema'
spec: 'draft7'

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Validate ${{ matrix.validation.name }}
if: matrix.validation.schema != null
run: |
echo "Validating: ${{ matrix.validation.name }}"
echo "Glob: ${{ matrix.validation.glob }}"
echo "Schema: ${{ matrix.validation.schema }}"
echo "Spec: ${{ matrix.validation.spec }}"

# Create temporary schema file from URL if needed
if [[ "${{ matrix.validation.schema }}" == http* ]]; then
curl -s "${{ matrix.validation.schema }}" > /tmp/schema.json
SCHEMA_PATH="/tmp/schema.json"
else
SCHEMA_PATH="${{ matrix.validation.schema }}"
fi

# Run validation
node scripts/json-validation/validate-json.js \
--glob "${{ matrix.validation.glob }}" \
--schema "$SCHEMA_PATH" \
--spec "${{ matrix.validation.spec }}" \
--validate-only \
--errors json

- name: Syntax-only validation for ${{ matrix.validation.name }}
if: matrix.validation.schema == null
run: |
echo "Syntax-only validation for: ${{ matrix.validation.name }}"
node scripts/json-validation/validate-json.js \
--glob "${{ matrix.validation.glob }}" \
--validate-only \
--strict

- name: Upload validation errors
if: failure()
uses: actions/upload-artifact@v4
with:
name: schema-errors-${{ matrix.validation.name }}
path: reports/
retention-days: 7

validate-changed-files:
name: Validate Changed Files (PR)
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Get changed JSON files
id: changed-files
uses: tj-actions/changed-files@v46
with:
files: |
**.json
files_ignore: |
package-lock.json
**/node_modules/**

- name: Format and validate changed files
if: steps.changed-files.outputs.any_changed == 'true'
run: |
echo "Changed JSON files:"
echo "${{ steps.changed-files.outputs.all_changed_files }}"

# Create temp file list
echo "${{ steps.changed-files.outputs.all_changed_files }}" | tr ' ' '\n' > /tmp/changed-files.txt

# Format check
echo "Checking formatting..."
npx prettier --check $(cat /tmp/changed-files.txt | tr '\n' ' ')

# Validate syntax
echo "Validating syntax..."
while IFS= read -r file; do
echo "Checking: $file"
node -e "JSON.parse(require('fs').readFileSync('$file', 'utf8'))" || exit 1
done < /tmp/changed-files.txt

Comment on lines +202 to +231

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Changed-files Prettier check is the direct cause of the reported Prettier/ESM pipeline failure

In validate-changed-files, you run:

- name: Format check
  run: |
    echo "Checking formatting..."
    npx prettier --check $(cat /tmp/changed-files.txt | tr '\n' ' ')

The pipeline error you shared:

Invalid configuration for file '.../package.json': require is not defined in ES module scope; this file is being treated as an ES module because it has a '.js' extension and 'type': 'module'. Prettier check failed.

comes from this prettier --check invocation loading a config that still uses CommonJS in a project marked as ESM. (prettier.io)

To make this step robust and consistent with your JSON validator script:

  1. Ignore the project Prettier config for this JSON-only check
-          npx prettier --check $(cat /tmp/changed-files.txt | tr '\n' ' ')
+          npx prettier --check --no-config $(cat /tmp/changed-files.txt | tr '\n' ' ')
  1. (Optional but cleaner) Reuse your JSON validator for syntax instead of the inline node -e:
-          # Validate syntax
-          echo "Validating syntax..."
-          while IFS= read -r file; do
-            echo "Checking: $file"
-            node -e "JSON.parse(require('fs').readFileSync('$file', 'utf8'))" || exit 1
-          done < /tmp/changed-files.txt
+          # Validate syntax using the shared JSON validation script
+          echo "Validating syntax..."
+          node scripts/json-validation/validate-json.js --validate-only --strict --glob "$(tr '\n' ' ' < /tmp/changed-files.txt)"

This should resolve the current Prettier config/ESM failure and centralize JSON syntax checks in one place.

Please re-run the “JSON Linting & Validation” workflow on a PR with changed JSON files after adding --no-config (and, if desired, switching to validate-json.js) to confirm the Prettier error is gone and that the syntax validation still behaves as expected.


I'll verify the review comment by examining the workflow file, prettier configuration, and the referenced validation script.


---

🏁 Script executed:

```shell
#!/bin/bash

# 1. Check the workflow file around lines 202-231
echo "=== Workflow file content (lines 202-231) ==="
cat .github/workflows/json-validation.yml | sed -n '202,231p'

# 2. Find and display prettier config
echo -e "\n=== Looking for prettier configuration ==="
fd -e json -e js -e yml | grep -E "(prettier|\.prettierrc)" | head -20

# 3. Check if prettier config exists and its content
if [ -f ".prettierrc" ]; then
  echo -e "\n=== .prettierrc content ==="
  cat .prettierrc
fi

if [ -f ".prettierrc.json" ]; then
  echo -e "\n=== .prettierrc.json content ==="
  cat .prettierrc.json
fi

if [ -f "prettier.config.js" ]; then
  echo -e "\n=== prettier.config.js content ==="
  cat prettier.config.js
fi

if [ -f "prettier.config.cjs" ]; then
  echo -e "\n=== prettier.config.cjs content ==="
  cat prettier.config.cjs
fi

# 4. Check package.json for "type": "module"
echo -e "\n=== Checking package.json for ESM type ==="
jq '.type // "not specified"' package.json

# 5. Find validate-json.js script
echo -e "\n=== Looking for validate-json.js ==="
fd validate-json

Length of output: 5544



---

🏁 Script executed:

```shell
#!/bin/bash

# Check validate-json.js for its available options and interface
echo "=== validate-json.js script (full content) ==="
cat scripts/json-validation/validate-json.js

echo -e "\n=== Checking for CLI argument parsing ==="
rg -n "process.argv|yargs|commander|minimist|--" scripts/json-validation/validate-json.js | head -20

Length of output: 14099


Add --no-config to Prettier check to bypass ESM/CommonJS config mismatch

The Prettier invocation fails because prettier.config.js uses CommonJS (module.exports) but the project is marked as ESM ("type": "module" in package.json). When Prettier loads the config, it tries to require('dotenv'), which fails in ESM scope.

-          npx prettier --check $(cat /tmp/changed-files.txt | tr '\n' ' ')
+          npx prettier --check --no-config $(cat /tmp/changed-files.txt | tr '\n' ' ')

This resolves the config loading error while keeping Prettier's formatting rules applied to JSON files only (which is safe for JSON-only validation).

🤖 Prompt for AI Agents
.github/workflows/json-validation.yml around lines 202 to 231: Prettier fails to
load the repo config due to an ESM/CommonJS mismatch; update the Prettier
invocation to skip loading config by adding the --no-config flag (i.e., call
Prettier with --no-config --check on the list of JSON files) so formatting is
checked using Prettier defaults for JSON only and avoids requiring the project
config.

- name: Comment on PR
if: failure() && github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `⚠️ **JSON validation failed**

Please ensure all JSON files are:
1. Properly formatted (run \`npm run format:json\`)
2. Valid syntax
3. Schema-compliant (if applicable)

See workflow logs for details.

## Quick fix commands:
\`\`\`bash
# Format all JSON files
npx prettier --write "**/*.json"

# Validate specific file
node scripts/json-validation/validate-json.js --glob "path/to/file.json"
\`\`\`

See [JSON Validation Documentation](https://github.com/lightspeedwp/.github/blob/develop/scripts/json-validation/README.md) for more details.`
})

comprehensive-validation:
name: Comprehensive Validation
runs-on: ubuntu-latest
needs: [format-check, syntax-validation]
if: github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/develop'

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run comprehensive validation
run: |
GLOB="${{ github.event.inputs.glob || '**/*.json' }}"
SCHEMA="${{ github.event.inputs.schema || '' }}"
READONLY="${{ github.event.inputs.read-only || 'false' }}"

CMD="node scripts/json-validation/validate-json.js --glob \"$GLOB\" --strict"

if [ "$READONLY" = "true" ]; then
CMD="$CMD --read-only"
fi

if [ -n "$SCHEMA" ]; then
CMD="$CMD --schema \"$SCHEMA\""
fi

echo "Running: $CMD"
eval $CMD

- name: Upload validation report
if: always()
uses: actions/upload-artifact@v4
with:
name: validation-report
path: reports/
retention-days: 30

- name: Generate summary
if: always()
run: |
echo "# Comprehensive JSON Validation Report" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Glob pattern:** \`${{ github.event.inputs.glob || '**/*.json' }}\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY

if [ -f "reports/ajv-errors.txt" ]; then
echo "## Validation Errors" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
head -n 50 reports/ajv-errors.txt >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
else
echo "✅ All validations passed!" >> $GITHUB_STEP_SUMMARY
fi
Loading
Loading