diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..9ce7fe2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,26 @@ +--- +name: Bug report +about: Report a reproducible problem in SemaPact +title: "bug: " +labels: bug +assignees: "" +--- + +## What happened? + +## Expected behavior + +## Reproduction + + + +## Environment + +- SemaPact version/commit: +- Python version: +- OS/runtime: +- Relevant integration (if any): + +## Governance impact + + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..60513a0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,23 @@ +--- +name: Feature request +about: Propose a focused SemaPact capability or governance improvement +title: "feat: " +labels: enhancement +assignees: "" +--- + +## Problem + + + +## Proposed behavior + +## Architectural ownership + + + +## Governance / compatibility impact + + + +## Alternatives considered diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..b0f5089 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,13 @@ +version: 2 +updates: + - package-ecosystem: pip + directory: / + schedule: + interval: weekly + open-pull-requests-limit: 5 + + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + open-pull-requests-limit: 5 diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..e201e28 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,18 @@ +## Summary + + + +## Architecture + + + +## Validation + +- [ ] Tests added or updated where behavior changed +- [ ] `uv run pytest` +- [ ] `uvx ruff check . --select E9,F63,F7,F82` +- [ ] `uv build` + +## Governance / compatibility impact + + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 95e5588..a5c498a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,6 +30,9 @@ jobs: - name: Install dependencies run: uv sync --all-extras --group dev --frozen + - name: Run static checks + run: uvx ruff check . --select E9,F63,F7,F82 + - name: Run tests run: uv run pytest diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..0fdadb8 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,29 @@ +name: CodeQL + +on: + pull_request: + branches: [main] + push: + branches: [main] + schedule: + - cron: "17 3 * * 1" + +permissions: + contents: read + security-events: write + +jobs: + analyze: + name: Analyze Python + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: python + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 0000000..720b8cd --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,18 @@ +name: Dependency Review + +on: + pull_request: + branches: [main] + +permissions: + contents: read + +jobs: + dependency-review: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Review dependency changes + uses: actions/dependency-review-action@v4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7b286d6..e11e43d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,9 +1,7 @@ name: Release on: - push: - branches: - - main + workflow_dispatch: permissions: contents: write # Crucial for pushing commits, tags, and creating releases diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..4f66862 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,43 @@ +# Contributing to SemaPact + +Thanks for contributing to SemaPact. + +## Development setup + +SemaPact uses Python 3.11+ and `uv`. + +```bash +uv sync --all-extras --group dev +uv run pytest +uvx ruff check . --select E9,F63,F7,F82 +uv build +``` + +## Architecture boundaries + +SemaPact is a change-driven governance system, not a CRUD layer. Keep responsibilities separated: + +- importers translate external metadata into canonical contract inputs; they must not own lifecycle or CI/CD policy +- lifecycle and governance code owns deterministic change analysis, policy evaluation, version classification, and governed decisions +- callers must consume the canonical governance decision instead of independently re-interpreting validation, breaking changes, or policy +- runtime integrations should provide observed state without redefining governance semantics +- side-effecting operations must respect the centralized governance gate + +When changing governance behavior, prefer one canonical calculation that downstream components consume over duplicated derivations. + +## Pull requests + +Keep changes small and explicit. A pull request should explain: + +- what behavior changes +- why the change belongs in that architectural layer +- what tests cover the behavior +- whether the change affects compatibility, lifecycle policy, or release behavior + +Use Conventional Commit-style titles where practical, for example `feat:`, `fix:`, `docs:`, `ci:`, or `refactor:`. Release versioning is intentionally triggered manually by maintainers. + +## Testing + +Add or update tests for behavior changes. Governance and lifecycle changes should test both allowed and prohibited paths where relevant. + +Do not weaken deterministic checks solely to make a test pass; fix the model, policy, or fixture that is actually incorrect. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..975efcb --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,15 @@ +# Security Policy + +## Reporting a vulnerability + +Please do not open a public GitHub issue for a suspected security vulnerability. + +Use GitHub's private vulnerability reporting for this repository when available. Include enough detail to reproduce and assess the issue, including affected versions, impact, and a minimal proof of concept when appropriate. + +Maintainers will triage reports, coordinate remediation, and publish an advisory when disclosure is warranted. + +## Scope + +Security reports may include vulnerabilities affecting SemaPact's CLI, importers, governance and lifecycle logic, CI/CD integration, credential handling, runtime platform integrations, or dependency supply chain. + +General bugs, feature requests, and governance-policy disagreements should use normal GitHub issues instead. diff --git a/pyproject.toml b/pyproject.toml index 7c16cc8..da2f65b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,9 +5,30 @@ build-backend = "setuptools.build_meta" [project] name = "semapact" version = "0.8.1" -description = "SemaPact importers for generating ODCS contracts from Delta, SQL folders, and Unity Catalog" +description = "Lifecycle governance for data contracts and enterprise semantics" readme = "README.md" requires-python = ">=3.11,<3.15" +license = { file = "LICENSE" } +authors = [ + { name = "Elliot Sun" }, +] +keywords = [ + "data-contracts", + "data-governance", + "odcs", + "gitops", + "databricks", +] +classifiers = [ + "Development Status :: 4 - Beta", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", + "Topic :: Software Development :: Libraries :: Python Modules", +] dependencies = [ "pydantic>=2.8.0", "PyYAML>=6.0.0", @@ -15,6 +36,12 @@ dependencies = [ "datacontract-cli>=0.12.0", ] +[project.urls] +Homepage = "https://github.com/DaorynAI/semapact" +Repository = "https://github.com/DaorynAI/semapact" +Issues = "https://github.com/DaorynAI/semapact/issues" +Changelog = "https://github.com/DaorynAI/semapact/blob/main/CHANGELOG.md" + [project.scripts] semapact = "semapact.interfaces.cli:main" contracthub = "semapact.interfaces.cli:main"