specshield 1.0.5 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,153 +1,742 @@
1
- # 🚀 SpecShield — OpenAPI Diff & Breaking Change Detection CLI
1
+ # SpecShield CLI
2
2
 
3
- ![npm](https://img.shields.io/npm/v/specshield)
4
- ![downloads](https://img.shields.io/npm/dw/specshield)
5
- ![license](https://img.shields.io/badge/license-MIT-blue)
6
- ![node](https://img.shields.io/badge/node-%3E%3D18-green)
3
+ [![npm](https://img.shields.io/npm/v/specshield)](https://www.npmjs.com/package/specshield)
4
+ [![downloads](https://img.shields.io/npm/dw/specshield)](https://www.npmjs.com/package/specshield)
5
+ [![license](https://img.shields.io/badge/license-MIT-blue)](#license)
6
+ [![node](https://img.shields.io/badge/node-%3E%3D18-green)](https://nodejs.org)
7
7
 
8
8
  Compare OpenAPI and Swagger specs, detect breaking changes, and fail CI before incompatible API changes reach production.
9
9
 
10
+ ---
11
+
12
+ ## Table of Contents
13
+
14
+ - [What is SpecShield CLI?](#what-is-specshield-cli)
15
+ - [Installation](#installation)
16
+ - [Local Compare](#local-compare)
17
+ - [Authentication](#authentication)
18
+ - [Generate an API Token](#generate-an-api-token)
19
+ - [Remote Compare](#remote-compare)
20
+ - [Contracts — Consumer-Driven Testing](#contracts--consumer-driven-testing)
21
+ - [Contract File Format](#contract-file-format)
22
+ - [Publish a Contract](#publish-a-contract)
23
+ - [List Contracts](#list-contracts)
24
+ - [Get Latest Contract](#get-latest-contract)
25
+ - [Verify a Contract](#verify-a-contract)
26
+ - [Verification History](#verification-history)
27
+ - [Can I Deploy?](#can-i-deploy)
28
+ - [Full Publish → Verify → Deploy Workflow](#full-publish--verify--deploy-workflow)
29
+ - [Contracts in CI/CD](#contracts-in-cicd)
30
+ - [Config File](#config-file)
31
+ - [All Options](#all-options)
32
+ - [Exit Codes](#exit-codes)
33
+ - [CI/CD — GitHub Actions](#cicd--github-actions)
34
+ - [Support](#support)
10
35
 
11
- ## 📌 What is SpecShield?
36
+ ---
12
37
 
13
- SpecShield is a CLI tool that compares two OpenAPI/Swagger specifications and detects:
38
+ ## What is SpecShield CLI?
14
39
 
15
- - Breaking changes
16
- - ➕ Additions
17
- - 🔄 Modifications
40
+ SpecShield CLI is a command-line tool for comparing two OpenAPI/Swagger specifications and detecting what changed between them. It classifies changes into:
18
41
 
19
- It is designed for:
20
- - CI/CD pipelines
21
- - Backend developers
22
- - API governance teams
23
- - Local development workflows
42
+ - **Breaking changes** — removed endpoints, changed required fields, incompatible type changes
43
+ - **Modifications** — changed behavior that may or may not break clients
44
+ - **Additions** — new endpoints or fields
45
+ - **Warnings** low-severity notices
46
+
47
+ It works in two modes:
48
+
49
+ | Mode | Description |
50
+ |---|---|
51
+ | **Local** | Compares two spec files on your machine. No account needed. |
52
+ | **Remote** | Sends specs to the SpecShield hosted API. Requires an API token. Results are stored in your dashboard. |
24
53
 
25
54
  ---
26
55
 
27
- ## ❗ Why SpecShield?
56
+ ## Installation
28
57
 
29
- API changes can silently break:
30
- - Mobile apps
31
- - Frontend clients
32
- - Partner integrations
33
- - Internal microservices
58
+ ```bash
59
+ npm install -g specshield
60
+ ```
34
61
 
35
- Manual API review is:
36
- - ❌ Error-prone
37
- - ❌ Time-consuming
38
- - ❌ Not scalable
62
+ Verify the installation:
39
63
 
40
- 👉 SpecShield solves this by automating API contract validation.
64
+ ```bash
65
+ specshield --version
66
+ ```
41
67
 
42
68
  ---
43
69
 
44
- ## 🎯 Key Benefits
70
+ ## Local Compare
71
+
72
+ No account or token required for local comparisons.
73
+
74
+ ```bash
75
+ specshield compare base.yaml target.yaml
76
+ ```
77
+
78
+ Fail CI if breaking changes are found:
45
79
 
46
- - 🚫 Prevent breaking API releases
47
- - ⚙️ Enforce API contract checks in CI/CD
48
- - 🔍 Compare OpenAPI specs automatically
49
- - 📊 Generate machine-readable reports
50
- - 🧩 Integrate easily with existing workflows
51
- - 🛑 Fail builds when breaking changes are detected
80
+ ```bash
81
+ specshield compare base.yaml target.yaml --fail-on-breaking
82
+ ```
83
+
84
+ Output as JSON:
85
+
86
+ ```bash
87
+ specshield compare base.yaml target.yaml --json
88
+ ```
89
+
90
+ Save results to a file:
91
+
92
+ ```bash
93
+ specshield compare base.yaml target.yaml --output result.json
94
+ ```
95
+
96
+ Ignore specific changes:
97
+
98
+ ```bash
99
+ specshield compare base.yaml target.yaml --ignore "DELETE /users removed" --fail-on-breaking
100
+ ```
52
101
 
53
102
  ---
54
103
 
55
- ## ✨ Features
104
+ ## Authentication
56
105
 
57
- - Detect breaking changes, additions, and modifications
58
- - Support YAML and JSON OpenAPI specs
59
- - CI/CD-ready with exit codes
60
- - JSON output for automation
61
- - `.specshield.yml` config support
62
- - Ignore list for known changes
63
- - Future SaaS-ready remote mode
106
+ Remote compare requires a SpecShield account and an API token.
64
107
 
65
- ## Installation
108
+ ### Sign in to SpecShield
109
+
110
+ 1. Go to [https://specshield.io](https://specshield.io)
111
+ 2. Sign in with your email/password, GitHub, or Google account
112
+ 3. You will land on your account dashboard
113
+
114
+ ### Generate an API Token
115
+
116
+ 1. From your dashboard, go to **Account → API Keys**
117
+ (direct link: [https://specshield.io/account/keys](https://specshield.io/account/keys))
118
+ 2. Click **Generate API Key**
119
+ 3. Copy the token — it starts with `ss_` and is shown only once
120
+ 4. Store it securely (password manager, secrets vault, or CI/CD secret)
121
+
122
+ ### Configure the CLI
123
+
124
+ Run the login command with your token:
66
125
 
67
126
  ```bash
68
- npm install -g specshield
69
- # or use locally:
70
- npm install && npm link
127
+ specshield login --api-key ss_your_token_here
128
+ ```
129
+
130
+ This validates the token against the SpecShield API and saves it to `~/.specshield/config.json`. You will not need to pass the token on every command after this.
131
+
132
+ **Example output:**
133
+
134
+ ```
135
+ ✔ Logged in successfully.
136
+
137
+ Customer: Jane Smith
138
+ Plan: FREE
139
+ Config: /Users/jane/.specshield/config.json
140
+
141
+ Run: specshield compare base.yaml target.yaml --remote
71
142
  ```
72
143
 
73
- ## Usage
144
+ ### Alternative: Environment Variable
145
+
146
+ If you prefer not to use the stored config (e.g. in CI/CD), set the token as an environment variable:
74
147
 
75
- ### Basic comparison
76
148
  ```bash
77
- specshield compare base.yaml target.yaml
149
+ export SPECSHIELD_API_KEY=ss_your_token_here
150
+ specshield compare base.yaml target.yaml --remote
78
151
  ```
79
152
 
80
- ### Fail CI on breaking changes
153
+ The token resolution order is:
154
+
155
+ 1. `--api-key` flag (highest priority)
156
+ 2. `SPECSHIELD_API_KEY` environment variable
157
+ 3. Stored config (`~/.specshield/config.json`)
158
+ 4. `remote.apiKey` in `.specshield.yml`
159
+
160
+ ### Log Out
161
+
162
+ To remove the stored token:
163
+
81
164
  ```bash
82
- specshield compare base.yaml target.yaml --fail-on-breaking
165
+ specshield logout
83
166
  ```
84
167
 
85
- ### JSON output (for scripts/automation)
168
+ ---
169
+
170
+ ## Remote Compare
171
+
172
+ Remote compare sends your spec files to the SpecShield hosted API at [https://specshield.io](https://specshield.io). Results are processed server-side and stored in your dashboard for review.
173
+
174
+ **When to use remote mode:**
175
+ - You want comparison history tracked in the SpecShield dashboard
176
+ - Your team shares a centralized view of API drift over time
177
+ - You are on a plan with advanced reporting features
178
+
179
+ ### Basic remote compare
180
+
86
181
  ```bash
87
- specshield compare base.yaml target.yaml --json
182
+ specshield compare base.yaml target.yaml --remote
88
183
  ```
89
184
 
90
- ### Save results to file
185
+ ### Remote compare with CI fail on breaking changes
186
+
91
187
  ```bash
92
- specshield compare base.yaml target.yaml --output result.json
188
+ specshield compare base.yaml target.yaml --remote --fail-on-breaking
93
189
  ```
94
190
 
95
- ### Ignore specific changes
191
+ ### Remote compare with JSON output
192
+
96
193
  ```bash
97
- specshield compare base.yaml target.yaml --ignore "DELETE /users removed" --fail-on-breaking
194
+ specshield compare base.yaml target.yaml --remote --json --output result.json
98
195
  ```
99
196
 
100
- ### Use custom config
197
+ ### How authentication works in remote mode
198
+
199
+ The CLI reads your API token (from flag, env var, or stored config) and sends it as an `X-Api-Key` header with each request. If no token is found, the command exits with an error:
200
+
201
+ ```
202
+ Error: No API key found. Run: specshield login --api-key <KEY>
203
+ ```
204
+
205
+ ---
206
+
207
+ ---
208
+
209
+ ## Contracts — Consumer-Driven Testing
210
+
211
+ SpecShield Contracts lets consumer teams publish API expectations (contracts) to a central registry. Provider teams then verify their service satisfies those contracts before deploying.
212
+
213
+ **Why contract testing?**
214
+ - Catch provider-side regressions before they reach consumers
215
+ - Enforce an agreed-upon API shape across services
216
+ - Gate deployments on verified contracts with `can-i-deploy`
217
+
218
+ All contract commands require an API token. See [Authentication](#authentication).
219
+
220
+ ---
221
+
222
+ ### Contract File Format
223
+
224
+ Create a `.json` file describing the expected API interactions:
225
+
226
+ ```json
227
+ {
228
+ "consumer": {
229
+ "name": "checkout-ui",
230
+ "version": "1.2.0"
231
+ },
232
+ "provider": {
233
+ "name": "payment-service"
234
+ },
235
+ "contractName": "create-payment",
236
+ "contractType": "HTTP",
237
+ "interactions": [
238
+ {
239
+ "description": "create payment",
240
+ "request": {
241
+ "method": "POST",
242
+ "path": "/payments",
243
+ "headers": {
244
+ "Content-Type": "application/json"
245
+ },
246
+ "body": {
247
+ "orderId": "ORD-123",
248
+ "amount": 100,
249
+ "currency": "INR"
250
+ }
251
+ },
252
+ "expectedResponse": {
253
+ "status": 201,
254
+ "headers": {
255
+ "Content-Type": "application/json"
256
+ },
257
+ "body": {
258
+ "paymentId": "PAY-123",
259
+ "status": "CREATED"
260
+ }
261
+ }
262
+ }
263
+ ],
264
+ "metadata": {
265
+ "generatedBy": "specshield-cli",
266
+ "contractFormatVersion": "1.0"
267
+ }
268
+ }
269
+ ```
270
+
271
+ The `consumer.name`, `provider.name`, and `contractName` fields are used to identify the contract in the registry. CLI flags (`--consumer`, `--provider`, `--contract-name`) override file values if provided.
272
+
273
+ ---
274
+
275
+ ### Publish a Contract
276
+
101
277
  ```bash
102
- specshield compare base.yaml target.yaml --config ./configs/.specshield.yml
278
+ specshield contracts publish \
279
+ --file ./contracts/create-payment.json \
280
+ --org acme
103
281
  ```
104
282
 
105
- ## Options
283
+ With all flags explicitly set (flags override file values):
106
284
 
107
- | Option | Description |
285
+ ```bash
286
+ specshield contracts publish \
287
+ --file ./contracts/create-payment.json \
288
+ --org acme \
289
+ --consumer checkout-ui \
290
+ --provider payment-service \
291
+ --contract-name create-payment \
292
+ --consumer-version 1.2.0 \
293
+ --tag main
294
+ ```
295
+
296
+ **Example output:**
297
+
298
+ ```
299
+ ✔ Contract Published Successfully
300
+ ─────────────────────────────────────────────────────
301
+ Contract ID : 42
302
+ Contract Name : create-payment
303
+ Consumer : checkout-ui
304
+ Provider : payment-service
305
+ Version : 3
306
+ Status : PUBLISHED
307
+ Content Hash : a3f9c1d2e7b8...
308
+ Published At : 06/04/2026 14:30:00
309
+
310
+ ➜ Run: specshield contracts verify --contract-id 42 --base-url http://localhost:8080
311
+ ```
312
+
313
+ **Options:**
314
+
315
+ | Flag | Description |
108
316
  |---|---|
109
- | `--json` | Output machine-readable JSON |
110
- | `--output <file>` | Save result to file |
111
- | `--fail-on-breaking` | Exit 1 if breaking changes found |
112
- | `--allow-breaking` | Override fail behavior |
113
- | `--config <path>` | Path to `.specshield.yml` |
114
- | `--ignore <change>` | Ignore a change string (repeatable) |
115
- | `--severity <level>` | `info` / `warning` / `error` |
116
- | `--remote-url <url>` | Remote API endpoint (future mode) |
117
- | `--timeout <ms>` | Timeout for remote requests |
317
+ | `--file <path>` | Path to contract JSON file (required) |
318
+ | `--org <key>` | Organization key |
319
+ | `--consumer <key>` | Consumer service key (overrides file) |
320
+ | `--provider <key>` | Provider service key (overrides file) |
321
+ | `--consumer-version <ver>` | Consumer version tag |
322
+ | `--contract-name <name>` | Contract name (overrides file) |
323
+ | `--tag <tag>` | Git branch or release tag |
324
+ | `--server <url>` | SpecShield server URL (default: `https://specshield.io`) |
325
+ | `--api-token <token>` | API token |
326
+
327
+ ---
328
+
329
+ ### List Contracts
330
+
331
+ ```bash
332
+ specshield contracts list
333
+ ```
334
+
335
+ Filter by provider:
336
+
337
+ ```bash
338
+ specshield contracts list --provider payment-service
339
+ ```
340
+
341
+ Filter by consumer, org, status:
342
+
343
+ ```bash
344
+ specshield contracts list \
345
+ --consumer checkout-ui \
346
+ --provider payment-service \
347
+ --status PUBLISHED
348
+ ```
349
+
350
+ Output raw JSON:
351
+
352
+ ```bash
353
+ specshield contracts list --json
354
+ ```
355
+
356
+ **Example output:**
357
+
358
+ ```
359
+ SpecShield Contract Registry
360
+ ─────────────────────────────────────────────────────
361
+ Showing 2 of 2 contracts
362
+
363
+ ID Contract Name Consumer Provider Ver Status Last Verify Published
364
+ ── ─────────────── ──────────── ─────────────── ─── ───────── ─────────── ─────────────────────
365
+ 42 create-payment checkout-ui payment-service 3 PUBLISHED SUCCESS 06/04/2026 14:30:00
366
+ 41 get-order-status order-ui order-service 1 PUBLISHED FAILED 05/04/2026 09:15:00
367
+ ```
368
+
369
+ **Options:**
370
+
371
+ | Flag | Description |
372
+ |---|---|
373
+ | `--consumer <key>` | Filter by consumer |
374
+ | `--provider <key>` | Filter by provider |
375
+ | `--org <key>` | Filter by organization |
376
+ | `--status <status>` | Filter by status (`PUBLISHED` / `DEPRECATED`) |
377
+ | `--contract-name <name>` | Filter by contract name |
378
+ | `--page <n>` | Page number (0-based, default: `0`) |
379
+ | `--size <n>` | Page size (default: `20`) |
380
+ | `--json` | Output raw JSON |
381
+
382
+ ---
383
+
384
+ ### Get Latest Contract
385
+
386
+ ```bash
387
+ specshield contracts latest \
388
+ --consumer checkout-ui \
389
+ --provider payment-service \
390
+ --contract-name create-payment
391
+ ```
392
+
393
+ Print the full contract content (interactions, body, etc.):
394
+
395
+ ```bash
396
+ specshield contracts latest \
397
+ --consumer checkout-ui \
398
+ --provider payment-service \
399
+ --json
400
+ ```
401
+
402
+ **Options:**
403
+
404
+ | Flag | Description |
405
+ |---|---|
406
+ | `--consumer <key>` | Consumer service key |
407
+ | `--provider <key>` | Provider service key |
408
+ | `--org <key>` | Organization key |
409
+ | `--contract-name <name>` | Contract name |
410
+ | `--json` | Print full contract JSON |
411
+
412
+ ---
413
+
414
+ ### Verify a Contract
415
+
416
+ Run the contract against a live provider. SpecShield replays each interaction against the `--base-url` and compares the response to the expected values.
417
+
418
+ ```bash
419
+ specshield contracts verify \
420
+ --contract-id 42 \
421
+ --base-url http://localhost:8080
422
+ ```
423
+
424
+ With version and environment tags:
425
+
426
+ ```bash
427
+ specshield contracts verify \
428
+ --contract-id 42 \
429
+ --base-url https://payment-service.staging.internal \
430
+ --provider-version v2.1.0 \
431
+ --env staging
432
+ ```
433
+
434
+ Output raw JSON (for CI parsing):
435
+
436
+ ```bash
437
+ specshield contracts verify \
438
+ --contract-id 42 \
439
+ --base-url http://localhost:8080 \
440
+ --json
441
+ ```
442
+
443
+ **Example output (pass):**
444
+
445
+ ```
446
+ ✔ Verification PASSED (1/1 interactions)
447
+ ─────────────────────────────────────────────────────
448
+ Verification ID : 101
449
+ Contract ID : 42
450
+ Status : SUCCESS
451
+ Started At : 06/04/2026 14:35:00
452
+ Completed At : 06/04/2026 14:35:01
453
+
454
+ ➜ Run: specshield contracts can-i-deploy --provider payment-service --version v2.1.0
455
+ ```
456
+
457
+ **Example output (fail):**
458
+
459
+ ```
460
+ ✖ Verification FAILED (0/1 interactions passed, 1 failed)
461
+ ─────────────────────────────────────────────────────
462
+ Verification ID : 102
463
+ Contract ID : 42
464
+ Status : FAILED
465
+
466
+ Mismatches
467
+ ─────────────────────────────────────────────────────
468
+ ● [create payment] STATUS_CODE_MISMATCH at $.status
469
+ expected: 201 → actual: 200
470
+ Expected status 201 but got 200
471
+
472
+ ➜ Run: specshield contracts history --contract-id 42 to inspect previous runs
473
+ ```
474
+
475
+ **Exit codes:** `0` = PASSED, `1` = FAILED, `2` = error
476
+
477
+ **Options:**
478
+
479
+ | Flag | Description |
480
+ |---|---|
481
+ | `--contract-id <id>` | Contract ID to verify (required) |
482
+ | `--base-url <url>` | Provider base URL (required, e.g. `http://localhost:8080`) |
483
+ | `--provider-version <ver>` | Provider version tag |
484
+ | `--env <environment>` | Environment label (`staging`, `qa`, `production`) |
485
+ | `--mode <mode>` | `LIVE` or `REPLAY` (default: `LIVE`) |
486
+ | `--json` | Output raw JSON |
487
+
488
+ ---
489
+
490
+ ### Verification History
491
+
492
+ ```bash
493
+ specshield contracts history --contract-id 42
494
+ ```
495
+
496
+ **Example output:**
497
+
498
+ ```
499
+ Verification History — Contract 42
500
+ ─────────────────────────────────────────────────────
501
+
502
+ ID Status Environment Provider Version Mode Completed At
503
+ ─── ─────── ─────────── ──────────────── ──── ─────────────────────
504
+ 102 FAILED staging v2.1.0 LIVE 06/04/2026 14:35:01
505
+ 101 SUCCESS staging v2.0.0 LIVE 05/04/2026 10:00:00
506
+ 98 SUCCESS qa v1.9.0 LIVE 01/04/2026 08:30:00
507
+ ```
508
+
509
+ **Options:**
510
+
511
+ | Flag | Description |
512
+ |---|---|
513
+ | `--contract-id <id>` | Contract ID (required) |
514
+ | `--json` | Output raw JSON |
515
+
516
+ ---
517
+
518
+ ### Can I Deploy?
519
+
520
+ Check whether a provider version has passing verifications for all associated contracts:
521
+
522
+ ```bash
523
+ specshield contracts can-i-deploy \
524
+ --provider payment-service \
525
+ --version v2.1.0
526
+ ```
527
+
528
+ Scoped to a specific environment:
529
+
530
+ ```bash
531
+ specshield contracts can-i-deploy \
532
+ --provider payment-service \
533
+ --version v2.1.0 \
534
+ --env production
535
+ ```
536
+
537
+ **Example output (allowed):**
538
+
539
+ ```
540
+ ✔ PASS: payment-service v2.1.0 is deployable in production
541
+ ─────────────────────────────────────────────────────
542
+
543
+ Contract Decisions
544
+ ✔ Contract ID 42 — SUCCESS
545
+ All contracts verified
546
+ ```
547
+
548
+ **Example output (blocked):**
549
+
550
+ ```
551
+ ✖ FAIL: payment-service v2.1.0 is NOT deployable in production
552
+ ─────────────────────────────────────────────────────
553
+
554
+ Contract Decisions
555
+ ✖ Contract ID 43 — FAILED
556
+ Unverified or failed contracts found
557
+
558
+ ➜ Run: specshield contracts verify --contract-id 43 --base-url <URL>
559
+ ➜ to verify pending contracts before deploying
560
+ ```
561
+
562
+ **Exit codes:** `0` = deployable, `1` = blocked, `2` = error
563
+
564
+ **Options:**
565
+
566
+ | Flag | Description |
567
+ |---|---|
568
+ | `--provider <key>` | Provider service key (required) |
569
+ | `--version <ver>` | Provider version to check (required) |
570
+ | `--env <environment>` | Target environment |
571
+ | `--json` | Output raw JSON |
572
+
573
+ ---
574
+
575
+ ### Full Publish → Verify → Deploy Workflow
576
+
577
+ ```bash
578
+ # 1. Consumer team publishes a contract
579
+ specshield contracts publish \
580
+ --file ./contracts/create-payment.json \
581
+ --org acme
582
+
583
+ # 2. Provider team starts their service locally
584
+ ./gradlew bootRun &
585
+
586
+ # 3. Provider team verifies the contract
587
+ specshield contracts verify \
588
+ --contract-id 42 \
589
+ --base-url http://localhost:8080 \
590
+ --provider-version v2.1.0 \
591
+ --env staging
592
+
593
+ # 4. Gate the deployment
594
+ specshield contracts can-i-deploy \
595
+ --provider payment-service \
596
+ --version v2.1.0 \
597
+ --env staging
598
+ ```
599
+
600
+ ---
601
+
602
+ ### Contracts in CI/CD
603
+
604
+ #### GitHub Actions — Publish on consumer change
605
+
606
+ ```yaml
607
+ name: Publish Contract
608
+
609
+ on:
610
+ push:
611
+ branches: [main]
612
+ paths:
613
+ - 'contracts/**'
614
+
615
+ jobs:
616
+ publish-contract:
617
+ runs-on: ubuntu-latest
618
+ steps:
619
+ - uses: actions/checkout@v4
620
+ - uses: actions/setup-node@v4
621
+ with:
622
+ node-version: '20'
623
+ - run: npm install -g specshield
624
+ - name: Publish contract
625
+ env:
626
+ SPECSHIELD_API_KEY: ${{ secrets.SPECSHIELD_API_KEY }}
627
+ run: |
628
+ specshield contracts publish \
629
+ --file ./contracts/create-payment.json \
630
+ --org acme \
631
+ --tag ${{ github.ref_name }}
632
+ ```
633
+
634
+ #### GitHub Actions — Verify + can-i-deploy on provider change
635
+
636
+ ```yaml
637
+ name: Contract Verification
638
+
639
+ on:
640
+ push:
641
+ branches: [main]
642
+
643
+ jobs:
644
+ verify-contracts:
645
+ runs-on: ubuntu-latest
646
+ services:
647
+ payment-service:
648
+ image: myorg/payment-service:${{ github.sha }}
649
+ ports:
650
+ - 8080:8080
651
+ steps:
652
+ - uses: actions/checkout@v4
653
+ - uses: actions/setup-node@v4
654
+ with:
655
+ node-version: '20'
656
+ - run: npm install -g specshield
657
+
658
+ - name: Verify contract
659
+ env:
660
+ SPECSHIELD_API_KEY: ${{ secrets.SPECSHIELD_API_KEY }}
661
+ run: |
662
+ specshield contracts verify \
663
+ --contract-id ${{ vars.PAYMENT_CONTRACT_ID }} \
664
+ --base-url http://localhost:8080 \
665
+ --provider-version ${{ github.sha }} \
666
+ --env staging
667
+
668
+ - name: Can I deploy?
669
+ env:
670
+ SPECSHIELD_API_KEY: ${{ secrets.SPECSHIELD_API_KEY }}
671
+ run: |
672
+ specshield contracts can-i-deploy \
673
+ --provider payment-service \
674
+ --version ${{ github.sha }} \
675
+ --env staging
676
+ ```
677
+
678
+ ---
118
679
 
119
680
  ## Config File
120
681
 
121
- Create `.specshield.yml` in your project root:
682
+ Create `.specshield.yml` in your project root to set default behavior:
122
683
 
123
684
  ```yaml
124
- allowBreakingChanges: false
125
685
  failOnBreaking: true
686
+ allowBreakingChanges: false
687
+ severity: error
126
688
 
127
689
  ignore:
128
- - "User.email removed"
129
- - "/admin DELETE removed"
130
-
131
- severity: error
690
+ - "DELETE /admin removed"
691
+ - "User.internal_id removed"
132
692
 
133
693
  remote:
134
694
  enabled: false
135
- url: "https://api.specshield.io/compare"
695
+ url: "https://specshield.io/compare"
136
696
  timeout: 10000
697
+ apiKey: "" # prefer env var or specshield login instead
698
+ ```
699
+
700
+ CLI flags always override config file values.
701
+
702
+ ---
703
+
704
+ ## All Options
705
+
706
+ ```bash
707
+ specshield compare <base> <target> [options]
137
708
  ```
138
709
 
139
- > CLI arguments always override config file values.
710
+ | Option | Description |
711
+ |---|---|
712
+ | `--remote` | Use the SpecShield hosted compare API |
713
+ | `--api-key <key>` | API token for remote mode (overrides env and stored config) |
714
+ | `--remote-url <url>` | Override the hosted API base URL |
715
+ | `--fail-on-breaking` | Exit code 1 if breaking changes are found |
716
+ | `--allow-breaking` | Override fail-on-breaking |
717
+ | `--json` | Output machine-readable JSON |
718
+ | `--output <file>` | Save result to a file |
719
+ | `--ignore <change>` | Ignore a specific change string (repeatable) |
720
+ | `--severity <level>` | Minimum severity: `info` / `warning` / `error` |
721
+ | `--config <path>` | Path to `.specshield.yml` |
722
+ | `--timeout <ms>` | Request timeout for remote mode (default: 10000) |
723
+
724
+ ---
140
725
 
141
726
  ## Exit Codes
142
727
 
143
728
  | Code | Meaning |
144
729
  |---|---|
145
730
  | `0` | Success — no blocking issues |
146
- | `1` | Breaking changes found and `--fail-on-breaking` active |
147
- | `2` | Invalid input, config error, or runtime error |
731
+ | `1` | Breaking changes found and `--fail-on-breaking` is active |
732
+ | `2` | Invalid input, missing token, config error, or runtime error |
733
+
734
+ ---
148
735
 
149
736
  ## CI/CD — GitHub Actions
150
737
 
738
+ ### Local compare (no token required)
739
+
151
740
  ```yaml
152
741
  name: API Contract Check
153
742
 
@@ -169,7 +758,6 @@ jobs:
169
758
 
170
759
  - run: npm install -g specshield
171
760
 
172
- # Option A: spec files are committed to the repo
173
761
  - name: Get base spec from main branch
174
762
  run: git show origin/main:api/openapi.yaml > /tmp/base-spec.yaml
175
763
 
@@ -187,22 +775,31 @@ jobs:
187
775
  path: spec-diff.json
188
776
  ```
189
777
 
190
- > **Note:** Some projects generate their OpenAPI spec dynamically (e.g. from Spring Boot annotations, FastAPI, etc.) instead of storing a static file. In that case, add a build step before the compare step to generate the spec from your code.
778
+ ### Remote compare (with SpecShield hosted API)
191
779
 
192
- ## Running Locally
780
+ Add your API token as a GitHub Actions secret named `SPECSHIELD_API_KEY`, then:
193
781
 
194
- ```bash
195
- npm install
196
- npm link
197
- specshield compare fixtures/spec-v1.yaml fixtures/spec-v2.yaml --fail-on-breaking
782
+ ```yaml
783
+ - name: Compare specs (remote)
784
+ env:
785
+ SPECSHIELD_API_KEY: ${{ secrets.SPECSHIELD_API_KEY }}
786
+ run: |
787
+ specshield compare /tmp/base-spec.yaml api/openapi.yaml \
788
+ --remote \
789
+ --fail-on-breaking \
790
+ --output spec-diff.json
198
791
  ```
199
792
 
200
- ## Running Tests
793
+ > **Note:** If your project generates its OpenAPI spec dynamically (e.g. Spring Boot, FastAPI), add a build step before the compare step to generate the spec from your code.
201
794
 
202
- ```bash
203
- npm test
204
- ```
795
+ ---
205
796
 
206
797
  ## License
207
798
 
208
799
  MIT © Deepak Satyam
800
+
801
+ ---
802
+
803
+ ## Support
804
+
805
+ Questions or issues? Reach out at [admin@specshield.io](mailto:admin@specshield.io) or open an issue on GitHub.