{"id":50532010,"url":"https://github.com/pyjeebz/breakwatch","last_synced_at":"2026-06-03T14:31:00.567Z","repository":{"id":355868585,"uuid":"1228494790","full_name":"pyjeebz/breakwatch","owner":"pyjeebz","description":"Breakwatch- OpenAPI Breaking Change Detector","archived":false,"fork":false,"pushed_at":"2026-05-10T14:50:21.000Z","size":2674,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"start","last_synced_at":"2026-05-12T18:47:51.105Z","etag":null,"topics":["api","breaking-changes","ci","developer-tools","devops-tools","github-actions","microservices","open-api"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pyjeebz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-04T04:33:42.000Z","updated_at":"2026-05-10T14:35:33.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pyjeebz/breakwatch","commit_stats":null,"previous_names":["pyjeebz/pactwatch","pyjeebz/breakwatch"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/pyjeebz/breakwatch","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyjeebz%2Fbreakwatch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyjeebz%2Fbreakwatch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyjeebz%2Fbreakwatch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyjeebz%2Fbreakwatch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pyjeebz","download_url":"https://codeload.github.com/pyjeebz/breakwatch/tar.gz/refs/heads/start","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyjeebz%2Fbreakwatch/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33870025,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-03T02:00:06.370Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","breaking-changes","ci","developer-tools","devops-tools","github-actions","microservices","open-api"],"created_at":"2026-06-03T14:30:59.050Z","updated_at":"2026-06-03T14:31:00.560Z","avatar_url":"https://github.com/pyjeebz.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Breakwatch\n\u003e Your microservices have a contract. Breakwatch enforces it before merge.\n\nAn OpenAPI breaking-change detector that knows which downstream consumers will actually break. Most API diff tools tell you *what* changed. Breakwatch tells you *who cares*.\n\n## Demo\n\n![Breakwatch demo](demo.gif)\n\n\u003csub\u003eAlso available as [MP4](demo.mp4) for sharing.\u003c/sub\u003e\n\n## The Problem\n\nTeam A changes their API. Team B's mobile app breaks in production. The spec diff showed \"field removed\" — but nobody connected it to Team B.\n\nBreakwatch maintains a service-to-consumer graph (`breakwatch.yaml`). When a producer's spec changes, it classifies each change as **BREAKING**, **RISKY**, or **SAFE**, then filters the results per consumer. Same spec change, different verdict per team.\n\n## How It Works\n\n```\n1. Diff    — structurally compare two OpenAPI 3.x specs\n2. Classify — label each change: BREAKING / RISKY / SAFE\n3. Filter  — check the consumer graph: who uses the affected endpoints?\n```\n\n## Installation\n\n```bash\npip install breakwatch\n```\n\n## Quick Start\n\n### Raw diff\n\nCompare two specs and get classified changes:\n\n```bash\n# Rich terminal output\nbreakwatch diff old-spec.yaml new-spec.yaml\n\n# JSON for CI\nbreakwatch diff old-spec.yaml new-spec.yaml --format json\n```\n\n### Per-consumer impact\n\nDefine your service topology in `breakwatch.yaml`:\n\n```yaml\nversion: 1\nproducers:\n  api:\n    spec: ./services/api/openapi.yaml\n\nconsumers:\n  mobile-app:\n    consumes:\n      - producer: api\n        endpoints:\n          - GET /users/{id}\n          - POST /orders\n  web-dashboard:\n    consumes:\n      - producer: api\n        endpoints:\n          - GET /users/{id}\n          - GET /admin/*\n```\n\nThen check per-consumer impact:\n\n```bash\n# Check all consumers\nbreakwatch check -c breakwatch.yaml -p api --old old.yaml --new new.yaml\n\n# Check a single consumer\nbreakwatch check -c breakwatch.yaml -p api --old old.yaml --new new.yaml --consumer mobile-app\n\n# JSON for CI\nbreakwatch check -c breakwatch.yaml -p api --old old.yaml --new new.yaml -f json\n```\n\n### GitHub Action\n\nAdd to your workflow:\n\n```yaml\nname: API Contract Check\non: pull_request\n\njobs:\n  breakwatch:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          fetch-depth: 0\n\n      - uses: pyjeebz/breakwatch@v0.1.0\n        with:\n          config: breakwatch.yaml\n          producer: api\n          old-spec: services/api/openapi.yaml  # from base branch\n          new-spec: services/api/openapi.yaml  # from PR branch\n          github-token: ${{ secrets.GITHUB_TOKEN }}\n```\n\nBreakwatch will:\n- Post a PR comment showing per-consumer impact\n- Set a commit status check (pass/fail)\n- Exit with code 1 if breaking changes affect any consumer\n\n## Classification Rules\n\n### Breaking\n| Change | Why |\n|--------|-----|\n| Endpoint removed | Consumers calling it will get 404s |\n| Required response field removed | Consumers parsing it will crash |\n| Response field type changed | Consumers deserializing it will get wrong types |\n| New required request field | Existing client code won't send it |\n| Status code removed | Consumers handling it will get unexpected responses |\n| Auth scheme changed | Existing tokens/keys will stop working |\n\n### Risky\n| Change | Why |\n|--------|-----|\n| Optional field made required | Consumers not sending it may start failing |\n| Field made nullable | Consumers not handling null may crash |\n| Enum value removed | Consumers matching on it will miss cases |\n\n### Safe\n| Change | Why |\n|--------|-----|\n| New endpoint | Existing consumers unaffected |\n| New optional request field | Old clients just don't send it |\n| New response field | Old clients ignore extra fields |\n| New enum value | Old clients still see their known values |\n| Documentation changes | No runtime impact |\n\n## CLI Reference\n\n### `breakwatch diff`\n\n```\nbreakwatch diff OLD NEW [--format text|json]\n```\n\nCompare two OpenAPI specs. Exits with code 1 if BREAKING changes found.\n\n### `breakwatch check`\n\n```\nbreakwatch check --config PATH --producer NAME --old PATH --new PATH\n                [--consumer NAME] [--format text|json]\n```\n\nCheck per-consumer impact using the consumer graph. Exits with code 1 if any consumer has BREAKING changes.\n\n## Exit Codes\n\n| Code | Meaning |\n|------|---------|\n| 0 | No breaking changes |\n| 1 | Breaking changes detected |\n| 2 | Input error (bad spec, bad config, unknown producer) |\n\n\nSee the [demo monorepo](examples/demo-monorepo/) for a working example with 3 services.\n\n```bash\n# Run the demo\nbreakwatch check \\\n  -c examples/demo-monorepo/breakwatch.yaml \\\n  -p user-api \\\n  --old examples/demo-monorepo/services/producer-api/openapi.yaml \\\n  --new examples/demo-monorepo/services/producer-api/openapi-breaking.yaml\n```\n\n## License\n\nApache 2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpyjeebz%2Fbreakwatch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpyjeebz%2Fbreakwatch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpyjeebz%2Fbreakwatch/lists"}