Added a breaking interface test#258
Conversation
| - name: Diff TypeScript public API vs baseline | ||
| if: env.SKIP != 'true' | ||
| working-directory: packages/cre-sdk | ||
| run: | | ||
| cat dist/index.d.ts dist/pb.d.ts \ | ||
| dist/sdk/index.d.ts dist/sdk/runtime.d.ts \ | ||
| dist/sdk/workflow.d.ts dist/sdk/errors.d.ts \ | ||
| dist/sdk/report.d.ts > /tmp/api-current.d.ts | ||
|
|
||
| if ! diff api-baseline.d.ts /tmp/api-current.d.ts; then | ||
| echo "::error::TypeScript public API surface changed. Run 'bun run update-api-baseline' locally and commit the updated api-baseline.d.ts." | ||
| exit 1 | ||
| fi |
There was a problem hiding this comment.
What I'm thinking is that we are exposing these in package.json:
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
},
"./restricted-apis": {
"types": "./dist/sdk/types/restricted-apis.d.ts",
"import": "./dist/sdk/types/restricted-apis.js"
},
"./pb": {
"types": "./dist/pb.d.ts",
"import": "./dist/pb.js"
},
"./test": {
"types": "./dist/sdk/test/index.d.ts",
"import": "./dist/sdk/test/index.js"
}
},
So basically ./test and /restricted-apis are missing in the concat. Not 100% sure if restricted apis would make sense here but probably we should be warned if we change test public APIs. Note: test in this case is a package for customers to write their own tests, not our internal unit tests.
| bun generate:sdk # Generate all SDK types and code | ||
| ``` | ||
|
|
||
| ### Breaking Changes |
There was a problem hiding this comment.
Thanks for the readme section 🙌
| "test:standard": "./scripts/run-standard-tests.sh", | ||
| "typecheck": "tsc -p tsconfig.json --noEmit" | ||
| "typecheck": "tsc -p tsconfig.json --noEmit", | ||
| "update-api-baseline": "bun run compile:build && cat dist/index.d.ts dist/pb.d.ts dist/sdk/index.d.ts dist/sdk/runtime.d.ts dist/sdk/workflow.d.ts dist/sdk/errors.d.ts dist/sdk/report.d.ts > api-baseline.d.ts" |
There was a problem hiding this comment.
Could make sense to create another small .sh script inside ./scripts and share exactly the same files between update-api-baseline and breaking-changes.yml workflow. In current shape it's easy to modify only in one place and get missmatches.
| - name: Diff Rust host imports vs baseline | ||
| if: env.SKIP != 'true' | ||
| run: | | ||
| sed -n '/unsafe extern "C"/,/^}/p' \ | ||
| packages/cre-sdk-javy-plugin/src/javy_chainlink_sdk/src/lib.rs \ | ||
| > /tmp/current-imports.txt | ||
|
|
||
| if ! diff packages/cre-sdk-javy-plugin/src/javy_chainlink_sdk/host-imports-baseline.txt \ | ||
| /tmp/current-imports.txt; then | ||
| echo "::error::Rust host import signatures changed. Update host-imports-baseline.txt if intentional." | ||
| exit 1 | ||
| fi |
There was a problem hiding this comment.
This is comment from my AI Agent (as my Rust sidekick):
Rust extern extraction fragile.
sed -n '/unsafe extern "C"/,/^}/p (breaking-changes.yml:144-146) match first ^} at column 0. Works today (only one extern block at lib.rs:23-54). Break silently if:
- Someone add 2nd extern block — only first captured.
- Closing } indented (rustfmt config change, cfg-gated block) — sed run past it to next col-0 }, capture wrong content.
- Attribute macro (#[link]) inserted before unsafe extern "C" — still ok actually.
Fix: use syn parse, or at minimum grep all extern "C" blocks. Cheaper alt: extract each fn <name>(...) line individually instead of block-range.
|
|
||
| permissions: | ||
| contents: read | ||
|
|
There was a problem hiding this comment.
Feels like we could add concurrency here and only care about the last runs, right? So something like:
concurrency:
group: breaking-changes-${{ github.event.pull_request.number }}
cancel-in-progress: true
Summary
Adds a dedicated breaking-changes GitHub Actions workflow that runs on pull requests to main and guards the three public contracts in this SDK: protobuf definitions, TypeScript API surface, and WASM host bindings (JS + Rust).
Each contract is checked in a parallel job with a committed baseline (or buf’s built-in rules for protos), so accidental breaking changes fail CI unless the author updates the baseline alongside the code change.