CI में JSON validation: jsonlint, ajv और jq के साथ एक pipeline
मुख्य बात: Syntax validation साबित करता है कि फ़ाइल parse होती है; schema validation साबित करता है कि fields अनुबंध का पालन करते हैं। CI में मायने रखती हैं स्पष्ट exit codes, error locations और मरम्मत के रास्ते।

सार: CI में jq empty को syntax संभालने दें, ajv-cli को structure (multi-format टीमों के लिए check-jsonschema), और Prettier को style; उन्हें परत-दर-परत श्रृंखला में चलाएँ और पहले failure पर रुकें।
आपके local एडिटर में parser पास होना यह नहीं दर्शाता कि फ़ाइल CI में जाने योग्य है; CI पास होना यह भी नहीं दर्शाता कि fields अनुबंध से मेल खाते हैं।
1. Syntax validation को schema validation से अलग रखें
"JSON validation" वाक्यांश बहुत व्यापक रूप से इस्तेमाल होता है, इसीलिए टीमें अक्सर दो अलग समस्याएँ हल करने के लिए एक ही उपकरण चुनती हैं:
| परत | कौन-सा प्रश्न उत्तरित | सामान्य उपकरण | Failure का अर्थ |
|---|---|---|---|
| Syntax | क्या यह फ़ाइल valid JSON है? | jq empty, jsonlint, python -m json.tool |
Brackets, commas, quotes या encoding टूटे हैं |
| Schema | क्या fields, types और required properties अनुबंध से मेल खाते हैं? | ajv-cli, check-jsonschema |
फ़ाइल parse होती है, पर business structure गलत है |
| Style | क्या indentation और key order संगत हैं? | Prettier, jq -S |
Formatting असंगत है और diffs शोर भरे हैं |
ये परतें एक-दूसरे की जगह नहीं ले सकतीं। जो फ़ाइल syntax पास करती है वह schema में fail हो सकती है: {"price": "12.5"} valid JSON है, पर अगर schema माँगता है कि price एक number हो, तो वह अस्वीकार्य है। उलटा भी, schema कितना भी पूर्ण हो, जिस फ़ाइल में closing brace गुम है वह उसके विरुद्ध कभी compile नहीं होगी।
इसलिए pipeline को पहले syntax, फिर structure और आख़िर में style चलाना चाहिए। किसी परत के fail होते ही रुकें, वरना parse error खुद को field error के रूप में छिपा लेता है।
2. Syntax परत: jq empty न्यूनतम-dependency विकल्प है
अगर jq पहले से CI image में है, तो syntax validation लगभग कुछ भी नहीं लेती:
jq empty data.json
jq empty कोई आउटपुट नहीं देता; वह केवल फ़ाइल parse करता है। सफल होने पर 0 से बाहर आता है और विफल होने पर non-zero code के साथ line/column जानकारी देता है। इससे यह पूरे Node dependency tree खींचने से हल्का है, और एक अच्छा पहला gate है।
Repository में JSON फ़ाइलों को batch में validate करते समय node_modules, build output और third-party caches को exclude करें:
find . -name '*.json' \
-not -path './node_modules/*' \
-not -path './dist/*' \
-print0 | xargs -0 -n1 jq empty
-print0 और xargs -0 फ़ाइल नामों में spaces संभालते हैं, जबकि -n1 सुनिश्चित करता है कि प्रति invocation एक फ़ाइल हो ताकि error संदेश दोषी की पहचान करे। सैकड़ों फ़ाइलें एक ही process को न दें; error संदेश एक-दूसरे को overwrite कर देंगे।
jsonlint एक और आम विकल्प है, आमतौर पर npx jsonlint -q data.json के रूप में बुलाया जाता है, जहाँ -q केवल errors छापता है। वह line और column numbers बताता है, पर उसका रखरखाव jq से कम सक्रिय है, और अलग संस्करण BOM व comments को अलग तरह से सहन करते हैं। इसे अधिक पठनीय syntax checker मानें, schema validator नहीं।
3. Schema परत: ajv-cli validate की मूल बातें
Ajv JavaScript पारिस्थितिकी तंत्र में सबसे व्यापक रूप से इस्तेमाल किया जाने वाला schema validator है, और ajv-cli उसे command-line उपकरण के रूप में उपलब्ध कराता है:
ajv validate -s schema.json -d data.json
-s schema फ़ाइल की ओर इंगित करता है और -d validate हो रहे डेटा की ओर। Failure पर process non-zero से बाहर आता है, इसलिए CI तुरंत fail होता है। असली प्रोजेक्ट्स आमतौर पर दो flags जोड़ते हैं:
npx ajv-cli validate \
-s schemas/order.json \
-d 'fixtures/orders/*.json' \
--strict=false \
--errors=text
--strict=false पुराने schemas में मदद करता है: strict mode अज्ञात keywords और संदिग्ध required घोषणाओं को errors मानता है, जिनमें कई legacy schemas fail हो जाते हैं। --errors=text मानव-पठनीय आउटपुट देता है, जबकि डिफ़ॉल्ट JSON structure मशीनों के लिए बेहतर है। परिणाम कौन उपभोग करता है, उसके अनुसार चुनें।
Schema draft संस्करण भी मेल खाना चाहिए। Ajv major संस्करण डिफ़ॉल्ट रूप से अलग drafts समर्थित करते हैं, और ajv-cli --spec=draft7, --spec=draft2019 या --spec=draft2020 से एक चुन सकता है। अगर schema $schema: "https://json-schema.org/draft/2020-12/schema" घोषित करता है पर CLI उसे draft-07 के रूप में compile करता है, तो कुछ keywords चुपचाप नज़रअंदाज़ हो जाते हैं। Schema लेखन और संस्करण अंतरों पर अधिक जानकारी के लिए देखें JSON Schema से शुरुआत।
Format validation एक और लगातार आने वाली आवश्यकता है। format keyword डिफ़ॉल्ट रूप से केवल annotation है; email, date-time और uri को वास्तव में कुछ लागू कराने के लिए ajv-formats लोड करें:
npx ajv-cli validate -c ajv-formats -s schema.json -d data.json
यह कदम आसानी से छूट जाता है, और परिणाम यह होता है कि कोई email field not-an-email स्वीकार कर लेता है। Ship करने से पहले pipeline को एक जानबूझकर invalid record दें; यह साबित करता है कि नियम सक्रिय है, documentation दस बार पढ़ने से कहीं बेहतर।
check-jsonschema: कई formats और अनुकूल errors
अगर टीम JSON के अलावा YAML, TOML या GitHub Actions configuration भी संभालती है, तो check-jsonschema अधिक सुविधाजनक है:
check-jsonschema --schemafile schemas/config.json config/app.json
check-jsonschema --schemafile schemas/pipeline.json .github/workflows/ci.yml
इसके व्यावहारिक लाभ:
- मूल YAML समर्थन, जो "JSON-आकार की पर YAML में लिखी" फ़ाइलों के लिए उपयुक्त है, जैसे Kubernetes manifests और CI configuration।
- Errors में फ़ाइल path, line number और field path शामिल होते हैं, जिससे location की लागत कम रहती है।
- एक pre-commit hook दिया जाता है, इसलिए integration सस्ती है।
- यह SchemaStore से सामान्य schemas खींच सकता है, पर local फ़ाइलें भी लेता है, जिससे network dependency से बचा जाता है।
Cross-language टीमों में Python अक्सर पहले से मौजूद होता है, इसलिए check-jsonschema install और upgrade करना Node toolchain बनाए रखने से हल्का है। jq को syntax और इस उपकरण को structure संभालने दें; संयोजन का रखरखाव ओवरहेड बहुत कम है।
4. Exit codes ही एकमात्र भरोसेमंद CI संकेत हैं
आउटपुट कितना भी चमकदार हो, CI केवल exit codes पढ़ता है। तीन traps आम हैं:
| लक्षण | कारण | समाधान |
|---|---|---|
| Errors मौजूद हैं पर CI हरा है | Command ` | |
| Errors नहीं हैं पर CI लाल है | diff "अंतर मिले" को failure मानता है |
"अंतर" और "execution error" में फ़र्क करें |
| Error आउटपुट कटा हुआ है | Parallel multi-file आउटपुट एक-दूसरे को overwrite करता है | क्रमबद्ध चलाएँ या प्रति फ़ाइल छापें |
jq exit-code semantics याद रखें: सामान्य parsing 0 लौटाता है; -e के साथ, expression का परिणाम false या null होने पर 1 लौटता है; usage errors और गुम फ़ाइलें 2 लौटाती हैं; script compilation errors 3 लौटाते हैं। Schema उपकरण आमतौर पर सफलता के लिए 0, validation failure के लिए 1 और उपकरण या argument errors के लिए 2 इस्तेमाल करते हैं। Wrapper लिखते समय हर non-zero code को "डेटा गलत है" में न समेटें, वरना environment failure को content समस्या समझकर गलत निदान होगा।
5. pre-commit: commit से पहले समस्याएँ पकड़ें
pre-commit का मूल्य "एक और जाँच" नहीं है; यह विकसितों को दस मिनट के CI run के बजाय एक मिनट में feedback देना है। न्यूनतम configuration ऐसा दिखता है:
repos:
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.33.0
hooks:
- id: check-jsonschema
files: ^configs/.*\.json$
args:
- --schemafile
- schemas/config.json
- repo: local
hooks:
- id: jq-syntax
name: jq syntax check
entry: jq empty
language: system
files: ^configs/.*\.json$
दो बातें मायने रखती हैं:
filesकेवल उन निर्देशिकाओं से मेल खाना चाहिए जिन्हें validation चाहिए। Hooks कोnode_modulesया generated फ़ाइलों पर न चलाएँ।- Local hook मानता है कि
jqविकसित की मशीन पर installed है। यह आवश्यकता document करें, या containerized hook पर जाएँ।
अगर प्रोजेक्ट पहले से Husky और lint-staged इस्तेमाल करता है, तो उन्हें सीधे जोड़ें:
{
"lint-staged": {
"configs/*.json": ["jq empty", "prettier --check"]
}
}
याद रखें कि lint-staged staged फ़ाइलों की सूची पास करता है, इसलिए command को कई paths स्वीकार करने चाहिए। jq empty और prettier --check दोनों करते हैं। Hook को पूरा repository scan न करने दें; commits स्पष्ट रूप से धीमे हो जाएँगे।
6. GitHub Actions: एक pipeline जिसे आप कॉपी कर सकते हैं
नीचे का workflow syntax validation और schema validation करता है, और failure पर report सुरक्षित रखता है:
name: json-validate
on:
push:
paths:
- 'schemas/**'
- 'fixtures/**'
pull_request:
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Syntax check
run: |
find fixtures -name '*.json' -print0 | xargs -0 -n1 jq empty
- name: Schema check
run: |
npx --yes ajv-cli validate \
-s schemas/order.json \
-d 'fixtures/orders/*.json' \
--strict=false \
--errors=text
paths filter केवल-documentation बदलावों को validation ट्रिगर करने से रोकता है। npx --yes उन repositories के लिए उपयुक्त है जिनमें dependencies pinned नहीं हैं; production प्रोजेक्ट्स को ajv-cli devDependencies में जोड़कर संस्करण pin करना चाहिए। Lock के बिना, डिफ़ॉल्ट draft या strict mode बदलने वाला upstream release एक रात में pipeline को लाल कर सकता है।
7. Error location: line numbers से field paths तक
Validator का आधा मूल्य detection है; बाकी आधा location। तीन तरह के आउटपुट पढ़ना सीखें:
- Syntax errors:
jqline और column बताता है, अक्सर साथ में नज़दीकी snippet। पहले brackets और commas ठीक करें; तुरंत encoding पर संदेह न करें। - Schema errors: Ajv का
instancePathडेटा स्थान की ओर इंगित करता है (जैसे/items/0/price),schemaPathनियम की ओर (जैसे#/properties/items/items/properties/price/type), औरkeywordउल्लंघन किए गए constraint का नाम बताता है। - Format errors: जब
formatजाँच fail होती है, संदेश अक्सर केवल "must match format "email"" कहता है। Field की पहचान के लिए इसेinstancePathके साथ जोड़ें।
instancePath को जाँच रिकॉर्ड में चिपकाएँ; यह JSON की दीवार से कहीं अधिक उपयोगी है। Arrays के लिए, संख्यात्मक index भी बताता है कि कौन-सा record fail हुआ। अगर business key अधिक सहज है, तो बाद में एक mapping पंक्ति जोड़ें, जैसे items[0].id = ORD-042।
सामान्य schema गलतियाँ, जैसे additionalProperties: false का अत्यधिक उपयोग या ऐसी oneOf शाखाएँ लिखना जो वास्तव में overlap करती हैं, सामान्य JSON Schema निर्माण pitfalls में covered हैं। गलत validation नियम बिना validation से अधिक खतरनाक है, क्योंकि वह सुरक्षा का झूठा भरोसा पैदा करता है।
8. उपकरण चयन तालिका
| ज़रूरत | सुझाया उपकरण | क्यों | किससे सावधान |
|---|---|---|---|
| केवल syntax | jq empty |
शून्य dependencies, तेज़, स्पष्ट exit codes | Batch runs में फ़ाइल नामों में spaces |
| अधिक अनुकूल line/column errors | jsonlint |
पठनीय आउटपुट | रखरखाव गतिविधि सीमित है |
| JSON Schema validation | ajv-cli |
परिपक्व पारिस्थितिकी तंत्र, संरचित errors | Draft संस्करण मिलाएँ और format समर्थन लोड करें |
| मिश्रित JSON और YAML repository | check-jsonschema |
Multi-format, pre-commit friendly | Schema स्रोत और network access |
| Commit से पहले तेज़ feedback | pre-commit / lint-staged | केवल staged फ़ाइलें process करता है | Hooks को कई paths स्वीकार करने चाहिए |
| संगत formatting | Prettier | व्यापक रूप से अपनाया गया | जब फ़ाइलें rewrite नहीं करनी हों तो --check इस्तेमाल करें |
एक अंतिम सुझाव: पहले pipeline को एक जानबूझकर invalid record देकर पुष्टि करें कि वह वास्तव में fail होता है। सबसे बड़ा जोखिम जटिल configuration नहीं; वह configuration है जो कभी प्रभावी ही नहीं होती। "यह fail हो सकता है" को acceptance मानदंड मानना "यह पास होता है" को मानदंड मानने से अधिक भरोसेमंद है। व्यापक command-line टूलचेन के लिए आगे पढ़ें एडिटर, कमांड लाइन और ऑटोमेशन।
सामान्य प्रश्न
jq empty इस्तेमाल करें या jsonlint?
CI में jq empty पसंद करें: शून्य dependencies, तेज़ शुरुआत, और स्पष्ट exit-code semantics। jsonlint तब इस्तेमाल करें जब अधिक अनुकूल line/column संदेश चाहिए या locally जाँच कर रहे हों। दोनों केवल syntax validation करते हैं; कोई field structure नहीं जाँचता।
ajv अज्ञात keyword की रिपोर्ट क्यों करता है?
पहले पुष्टि करें कि schema का $schema draft CLI के इस्तेमाल किए संस्करण से मेल खाता है। कई "unknown keyword" errors नए-draft keywords हैं जो पुराने compiler को मिले। अगर संस्करण मेल खाते हैं, तो typo देखें। --strict=false legacy schemas को चालू रख सकता है, पर असली समस्याएँ छिपाने के लिए उस पर लंबे समय तक निर्भर न रहें।
Schema validation पास होती है, पर API फिर भी fail होता है। क्यों?
Schema structure validate करता है, business semantics नहीं। उदाहरण के लिए, status एक string हो सकता है जिसमें वैध enum हो, पर state machine paid से सीधे refunded पर जाने से रोकता है। ऐसे नियम code या database constraints में होते हैं, JSON Schema में नहीं।
Fail हो रहा field जल्दी कैसे ढूँढें?
उपकरण आउटपुट से instancePath या line number पढ़ें। Ajv का instancePath एक JSON Pointer है जो सीधे डेटा की ओर इंगित करता है; check-jsonschema फ़ाइल और line बताता है। Path दर्ज करें और उसे business key से map करें; समस्या ढूँढने में आमतौर पर कुछ मिनट लगते हैं।
क्या pre-commit को पूरा validation चलाना चाहिए?
नहीं। pre-commit को केवल staged फ़ाइलें process करनी चाहिए ताकि commits तेज़ रहें। पूरा scan CI या scheduled jobs का काम है। विभाजन सरल है: local runs गति पसंद करते हैं, CI पूर्णता।