Skip to content

Commit 39e3878

Browse files
raych1mikeharder
andauthored
Create runner for breaking change check (#35353)
* Initial check in for openapi-diff-runner * added readme content * added report generator * added report generator * refactored code to be function based * refactor breaking change detector * added unit tests * refactor oad processor and logging * Added breaking change label processing * added workflows * updated dev deps * updated settings for test workflow * updated prettier script * checkout full history * fixed tests * added error handling for branch operation * added .net installation step * filter swaggers for the changed files * updated output variable name * continue on error in workflow * updated title in the report * updated triggers of update label WF * updated workflows list in the update label WF * removed brackets from WF name * Add trailing newline * upgraded openapi-diff pkg version * removed version from package.json * update package lock file * Revert "update package lock file" This reverts commit 3b1c4a5. * suppress node warnings * updated markdown table format * updated markdown table format * use node 20 * revert debug code --------- Co-authored-by: Mike Harder <[email protected]>
1 parent 9cfe920 commit 39e3878

36 files changed

+7449
-0
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
name: "[TEST-IGNORE] Swagger BreakingChange - Analyze Code"
2+
3+
on: pull_request
4+
5+
permissions:
6+
contents: read
7+
8+
jobs:
9+
validateBreakingChange:
10+
name: "[TEST-IGNORE] Swagger BreakingChange - Analyze Code"
11+
runs-on: ubuntu-24.04
12+
13+
steps:
14+
- name: Checkout repo
15+
uses: actions/checkout@v4
16+
with:
17+
fetch-depth: 0
18+
19+
- name: Setup Node and install deps
20+
uses: ./.github/actions/setup-node-install-deps
21+
with:
22+
node-version: '20.x'
23+
24+
- name: Setup .NET 6 SDK
25+
uses: actions/setup-dotnet@v4
26+
with:
27+
dotnet-version: '6.0.x'
28+
29+
- name: Swagger Breaking Change - Analyze Code
30+
id: swagger-breaking-change-analyze-code
31+
run: |
32+
npm exec --no -- openapi-diff-runner \
33+
--srp "${{ github.workspace }}" \
34+
--number "${{ github.event.pull_request.number }}" \
35+
--sb "${{ github.event.pull_request.head.ref }}" \
36+
--tb "${{ github.event.pull_request.base.ref }}" \
37+
--hc "${{ github.event.pull_request.head.sha }}" \
38+
--repo "${{ github.repository }}"
39+
40+
# Upload artifact for 'BreakingChangeReviewRequired' label
41+
- if: |
42+
always() &&
43+
(steps.swagger-breaking-change-analyze-code.outputs.breakingChangeReviewLabelName != '')
44+
name: Upload artifact with BreakingChangeReviewRequiredLabel label
45+
uses: ./.github/actions/add-label-artifact
46+
with:
47+
name: "${{ steps.swagger-breaking-change-analyze-code.outputs.breakingChangeReviewLabelName }}"
48+
value: "${{ steps.swagger-breaking-change-analyze-code.outputs.breakingChangeReviewLabelValue == 'true' }}"
49+
50+
# Upload artifact for 'VersioningReviewRequired' label
51+
- if: |
52+
always() &&
53+
(steps.swagger-breaking-change-analyze-code.outputs.versioningReviewLabelName != '')
54+
name: Upload artifact with VersioningReviewRequiredLabel label
55+
uses: ./.github/actions/add-label-artifact
56+
with:
57+
name: "${{ steps.swagger-breaking-change-analyze-code.outputs.versioningReviewLabelName }}"
58+
# Convert "add/remove" to "true/false"
59+
value: "${{ steps.swagger-breaking-change-analyze-code.outputs.versioningReviewLabelValue == 'true' }}"
60+
61+
# Upload artifact with issue number if labels are present and PR number is valid
62+
- if: |
63+
always() &&
64+
(steps.swagger-breaking-change-analyze-code.outputs.breakingChangeReviewLabelName != '' ||
65+
steps.swagger-breaking-change-analyze-code.outputs.versioningReviewLabelName != '') &&
66+
github.event.pull_request.number > 0
67+
name: Upload artifact with issue number
68+
uses: ./.github/actions/add-empty-artifact
69+
with:
70+
name: "issue-number"
71+
value: "${{ github.event.pull_request.number }}"
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: openapi-diff-runner - Test
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
paths:
9+
- package-lock.json
10+
- package.json
11+
- tsconfig.json
12+
- .github/workflows/_reusable-eng-tools-test.yaml
13+
- .github/workflows/openapi-diff-runner-test.yaml
14+
- eng/tools/package.json
15+
- eng/tools/tsconfig.json
16+
- eng/tools/openapi-diff-runner/**
17+
workflow_dispatch:
18+
19+
permissions:
20+
contents: read
21+
22+
jobs:
23+
openapiDiffRunner:
24+
name: openapi-diff-runner
25+
uses: ./.github/workflows/_reusable-eng-tools-test.yaml
26+
with:
27+
package: openapi-diff-runner
28+
lint: false
29+
prettier: true
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# OpenAPI Diff Runner
2+
3+
A tool for detecting breaking changes in OpenAPI specifications by comparing different versions and analyzing the
4+
differences using @azure/oad library.
5+
6+
## Overview
7+
8+
The OpenAPI Diff Runner is designed to:
9+
10+
- Compare OpenAPI specifications between different versions
11+
- Generate detailed reports of comparing result
12+
- Support both same-version and cross-version breaking change detection
13+
- Integrate with GitHub workflow for automated validation
14+
15+
## Installation
16+
17+
```bash
18+
# Install dependencies
19+
npm ci
20+
21+
# Build the project
22+
npm run build
23+
```
24+
25+
## Usage
26+
27+
### Command Line Interface
28+
29+
```bash
30+
# Basic usage
31+
npx openapi-diff-runner --srp <spec-repo-path> --repo <github-repo> --number <pr-number>
32+
33+
# Example
34+
npx openapi-diff-runner \
35+
--srp /path/to/azure-rest-api-specs \
36+
--repo Azure/azure-rest-api-specs \
37+
--number 12345 \
38+
--bb main \
39+
--rt SameVersion
40+
```
41+
42+
### Command Line Options
43+
44+
| Option | Description | Default |
45+
|--------|-------------|---------|
46+
| `--srp` | Spec repository path | `../` |
47+
| `--repo` | GitHub repository | `azure/azure-rest-api-specs` |
48+
| `--number` | Pull request number | Required |
49+
| `--bb` | Base branch | `main` |
50+
| `--rt` | Run type (SameVersion/CrossVersion) | `SameVersion` |
51+
| `--hc` | Head commit | `HEAD` |
52+
| `--sb` | Source branch | From PR |
53+
| `--tb` | Target branch | From PR |
54+
55+
## Breaking Change Types
56+
57+
### Same Version Breaking Changes
58+
59+
- Changes within the same API version that break backward compatibility
60+
- Examples: Removing properties, changing required fields, modifying response schemas
61+
62+
### Cross Version Breaking Changes
63+
64+
- Changes between different API versions
65+
- Helps ensure proper versioning and migration paths
66+
67+
### Workflow
68+
69+
1. **Initialize Context**: Parse command line arguments and setup environment
70+
2. **Setup PR Info**: Fetch pull request details and prepare Git workspace
71+
3. **Detect Changes**: Use OAD (OpenAPI Analysis) to compare specifications
72+
4. **Apply Rules**: Process detected changes through rule engine
73+
5. **Generate Report**: Create detailed output with violations and recommendations
74+
75+
## Development
76+
77+
### Prerequisites
78+
79+
- Node.js >= 20.0.0
80+
- npm
81+
- .NET 6
82+
- Git
83+
84+
### Building
85+
86+
```bash
87+
# Build TypeScript files
88+
npm run build
89+
90+
# Run tests
91+
npm test
92+
93+
# Run tests with coverage
94+
npm run test:ci
95+
96+
# Lint code
97+
npm run prettier
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/env node
2+
3+
import { main } from "../dist/src/index.js";
4+
5+
await main();
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "@azure-tools/openapi-diff-runner",
3+
"private": true,
4+
"type": "module",
5+
"main": "dist/src/index.js",
6+
"bin": {
7+
"openapi-diff-runner": "cmd/openapi-diff-runner.js"
8+
},
9+
"scripts": {
10+
"build": "tsc --build",
11+
"test": "vitest",
12+
"test:ci": "vitest --coverage --reporter=verbose",
13+
"prettier": "prettier \"**/*.ts\" \"!dist/**\" --check",
14+
"prettier:write": "prettier \"**/*.ts\" \"!dist/**\" --write"
15+
},
16+
"engines": {
17+
"node": ">=20.0.0"
18+
},
19+
"dependencies": {
20+
"@azure-tools/specs-shared": "file:../../../.github/shared",
21+
"@azure/oad": "0.10.14"
22+
},
23+
"devDependencies": {
24+
"@types/node": "^20.0.0",
25+
"@vitest/coverage-v8": "^3.0.7",
26+
"typescript": "~5.8.2",
27+
"vitest": "^3.0.7"
28+
}
29+
}

0 commit comments

Comments
 (0)