Skip to content

Commit afd7a73

Browse files
authored
Test OpenAPI schema has no breaking changes (#979)
Modified `test_openapi` so that after it generates the current schema and runs the OpenAPI linter, it'll also check for breaking changes. I'm adding this test because we can no longer break old versions of Zoo Design Studio. We should really never break the OpenAPI schema. If you find you need a breaking change, just make a new endpoint instead. The new "check for breaking changes" test logic is pretty simple. It does this by: 1. Downloading the latest schema on `main` branch from GitHub 2. Reading this branch's schema from disk (written earlier in `test_openapi`) 3. Run `just breaking-api-changes`, which 4. compares the two schemae via the `openapi-changes` CLI tool. 5. If there's a breaking change, that tool terminates with exit code 1 (and 0 i.e. OK if there's no changes, or only additive changes). In my testing, this tool has much better understanding of OpenAPI than `oasdiff`, which the engine currently uses. For example, `oasdiff` thinks that adding a new optional field, or a field with a default value is a breaking change. That's wrong. `openapi-changes` correctly classifies those as additions, not breaking changes.
1 parent 8865a94 commit afd7a73

File tree

7 files changed

+85
-97
lines changed

7 files changed

+85
-97
lines changed

.github/workflows/ci.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,23 @@ jobs:
4040
verbose: true
4141
files: lcov.info
4242

43+
check-breaking-changes:
44+
name: Check for breaking API changes
45+
runs-on: ubuntu-latest-8-cores
46+
steps:
47+
- uses: actions/checkout@v4
48+
- uses: taiki-e/install-action@just
49+
- name: Install Rust
50+
uses: dtolnay/rust-toolchain@stable
51+
- uses: taiki-e/install-action@nextest
52+
- name: Setup node
53+
uses: actions/setup-node@v5
54+
- name: Install openapi-changes
55+
run: npm i -g @pb33f/openapi-changes
56+
- uses: Swatinem/[email protected]
57+
- name: Run just breaking-api-changes
58+
run: just breaking-api-changes
59+
4360
check-lint:
4461
name: Check lints
4562
runs-on: ubuntu-latest-8-cores

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@
44
.idea/
55
flamegraph.svg
66
perf.data
7+
**/.DS_Store
8+
modeling-cmds/openapi/old_api.json

.helix/languages.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[language-server.rust-analyzer.config]
2+
cargo.features = "all"

Cargo.lock

Lines changed: 46 additions & 96 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

justfile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ test:
1818

1919
# Regenerate OpenAPI spec
2020
redo-openapi:
21-
EXPECTORATE=overwrite cargo nextest run --all-features -- test_openapi
21+
EXPECTORATE=overwrite cargo nextest run --all-features --nocapture -E "test(test_openapi)"
2222

2323
# Run unit tests, output coverage to `lcov.info`.
2424
test-with-coverage:
@@ -71,3 +71,8 @@ finish-release pkg:
7171
git tag kittycad-{{pkg}}-$version -m "kittycad-{{pkg}}-$version"
7272
git push --tags
7373
cargo publish -p kittycad-{{pkg}}
74+
75+
# Other actions: changelog, checks, diff, summary
76+
breaking-api-changes action='summary':
77+
just redo-openapi
78+
openapi-changes {{action}} --no-color -b modeling-cmds/openapi/old_api.json modeling-cmds/openapi/api.json

modeling-cmds/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ dropshot = { version = "0.16.4", default-features = false }
6969
expectorate = "1.1.0"
7070
openapi-lint = { git = "https://github.com/KittyCAD/openapi-lint", branch = "kittycad" }
7171
openapiv3 = "2.2.0"
72+
reqwest = "0.12.23"
7273
tokio = { version = "1.47.1", features = ["macros"] }
7374

7475
[lints]

modeling-cmds/src/tests.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ async fn test_openapi() {
2323
// Check for lint errors.
2424
let errors = openapi_lint::validate(&spec);
2525
assert!(errors.is_empty(), "{}", errors.join("\n\n"));
26+
27+
// Download the old schema, write it to disk.
28+
let schema = download_openapi_schema("main").await;
29+
std::fs::write("openapi/old_api.json", schema).unwrap();
2630
}
2731

2832
fn example_server() -> Result<ApiDescription<()>, String> {
@@ -50,3 +54,10 @@ fn example_server() -> Result<ApiDescription<()>, String> {
5054

5155
Ok(api)
5256
}
57+
58+
async fn download_openapi_schema(branch: &str) -> String {
59+
let file = "openapi/api.json";
60+
let path =
61+
format!("https://raw.githubusercontent.com/KittyCAD/modeling-api/refs/heads/{branch}/modeling-cmds/{file}");
62+
reqwest::get(path).await.unwrap().text().await.unwrap()
63+
}

0 commit comments

Comments
 (0)