diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..432fcac --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,32 @@ +name: CodeQL + +on: + push: + branches: [main] + pull_request: + branches: [main] + paths-ignore: + - "src/_vendor/**" + schedule: + - cron: "23 3 * * 1" + workflow_dispatch: + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + steps: + - uses: actions/checkout@v6 + + - 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/release.yml b/.github/workflows/release.yml index 870a765..696c08a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,6 +11,7 @@ jobs: permissions: contents: write id-token: write + attestations: write steps: - uses: actions/checkout@v6 @@ -19,6 +20,8 @@ jobs: with: python-version: "3.13" + - uses: astral-sh/setup-uv@v5 + - name: Verify tag matches version run: | python - <<'PY' @@ -35,10 +38,27 @@ jobs: sys.exit(1) PY + - name: Install deps + run: uv pip install --system -e ".[dev]" + + - name: Ruff + run: uv run ruff check src test + + - name: Mypy + run: uv run mypy src/sportradar_datacore_api + + - name: Pytest + run: uv run pytest + - name: Build artifacts run: | - python -m pip install --upgrade pip build - python -m build + uv build + + - name: Generate SBOM + uses: anchore/sbom-action@v0 + with: + path: dist + artifact-name: sportradar-sbom - name: Upload release artifacts uses: actions/upload-artifact@v7 @@ -46,9 +66,15 @@ jobs: name: sportradar-dist path: dist/* + - name: Attest build provenance + uses: actions/attest-build-provenance@v2 + with: + subject-path: dist/* + - name: Create GitHub Release uses: softprops/action-gh-release@v2 with: + generate_release_notes: true files: dist/* env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/RELEASING.md b/RELEASING.md index 02b33aa..9869e6d 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -16,6 +16,9 @@ git push origin vX.Y.Z ## 3) What happens automatically - GitHub Action `release.yml` verifies tag matches `pyproject.toml` version -- Builds `sdist` + `wheel` +- Runs ruff, mypy, and pytest before building +- Builds `sdist` + `wheel` with `uv` - Publishes to PyPI via trusted publishing - Artifacts are attached to a GitHub Release for the tag +- GitHub Release notes are auto-generated +- SBOM is generated and build provenance is attested diff --git a/pyproject.toml b/pyproject.toml index 620b518..aeb43f5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -80,11 +80,18 @@ testpaths = ["test"] [tool.mypy] python_version = "3.12" plugins = ["pydantic.mypy"] + mypy_path = ["src", "src/_vendor"] -exclude = 'src/_vendor/' + +exclude = ["^src/_vendor/"] warn_unused_ignores = true warn_redundant_casts = true strict_optional = true check_untyped_defs = true disallow_untyped_defs = true + +[[tool.mypy.overrides]] +module = "datacore_client.*" +follow_imports = "skip" +ignore_errors = true