Organization-wide baseline standards for Python repositories: pinned tooling, pre-commit, CI, and contributor workflows.
- Purpose
- Development documentation
- What Is Standardized
- Repository Layout
- Usage Model
- Design Principles
- Quick Start (Consumer Repo)
- Adoption tiers
- Reusable GitHub Actions
- Status
This repository provides a shared baseline for Python projects so teams can:
- keep lint, format, and type checks consistent across repositories;
- reduce CI/local drift;
- document process expectations in one place;
- allow project-specific ignores (Ruff per-file, Mypy overrides) without forking the shared rule baseline.
docs/development.md is the hub for organization-wide Python development policy (links to migration, versioning, CI reusables, and style notes such as string enums). Point consumer DEVELOPMENT.md / contributor docs at that page for shared baselines.
- Shared policy and doc index in docs/development.md (includes links to style pages under
docs/); pyproject.tomltooling sections (ruffviabaselines/ruff.toml+ thin overlay, strictmypykeys vsbaselines/expected-mypy.json,pytest,pytest-covin template dev extras forpytest --cov=…);.pre-commit-config.yamlwith pinned hook revisions;- CI workflow baseline: Tier A
lint.ymldelegates to orgreusable-pre-commit.yml(pin@v…); tests live in the consumer repo (start fromtemplates/github-workflows/test.yml); - Cursor rules baseline for process conventions;
- migration and versioning guidance.
templates/pyproject/: baselinepyproject.tomlsections and examples.templates/baselines/: vendoredruff.toml,DIGESTS,expected-mypy.json— copy into consumerbaselines/(digest-checked byscripts/check_lint_baseline.py).templates/pre-commit/: baseline.pre-commit-config.yaml(includesverify-python-project-standardshook).templates/scripts/:verify-standards.shandcheck_lint_baseline.py— copy into consumerscripts/next to the pre-commit hook.templates/github-workflows/: copy-paste workflow examples for consumer repos..github/workflows/reusable-*.yml: callable workflows (shared pre-commit) for repos that reference this repository instead of duplicating lint YAML. Thereusable-filename prefix is an org convention for discoverability, not a GitHub requirement — see the Naming section in docs/reusable-workflows.md.templates/cursor-rules/: baseline.cursor/rules/*.mdcfiles (dependency pinning, commit messages, PR workflow, documentation TOC, changelog alignment, string enums /StrEnum). Consumers copy the ones they need into their own.cursor/rules/— not installed automatically; see docs/development.md (Cursor / AI assistant rules).docs/: development.md (hub), migration guide, versioning, reusable workflows, and style notes (e.g.string-enums.md).scripts/: validation helpers for standards adoption;standards_release_bump.sh+finalize_standards_changelog.pyautomate SemVer bumps (see docs/versioning.md)..bumpversion.tomlconfiguresbump-my-versionforSTANDARDS_VERSIONand example@v…pins (notCHANGELOG.md).
- Start from these templates when creating a new Python repository.
- Copy the baseline into an existing repository.
- Add explicit, documented project-level overrides.
- Keep a
STANDARDS_VERSIONfile in each consumer repository.
- Tooling config is the primary enforcement mechanism.
- Exact version pinning for reproducibility.
- Baseline plus local overrides.
- Minimize duplicated policy text between tools, CI, and AI rules.
cp templates/pre-commit/.pre-commit-config.yaml /path/to/repo/.pre-commit-config.yaml
cp templates/github-workflows/lint.yml /path/to/repo/.github/workflows/lint.yml
cp templates/pyproject/pyproject.toml /path/to/repo/pyproject.toml
mkdir -p /path/to/repo/baselines
cp templates/baselines/* /path/to/repo/baselines/Then copy templates/scripts/verify-standards.sh and templates/scripts/check_lint_baseline.py to scripts/ in the consumer repo (the pre-commit template runs verify-standards.sh, which invokes the Python checker). Adjust package metadata; keep [tool.ruff] extend = "baselines/ruff.toml" and put rule changes only in baselines/ruff.toml when upgrading from this repo.
When publishing updates to these scripts, keep scripts/verify-standards.sh and templates/scripts/verify-standards.sh identical, and scripts/check_lint_baseline.py and templates/scripts/check_lint_baseline.py identical (or regenerate template copies from the canonical files).
Not every Python repo should use the same CI shape. Use these tiers:
| Tier | Typical repo | Use from this repo | Keep local |
|---|---|---|---|
| A — Library | Packaged library, multi-OS/Python matrix, pyproject.toml dev extras |
Delegated reusable-pre-commit.yml for lint; owned test.yml (see templates/github-workflows/test.yml + local matrix/coverage) |
Thin lint.yml caller; full control over test CI |
| B — Service / API | Django/FastAPI apps, Docker, DB, secrets, long integration jobs | reusable-pre-commit.yml, pre-commit + policy templates |
Full test / deploy workflows in the app repository |
Pinning: Consumer workflows should reference a release tag such as @v4.3.2 (or a commit SHA), not @main, and set STANDARDS_VERSION in the consumer repo to match. See docs/versioning.md.
Example Tier B: hear-the-music-tree-api keeps database and containerized pytest in its own workflow and may call reusable pre-commit only. See that repo’s docs/ci/python-project-standards.md.
For orgs that keep this repo as the single source of truth, consumer workflows can call:
.github/workflows/reusable-pre-commit.yml— checkout, install, runpre-commit(Tier A and Tier B).
There is no reusable test matrix; use templates/github-workflows/test.yml in the consumer repo and extend it as needed.
See docs/reusable-workflows.md for caller examples and the full input list.
Versions are SemVer (v1.2.3 tags, STANDARDS_VERSION without v). Maintainers document changes in CHANGELOG.md, tag vX.Y.Z, and publish a GitHub Release with the same notes. Consumers pin callable workflows to that tag (or a commit SHA), not to main long term.
Pushing a SemVer tag like v4.3.2 triggers .github/workflows/release-on-tag.yml, which publishes the GitHub Release from the matching CHANGELOG.md section. You can still run python3 scripts/publish_github_release.py locally (see docs/versioning.md).
Baseline is versioned; evolve via tagged releases and migration notes, not only through main.