diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 67b22f4..2e761bf 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1,27 @@ -* @Coding-Dev-Tools +# CODEOWNERS +# +# These users/groups will be requested for review when someone opens a PR +# touching the matching files. See https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners +# +# Global defaults +* @Coding-Dev-Tools/engineers + +# Core source files +/src/ @Coding-Dev-Tools/engineers + +# Tests +/tests/ @Coding-Dev-Tools/engineers + +# CI/CD workflows +/.github/workflows/ @Coding-Dev-Tools/engineers + +# Documentation +README.md @Coding-Dev-Tools/engineers +CHANGELOG.md @Coding-Dev-Tools/engineers +CONTRIBUTING.md @Coding-Dev-Tools/engineers +CODE_OF_CONDUCT.md @Coding-Dev-Tools/engineers +SECURITY.md @Coding-Dev-Tools/engineers + +# Configuration +/pyproject.toml @Coding-Dev-Tools/engineers +/LICENSE @Coding-Dev-Tools/engineers \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml index c4f654d..cafadda 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,22 +1,64 @@ +# Dependabot configuration for automated dependency updates +# See https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + version: 2 updates: - - package-ecosystem: pip - directory: / + # Python dependencies (pip) + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + time: "09:00" + timezone: "UTC" + open-pull-requests-limit: 5 + labels: + - "dependencies" + - "python" + commit-message: + prefix: "deps(pip)" + include: "scope" + reviewers: + - "Coding-Dev-Tools/engineers" + assignees: + - "Coding-Dev-Tools/engineers" + + # GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" schedule: - interval: weekly - day: monday + interval: "weekly" + day: "monday" + time: "09:00" + timezone: "UTC" open-pull-requests-limit: 5 labels: - - dependencies - - automated + - "dependencies" + - "github-actions" + commit-message: + prefix: "deps(actions)" + include: "scope" + reviewers: + - "Coding-Dev-Tools/engineers" + assignees: + - "Coding-Dev-Tools/engineers" - - package-ecosystem: github-actions - directory: / + # npm (for package.json if present) + - package-ecosystem: "npm" + directory: "/" schedule: - interval: weekly - day: monday + interval: "weekly" + day: "monday" + time: "09:00" + timezone: "UTC" open-pull-requests-limit: 5 labels: - - dependencies - - ci - - automated + - "dependencies" + - "npm" + commit-message: + prefix: "deps(npm)" + include: "scope" + reviewers: + - "Coding-Dev-Tools/engineers" + assignees: + - "Coding-Dev-Tools/engineers" \ No newline at end of file diff --git a/.gitignore b/.gitignore index af75381..2d2c765 100644 --- a/.gitignore +++ b/.gitignore @@ -73,11 +73,8 @@ research/ fixtures/generated/ .ruff_cache/ -<<<<<<< Updated upstream # Local opencode config .agents/ -======= # Added by release-prep node_modules ->>>>>>> Stashed changes diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..699b1e8 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,126 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for +moderation decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies +when an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +conduct@coding-dev-tools.com. All complaints will be reviewed and investigated +promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interactions with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interactions +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][mozilla-coc-enforcement]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[mozilla-coc-enforcement]: https://github.com/mozilla/diversity \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index c18fa25..2750f1b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,72 +1,72 @@ -[build-system] -requires = ["setuptools>=68.0", "wheel"] -build-backend = "setuptools.build_meta" - -[project] -name = "api-contract-guardian" -version = "0.1.0" -description = "CLI tool that monitors OpenAPI schema diffs, detects breaking changes, generates migration guides, and gates CI pipelines on contract violations" -readme = "README.md" -requires-python = ">=3.10" -license = "MIT" -authors = [{name = "DevForge"}] -keywords = ["openapi", "api", "contract", "breaking-changes", "ci", "diff"] -classifiers = [ - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "Topic :: Software Development :: Testing", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", -] -dependencies = [ - "typer>=0.26.0", - "rich>=15.0.0", - "pyyaml>=6.0", - "jsonschema>=4.17.0", - "deepdiff>=9.0.0", -] - -[project.urls] -Homepage = "https://github.com/Coding-Dev-Tools/api-contract-guardian" -Documentation = "https://github.com/Coding-Dev-Tools/api-contract-guardian#readme" -Repository = "https://github.com/Coding-Dev-Tools/api-contract-guardian" -Issues = "https://github.com/Coding-Dev-Tools/api-contract-guardian/issues" -Changelog = "https://github.com/Coding-Dev-Tools/api-contract-guardian/releases" - -[project.optional-dependencies] -dev = [ - "pytest>=9.0.0", - "pytest-cov>=7.0.0", - "ruff>=0.15.0", -] -license = ["revenueholdings-license>=0.1.0"] - -[project.scripts] -api-contract-guardian = "api_contract_guardian.cli:app" - -[tool.setuptools] -include-package-data = true - -[tool.setuptools.packages.find] -where = ["src"] - -[tool.setuptools.package-data] -api_contract_guardian = ["py.typed"] - -[tool.pytest.ini_options] -testpaths = ["tests"] -addopts = "-v --tb=short" - -[tool.ruff] -target-version = "py310" -line-length = 120 - -[tool.ruff.lint] -select = ["E", "F", "W", "I", "UP", "B", "SIM"] -ignore = ["E501"] - -[tool.ruff.lint.isort] -known-first-party = ["api_contract_guardian"] +[build-system] +requires = ["setuptools>=68.0", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "api-contract-guardian" +version = "0.1.0" +description = "CLI tool that monitors OpenAPI schema diffs, detects breaking changes, generates migration guides, and gates CI pipelines on contract violations" +readme = "README.md" +requires-python = ">=3.10" +license = "MIT" +authors = [{name = "DevForge"}] +keywords = ["openapi", "api", "contract", "breaking-changes", "ci", "diff"] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "Topic :: Software Development :: Testing", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", +] +dependencies = [ + "typer>=0.26.0", + "rich>=15.0.0", + "pyyaml>=6.0", + "jsonschema>=4.17.0", + "deepdiff>=9.0.0", +] + +[project.urls] +Homepage = "https://github.com/Coding-Dev-Tools/api-contract-guardian" +Documentation = "https://github.com/Coding-Dev-Tools/api-contract-guardian#readme" +Repository = "https://github.com/Coding-Dev-Tools/api-contract-guardian" +Issues = "https://github.com/Coding-Dev-Tools/api-contract-guardian/issues" +Changelog = "https://github.com/Coding-Dev-Tools/api-contract-guardian/releases" + +[project.optional-dependencies] +dev = [ + "pytest>=9.0.0", + "pytest-cov>=7.0.0", + "ruff>=0.15.0", +] +license = ["revenueholdings-license>=0.1.0"] + +[project.scripts] +api-contract-guardian = "api_contract_guardian.cli:app" + +[tool.setuptools] +include-package-data = true + +[tool.setuptools.packages.find] +where = ["src"] + +[tool.setuptools.package-data] +api_contract_guardian = ["py.typed"] + +[tool.pytest.ini_options] +testpaths = ["tests"] +addopts = "-v --tb=short" + +[tool.ruff] +target-version = "py310" +line-length = 120 + +[tool.ruff.lint] +select = ["E", "F", "W", "I", "UP", "B", "SIM"] +ignore = ["E501"] + +[tool.ruff.lint.isort] +known-first-party = ["api_contract_guardian"] diff --git a/tests/fixtures/spec-v1.yaml b/tests/fixtures/spec-v1.yaml new file mode 100644 index 0000000..419d497 --- /dev/null +++ b/tests/fixtures/spec-v1.yaml @@ -0,0 +1,50 @@ +openapi: "3.0.3" +info: + title: Sample API + version: "1.0.0" +paths: + /users: + get: + summary: List users + operationId: listUsers + responses: + '200': + description: A list of users + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/User' + /users/{id}: + get: + summary: Get user by ID + operationId: getUser + parameters: + - name: id + in: path + required: true + schema: + type: string + responses: + '200': + description: A user + content: + application/json: + schema: + $ref: '#/components/schemas/User' + '404': + description: User not found +components: + schemas: + User: + type: object + properties: + id: + type: string + name: + type: string + email: + type: string + format: email + required: [id, name] diff --git a/tests/fixtures/spec-v2.yaml b/tests/fixtures/spec-v2.yaml new file mode 100644 index 0000000..4906c4e --- /dev/null +++ b/tests/fixtures/spec-v2.yaml @@ -0,0 +1,90 @@ +openapi: "3.0.3" +info: + title: Sample API + version: "2.0.0" +paths: + /users: + get: + summary: List users + operationId: listUsers + responses: + '200': + description: A list of users + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/User' + post: + summary: Create user + operationId: createUser + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UserCreate' + responses: + '201': + description: User created + content: + application/json: + schema: + $ref: '#/components/schemas/User' + /users/{id}: + get: + summary: Get user by ID + operationId: getUser + parameters: + - name: id + in: path + required: true + schema: + type: string + responses: + '200': + description: A user + content: + application/json: + schema: + $ref: '#/components/schemas/User' + '404': + description: User not found + delete: + summary: Delete user + operationId: deleteUser + parameters: + - name: id + in: path + required: true + schema: + type: string + responses: + '204': + description: User deleted +components: + schemas: + User: + type: object + properties: + id: + type: string + name: + type: string + email: + type: string + format: email + created_at: + type: string + format: date-time + required: [id, name, email] + UserCreate: + type: object + properties: + name: + type: string + email: + type: string + format: email + required: [name, email]