From 59de2795991452bca304796b1afa736526310882 Mon Sep 17 00:00:00 2001 From: Deborah Jacob Date: Thu, 5 Feb 2026 12:48:24 -0500 Subject: [PATCH 1/2] build: add pyproject.toml with hatch-vcs and CI/CD workflows Add pyproject.toml with opentelemetry-api as sole core dependency, optional extras (sdk, instruments, carriers), and hatch-vcs for git-tag-based versioning targeting Python 3.9+. Add GitHub Actions workflows: - ci.yml: lint, typecheck, test matrix (3.9-3.13), build, DCO check - release.yml: PyPI trusted publishing via OIDC on tag push - codeql.yml: weekly CodeQL security analysis - scorecard.yml: OpenSSF Scorecard compliance - repolinter.yml: LF AI & Data repo structure validation Signed-off-by: deborahjacob-botanu Co-Authored-By: Claude Opus 4.5 --- .github/workflows/ci.yml | 104 +++++++++++++++++ .github/workflows/codeql.yml | 40 +++++++ .github/workflows/release.yml | 80 +++++++++++++ .github/workflows/repolinter.yml | 24 ++++ .github/workflows/scorecard.yml | 35 ++++++ pyproject.toml | 190 +++++++++++++++++++++++++++++++ 6 files changed, 473 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/codeql.yml create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/repolinter.yml create mode 100644 .github/workflows/scorecard.yml create mode 100644 pyproject.toml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..757042e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,104 @@ +# SPDX-FileCopyrightText: 2026 The Botanu Authors +# SPDX-License-Identifier: Apache-2.0 + +name: CI + +on: + push: + branches: [main, developer-deborah] + pull_request: + branches: [main] + +permissions: + contents: read + +jobs: + # ------------------------------------------------------------------- + # Lint & format check + # ------------------------------------------------------------------- + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - run: pip install ruff + - run: ruff check src/ tests/ + - run: ruff format --check src/ tests/ + + # ------------------------------------------------------------------- + # Type checking + # ------------------------------------------------------------------- + typecheck: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - run: pip install -e ".[dev]" + - run: mypy src/botanu/ + + # ------------------------------------------------------------------- + # Test matrix — Python 3.9 → 3.13 + # ------------------------------------------------------------------- + test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # hatch-vcs needs full history + + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: pip install -e ".[dev]" + + - name: Run tests with coverage + run: pytest --cov=botanu --cov-report=xml --cov-report=term-missing + + - name: Upload coverage + if: matrix.python-version == '3.12' + uses: codecov/codecov-action@v4 + with: + file: coverage.xml + fail_ci_if_error: false + + # ------------------------------------------------------------------- + # Build verification — ensure the package builds cleanly + # ------------------------------------------------------------------- + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - run: pip install build + - run: python -m build + - uses: actions/upload-artifact@v4 + with: + name: dist + path: dist/ + + # ------------------------------------------------------------------- + # DCO sign-off check (required by Linux Foundation) + # ------------------------------------------------------------------- + dco: + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: DCO check + uses: dcoapp/app@v1 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..b0d5105 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,40 @@ +# SPDX-FileCopyrightText: 2026 The Botanu Authors +# SPDX-License-Identifier: Apache-2.0 + +name: CodeQL + +on: + push: + branches: [main] + pull_request: + branches: [main] + schedule: + - cron: "23 4 * * 1" # Weekly Monday 04:23 UTC + +permissions: + contents: read + +jobs: + analyze: + runs-on: ubuntu-latest + permissions: + security-events: write + strategy: + fail-fast: false + matrix: + language: [python] + steps: + - uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + + - name: Autobuild + uses: github/codeql-action/autobuild@v3 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{ matrix.language }}" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..ba7bf80 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,80 @@ +# SPDX-FileCopyrightText: 2026 The Botanu Authors +# SPDX-License-Identifier: Apache-2.0 + +name: Release to PyPI + +on: + push: + tags: + - "v*" + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # hatch-vcs needs full history + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install build tools + run: pip install build + + - name: Build sdist and wheel + run: python -m build + + - uses: actions/upload-artifact@v4 + with: + name: dist + path: dist/ + + # ------------------------------------------------------------------- + # Publish to PyPI via Trusted Publishing (OIDC — no API tokens) + # Requires PyPI project to be configured for GitHub OIDC: + # https://docs.pypi.org/trusted-publishers/ + # ------------------------------------------------------------------- + publish-pypi: + needs: build + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/botanu + permissions: + id-token: write # required for OIDC trusted publishing + steps: + - uses: actions/download-artifact@v4 + with: + name: dist + path: dist/ + + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + + # ------------------------------------------------------------------- + # Create GitHub Release with auto-generated notes + # ------------------------------------------------------------------- + github-release: + needs: publish-pypi + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: actions/download-artifact@v4 + with: + name: dist + path: dist/ + + - name: Create GitHub Release + env: + GH_TOKEN: ${{ github.token }} + run: gh release create "${{ github.ref_name }}" dist/* --generate-notes diff --git a/.github/workflows/repolinter.yml b/.github/workflows/repolinter.yml new file mode 100644 index 0000000..1c07d88 --- /dev/null +++ b/.github/workflows/repolinter.yml @@ -0,0 +1,24 @@ +# SPDX-FileCopyrightText: 2026 The Botanu Authors +# SPDX-License-Identifier: Apache-2.0 + +name: Repolinter + +on: + push: + branches: [main] + pull_request: + branches: [main] + +permissions: + contents: read + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Run Repolinter + uses: todogroup/repolinter-action@v1 + with: + config_url: https://raw.githubusercontent.com/lfai/foundation/main/repolinter.json diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml new file mode 100644 index 0000000..2e56bfc --- /dev/null +++ b/.github/workflows/scorecard.yml @@ -0,0 +1,35 @@ +# SPDX-FileCopyrightText: 2026 The Botanu Authors +# SPDX-License-Identifier: Apache-2.0 + +name: OpenSSF Scorecard + +on: + push: + branches: [main] + schedule: + - cron: "30 1 * * 1" # Weekly Monday 01:30 UTC + +permissions: read-all + +jobs: + analysis: + runs-on: ubuntu-latest + permissions: + security-events: write # upload SARIF + id-token: write # publish results + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Run OpenSSF Scorecard + uses: ossf/scorecard-action@v2 + with: + results_file: results.sarif + results_format: sarif + publish_results: true + + - name: Upload SARIF to GitHub Security tab + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: results.sarif diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..c14bd48 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,190 @@ +# SPDX-FileCopyrightText: 2026 The Botanu Authors +# SPDX-License-Identifier: Apache-2.0 + +[build-system] +requires = ["hatchling", "hatch-vcs"] +build-backend = "hatchling.build" + +# --------------------------------------------------------------------------- +# Project metadata (PEP 621) +# --------------------------------------------------------------------------- +[project] +name = "botanu" +dynamic = ["version"] +description = "OpenTelemetry-native run-level cost attribution for AI workflows" +readme = "README.md" +license = "Apache-2.0" +requires-python = ">=3.9" +authors = [ + { name = "The Botanu Authors", email = "oss@botanu.ai" }, +] +keywords = [ + "opentelemetry", + "tracing", + "observability", + "ai", + "llm", + "cost-attribution", + "mlops", +] +classifiers = [ + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: System :: Monitoring", + "Typing :: Typed", +] + +# Core dependency — opentelemetry-api only (~50 KB, zero transitive deps). +# Everything else is behind optional extras so adopters never pay for what +# they don't use. +dependencies = [ + "opentelemetry-api >= 1.20.0", +] + +[project.urls] +Homepage = "https://github.com/botanu-ai/botanu-sdk-python" +Documentation = "https://docs.botanu.ai" +Repository = "https://github.com/botanu-ai/botanu-sdk-python" +Changelog = "https://github.com/botanu-ai/botanu-sdk-python/blob/main/CHANGELOG.md" +Issues = "https://github.com/botanu-ai/botanu-sdk-python/issues" + +# --------------------------------------------------------------------------- +# Optional extras +# --------------------------------------------------------------------------- +[project.optional-dependencies] +# Full OTel SDK + OTLP exporter — needed only when running standalone +# (no pre-existing TracerProvider from Datadog / Splunk / etc.) +sdk = [ + "opentelemetry-sdk >= 1.20.0", + "opentelemetry-exporter-otlp-proto-http >= 1.20.0", +] + +# Auto-instrumentation libraries for common frameworks +instruments = [ + "opentelemetry-instrumentation >= 0.41b0", + "opentelemetry-instrumentation-fastapi >= 0.41b0", + "opentelemetry-instrumentation-requests >= 0.41b0", + "opentelemetry-instrumentation-flask >= 0.41b0", + "opentelemetry-instrumentation-urllib3 >= 0.41b0", +] + +# Cross-service carrier propagation (SQS, Kafka, Celery, Redis) +carriers = [ + "celery >= 5.0.0", + "aiokafka >= 0.8.0", +] + +# Everything +all = [ + "botanu[sdk,instruments,carriers]", +] + +# Development / CI +dev = [ + "botanu[all]", + "pytest >= 7.4.0", + "pytest-asyncio >= 0.21.0", + "pytest-cov >= 4.1.0", + "coverage[toml] >= 7.0", + "httpx >= 0.24.0", + "ruff >= 0.4.0", + "mypy >= 1.7.0", + "pre-commit >= 3.5.0", +] + +# --------------------------------------------------------------------------- +# Hatch — build targets & versioning +# --------------------------------------------------------------------------- +[tool.hatch.version] +source = "vcs" + +[tool.hatch.version.raw-options] +version_scheme = "guess-next-dev" +local_scheme = "no-local-version" + +[tool.hatch.build.targets.sdist] +include = ["src/botanu/**", "LICENSE", "NOTICE", "README.md"] + +[tool.hatch.build.targets.wheel] +packages = ["src/botanu"] + +# --------------------------------------------------------------------------- +# Ruff (linter + formatter) +# --------------------------------------------------------------------------- +[tool.ruff] +line-length = 120 +target-version = "py39" +src = ["src"] + +[tool.ruff.lint] +select = [ + "E", # pycodestyle errors + "W", # pycodestyle warnings + "F", # pyflakes + "I", # isort + "B", # flake8-bugbear + "UP", # pyupgrade + "S", # flake8-bandit (security) + "RUF", # ruff-specific +] +ignore = [ + "E501", # line too long — handled by formatter + "S101", # assert in tests is fine + "UP007", # X | Y syntax — keep Optional[] for 3.9 compat +] + +[tool.ruff.lint.per-file-ignores] +"tests/**" = ["S101", "S106"] + +[tool.ruff.format] +quote-style = "double" +indent-style = "space" +line-ending = "auto" + +# --------------------------------------------------------------------------- +# mypy +# --------------------------------------------------------------------------- +[tool.mypy] +python_version = "3.9" +warn_return_any = true +warn_unused_configs = true +ignore_missing_imports = true +strict = false + +# --------------------------------------------------------------------------- +# pytest +# --------------------------------------------------------------------------- +[tool.pytest.ini_options] +asyncio_mode = "auto" +testpaths = ["tests"] +addopts = [ + "--strict-markers", + "--tb=short", +] +markers = [ + "integration: marks tests that require external services", +] + +# --------------------------------------------------------------------------- +# coverage +# --------------------------------------------------------------------------- +[tool.coverage.run] +source = ["botanu"] +branch = true + +[tool.coverage.report] +show_missing = true +fail_under = 80 +exclude_lines = [ + "pragma: no cover", + "if TYPE_CHECKING:", + "if __name__ == .__main__.", +] From 334e2f71b42e46ce40c3605ee1d570c35c831cc1 Mon Sep 17 00:00:00 2001 From: Deborah Jacob Date: Thu, 5 Feb 2026 12:56:00 -0500 Subject: [PATCH 2/2] chore: add pre-commit, repolinter, clomonitor configs and GitHub templates Add developer tooling and LF compliance configs: - .pre-commit-config.yaml (ruff, mypy, SPDX/REUSE, DCO check) - .repolinterrc.yml (LF AI repo structure rules) - .clomonitor.yml (LF project maturity metadata) - GitHub issue templates (bug report, feature request) - Pull request template with DCO/SPDX checklist Note: CI is expected to fail until SDK source code and tests are added in the next commit (empty src/ and tests/ directories). Signed-off-by: deborahjacob-botanu Co-Authored-By: Claude Opus 4.5 --- .clomonitor.yml | 27 +++++ .github/ISSUE_TEMPLATE/bug_report.yml | 88 +++++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 11 ++ .github/ISSUE_TEMPLATE/feature_request.yml | 53 +++++++++ .github/PULL_REQUEST_TEMPLATE.md | 38 +++++++ .pre-commit-config.yaml | 46 ++++++++ .repolinterrc.yml | 124 +++++++++++++++++++++ 7 files changed, 387 insertions(+) create mode 100644 .clomonitor.yml create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .pre-commit-config.yaml create mode 100644 .repolinterrc.yml diff --git a/.clomonitor.yml b/.clomonitor.yml new file mode 100644 index 0000000..81639fe --- /dev/null +++ b/.clomonitor.yml @@ -0,0 +1,27 @@ +# SPDX-FileCopyrightText: 2026 The Botanu Authors +# SPDX-License-Identifier: Apache-2.0 +# +# CLOMonitor metadata — used by LF AI & Data Foundation to track +# project maturity and best-practice adoption. +# See: https://clomonitor.io/docs/topics/checks/ + +# Documentation +documentation: + adopters: "https://github.com/botanu-ai/botanu-sdk-python/blob/main/ADOPTERS.md" + changelog: "https://github.com/botanu-ai/botanu-sdk-python/blob/main/CHANGELOG.md" + code_of_conduct: "https://github.com/botanu-ai/botanu-sdk-python/blob/main/CODE_OF_CONDUCT.md" + contributing: "https://github.com/botanu-ai/botanu-sdk-python/blob/main/CONTRIBUTING.md" + governance: "https://github.com/botanu-ai/botanu-sdk-python/blob/main/GOVERNANCE.md" + maintainers: "https://github.com/botanu-ai/botanu-sdk-python/blob/main/MAINTAINERS.md" + readme: "https://github.com/botanu-ai/botanu-sdk-python/blob/main/README.md" + security: "https://github.com/botanu-ai/botanu-sdk-python/blob/main/SECURITY.md" + +# License +license: + approved: true + spdx_id: "Apache-2.0" + +# Best practices +best_practices: + dco: true + openssf_badge: false # TODO: apply at https://www.bestpractices.dev/ diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..da664ab --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,88 @@ +# SPDX-FileCopyrightText: 2026 The Botanu Authors +# SPDX-License-Identifier: Apache-2.0 + +name: Bug Report +description: Report a bug in the Botanu SDK +labels: ["bug", "triage"] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to report a bug. + Please fill in the details below to help us reproduce and fix the issue. + + - type: input + id: version + attributes: + label: Botanu SDK version + description: "Output of `python -c 'import botanu; print(botanu.__version__)'`" + placeholder: "0.1.0" + validations: + required: true + + - type: input + id: python-version + attributes: + label: Python version + description: "Output of `python --version`" + placeholder: "3.12.1" + validations: + required: true + + - type: dropdown + id: init-mode + attributes: + label: Initialization mode + options: + - Standalone (no existing TracerProvider) + - Attach (OTEL-native vendor — Splunk, Honeycomb, etc.) + - Alongside (proprietary agent — Datadog, New Relic, etc.) + - Unknown / not sure + validations: + required: true + + - type: textarea + id: description + attributes: + label: Description + description: A clear and concise description of the bug. + validations: + required: true + + - type: textarea + id: reproduce + attributes: + label: Steps to reproduce + description: Minimal code or steps to reproduce the issue. + render: python + validations: + required: true + + - type: textarea + id: expected + attributes: + label: Expected behavior + description: What you expected to happen. + validations: + required: true + + - type: textarea + id: actual + attributes: + label: Actual behavior + description: What actually happened. Include tracebacks if applicable. + render: shell + validations: + required: true + + - type: textarea + id: context + attributes: + label: Additional context + description: | + - OS and platform + - OTel SDK / instrumentation versions + - Existing observability vendor (Datadog, Splunk, etc.) + - Collector configuration + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..4acc5ec --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,11 @@ +# SPDX-FileCopyrightText: 2026 The Botanu Authors +# SPDX-License-Identifier: Apache-2.0 + +blank_issues_enabled: false +contact_links: + - name: Questions & Discussions + url: https://github.com/botanu-ai/botanu-sdk-python/discussions + about: Ask questions and discuss ideas + - name: Security Vulnerabilities + url: https://github.com/botanu-ai/botanu-sdk-python/blob/main/SECURITY.md + about: Report security vulnerabilities privately (do NOT open a public issue) diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..d35d736 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,53 @@ +# SPDX-FileCopyrightText: 2026 The Botanu Authors +# SPDX-License-Identifier: Apache-2.0 + +name: Feature Request +description: Suggest a new feature or enhancement +labels: ["enhancement"] +body: + - type: markdown + attributes: + value: | + Thanks for suggesting an improvement to Botanu SDK! + + - type: textarea + id: problem + attributes: + label: Problem statement + description: What problem does this feature solve? Is this related to a frustration? + validations: + required: true + + - type: textarea + id: solution + attributes: + label: Proposed solution + description: Describe the solution you'd like. Include API sketches if possible. + validations: + required: true + + - type: textarea + id: alternatives + attributes: + label: Alternatives considered + description: Any alternative approaches you've considered. + validations: + required: false + + - type: dropdown + id: scope + attributes: + label: Which component does this affect? + multiple: true + options: + - Core SDK (bootstrap / attach) + - Run context / decorators + - Span processors + - Carrier propagation (SQS, Kafka, Celery) + - LLM / GenAI tracking + - Resource detection + - Collector configuration + - Documentation + - Other + validations: + required: true diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..42cfbe4 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,38 @@ + + + +## Summary + + + +## Changes + + + +- + +## Type of change + + + +- [ ] Bug fix (non-breaking change that fixes an issue) +- [ ] New feature (non-breaking change that adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to change) +- [ ] Documentation update +- [ ] CI / build / tooling + +## Testing + + + +- [ ] Unit tests pass (`pytest`) +- [ ] Lint passes (`ruff check`) +- [ ] Type check passes (`mypy`) + +## Checklist + +- [ ] My code follows the project's coding style +- [ ] I have added SPDX headers to new files +- [ ] I have added tests for my changes +- [ ] I have updated documentation if needed +- [ ] All commits are signed off (`git commit -s`) per the [DCO](../DCO) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..7aba505 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,46 @@ +# SPDX-FileCopyrightText: 2026 The Botanu Authors +# SPDX-License-Identifier: Apache-2.0 + +repos: + # General file hygiene + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-toml + - id: check-added-large-files + args: ["--maxkb=500"] + - id: check-merge-conflict + - id: detect-private-key + + # Ruff — linter + formatter (replaces flake8, isort, black) + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.4.8 + hooks: + - id: ruff + args: [--fix, --exit-non-zero-on-fix] + - id: ruff-format + + # Type checking + - repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.10.0 + hooks: + - id: mypy + additional_dependencies: ["opentelemetry-api>=1.20.0"] + args: [--ignore-missing-imports] + pass_filenames: false + entry: mypy src/botanu/ + + # SPDX license header check + - repo: https://github.com/fsfe/reuse-tool + rev: v3.0.2 + hooks: + - id: reuse + + # DCO sign-off check (local — CI uses dcoapp/app) + - repo: https://github.com/christophebedard/dco-check + rev: v1.1.0 + hooks: + - id: dco-check diff --git a/.repolinterrc.yml b/.repolinterrc.yml new file mode 100644 index 0000000..d692b3b --- /dev/null +++ b/.repolinterrc.yml @@ -0,0 +1,124 @@ +# SPDX-FileCopyrightText: 2026 The Botanu Authors +# SPDX-License-Identifier: Apache-2.0 +# +# Repolinter configuration for LF AI & Data Foundation compliance. +# See: https://github.com/todogroup/repolinter + +version: 2 +axioms: + linguist: language + licensee: license + packagers: packager + +rules: + # ---- License ---- + license-file-exists: + level: error + rule: + type: file-existence + options: + globsAny: + - LICENSE* + - COPYING* + + # ---- README ---- + readme-file-exists: + level: error + rule: + type: file-existence + options: + globsAny: + - README* + + # ---- CONTRIBUTING ---- + contributing-file-exists: + level: error + rule: + type: file-existence + options: + globsAny: + - CONTRIBUTING* + - .github/CONTRIBUTING* + + # ---- Code of Conduct ---- + code-of-conduct-file-exists: + level: error + rule: + type: file-existence + options: + globsAny: + - CODE_OF_CONDUCT* + - .github/CODE_OF_CONDUCT* + + # ---- SECURITY ---- + security-file-exists: + level: warning + rule: + type: file-existence + options: + globsAny: + - SECURITY* + - .github/SECURITY* + + # ---- NOTICE / attribution ---- + notice-file-exists: + level: warning + rule: + type: file-existence + options: + globsAny: + - NOTICE* + + # ---- DCO ---- + dco-file-exists: + level: warning + rule: + type: file-existence + options: + globsAny: + - DCO* + + # ---- CHANGELOG ---- + changelog-file-exists: + level: warning + rule: + type: file-existence + options: + globsAny: + - CHANGELOG* + - HISTORY* + + # ---- No binaries ---- + binaries-not-present: + level: error + rule: + type: file-type-exclusion + options: + type: + - "**/*.exe" + - "**/*.dll" + - "**/*.so" + - "**/*.dylib" + - "**/*.pyc" + - "**/*.pyo" + + # ---- Source files have SPDX headers ---- + source-license-headers-exist: + level: warning + rule: + type: file-contents + options: + globsAll: + - "src/**/*.py" + content: "SPDX-License-Identifier" + fail-on-non-existent: false + + # ---- No test credentials ---- + test-directory-exists: + level: warning + rule: + type: file-existence + options: + globsAny: + - tests/* + - test/*