Project Checklist
This checklist helps verify whether a small Python project has a clean and maintainable foundation.
It is not a strict certification.
It is a practical self-review tool.
Repository basics
A good project should have basic repository files:
- [ ]
README.md - [ ]
.gitignore - [ ]
LICENSE - [ ]
CONTRIBUTING.md - [ ] pull request template
- [ ] clear project roadmap or development notes
These files help people understand what the project is, how to work with it, and how it may grow.
Project structure
The project should have a clear structure:
- [ ] source code is separated from repository metadata
- [ ] tests are separated from source code
- [ ] documentation has a dedicated place
- [ ] GitHub-specific files are stored in
.github/ - [ ] generated local files are ignored
Example:
modern-python-project-guide/
├── .github/
├── docs/
├── src/
├── tests/
├── .gitignore
├── .pre-commit-config.yaml
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── mkdocs.yml
├── pyproject.toml
└── uv.lock
The exact structure may differ between projects.
The important part is that the structure is understandable.
Python project configuration
The project should clearly define how Python and dependencies are managed:
- [ ]
pyproject.tomlexists - [ ] project name is defined
- [ ] project version is defined
- [ ] supported Python version is defined
- [ ] a build system is defined when the project is installable
- [ ] runtime dependencies are listed
- [ ] development dependencies are separated from runtime dependencies
- [ ]
uv.lockis committed - [ ]
.venv/is ignored
This makes the project easier to reproduce on another machine.
Source code
The source code should be easy to find and understand:
- [ ] package code is inside
src/ - [ ] package name is clear
- [ ] modules have focused responsibilities
- [ ] public functions have readable names
- [ ] simple docstrings explain non-obvious modules or functions
- [ ] code avoids unnecessary complexity
The goal is not to make the code clever.
The goal is to make it readable and maintainable.
Tests
The project should include automated tests:
- [ ] tests are stored in
tests/ - [ ] test files use clear names
- [ ] test functions use clear names
- [ ] tests check behavior, not implementation details
- [ ] tests include important edge cases
- [ ] tests can be run with one command
In this guide, tests are run with:
uv run pytest
Good tests make future changes safer.
Linting and formatting
The project should use automated code quality tools:
- [ ] Ruff is installed as a development dependency
- [ ] Ruff is configured in
pyproject.toml - [ ] linting can be run locally
- [ ] formatting can be checked locally
- [ ] formatting can be fixed automatically
- [ ] ignored rules are intentional and documented when needed
In this guide, the local commands are:
uv run ruff check .
uv run ruff format --check .
uv run ruff format .
The goal is not to satisfy tools blindly.
The goal is to keep the project clean and consistent.
Type checking
The project should check whether code follows its type annotations:
- [ ] mypy is installed as a development dependency
- [ ] mypy is configured in
pyproject.toml - [ ] source code and tests use readable type annotations
- [ ] type checking can be run locally
- [ ] strictness settings are understood rather than copied blindly
In this guide, type checking runs with:
uv run mypy
Type checking complements tests and Ruff; it does not replace them.
Test coverage
The project should use coverage as a diagnostic tool:
- [ ] pytest-cov is installed as a development dependency
- [ ] coverage is limited to production source code
- [ ] statement and branch coverage are measured
- [ ] missing lines are visible in the terminal report
- [ ] a percentage is not treated as proof of test quality
In this guide, tests and coverage run together:
uv run pytest --cov=text_toolkit --cov-report=term-missing
There is no minimum percentage gate.
pre-commit hooks
The project may automate fast checks before a commit:
- [ ]
pre-commitis installed as a development dependency - [ ]
.pre-commit-config.yamlis committed - [ ] hooks focus on fast, repeatable checks
- [ ] contributors know that hooks must be installed in each clone
- [ ] hooks do not replace the complete local checks or CI
In this guide, install and run the hooks with:
uv run pre-commit install
uv run pre-commit run --all-files
Markdown linting
Documentation should have lightweight automated checks:
- [ ]
rumdlis installed as a development dependency - [ ] Markdown rules are configured deliberately
- [ ] project-specific exceptions are narrow and explained
- [ ] linting runs locally, in pre-commit, and in CI
- [ ] link checking and human review remain separate checks
In this guide, Markdown linting runs with:
uv run rumdl check .
Documentation site
When the documentation set grows, a generated site can improve navigation:
- [ ] MkDocs is installed as a development dependency
- [ ]
mkdocs.ymldefines explicit navigation - [ ]
docs/index.mdprovides a site landing page - [ ] source Markdown remains readable directly on GitHub
- [ ] generated
site/files are ignored - [ ] strict site builds run locally and in CI
- [ ] building and publishing are treated as separate operations
- [ ] a dedicated deployment workflow publishes only from
main - [ ] generated output is uploaded as an artifact instead of committed
- [ ] deployment permissions are limited to the deployment job
- [ ] the public site contains no secrets or private material
Preview and validate the site with:
uv run mkdocs serve
uv run mkdocs build --strict
Continuous integration
The project should run checks automatically in CI:
- [ ] GitHub Actions workflow exists
- [ ] CI runs on pull requests
- [ ] CI runs on pushes to
main - [ ] CI installs dependencies from the lockfile
- [ ] CI runs linting
- [ ] CI checks formatting
- [ ] CI lints Markdown
- [ ] CI builds the documentation site strictly
- [ ] CI runs tests with coverage reporting
- [ ] CI runs type checking
- [ ] CI builds a wheel and source distribution
- [ ] CI status is visible in the README
Continuous deployment
If the documentation is published automatically:
- [ ] GitHub Pages uses GitHub Actions as its source
- [ ] the deployment workflow runs after relevant changes reach
main - [ ] pull requests validate the site without publishing it
- [ ] build and deploy jobs pass the generated site as an artifact
- [ ] the deployment uses the
github-pagesenvironment - [ ] the published site is checked after deployment
CI helps protect the main branch from broken changes.
Git workflow
The project should use a clear Git workflow:
- [ ] changes are made on branches
- [ ] branch names are descriptive
- [ ] commits are small and focused
- [ ] commit messages are readable
- [ ] meaningful changes go through pull requests
- [ ] pull requests explain what changed and why
- [ ] pull requests include information about checks
- [ ] merged branches are deleted
A good workflow keeps history understandable.
Pull requests
A good pull request should answer:
- [ ] What changed?
- [ ] Why was it changed?
- [ ] How was it checked?
Before opening a pull request, review:
- [ ] the changed files
- [ ] the diff
- [ ] the pull request title
- [ ] the pull request description
- [ ] local check results
- [ ] whether the change is small enough
Small pull requests are easier to review and safer to merge.
Local command checklist
For code changes, run:
uv run ruff check .
uv run ruff format --check .
uv run rumdl check .
uv run mkdocs build --strict
uv run pytest --cov=text_toolkit --cov-report=term-missing
uv run mypy
uv build --no-sources
If formatting fails, run:
uv run ruff format .
Then repeat:
uv run ruff check .
uv run ruff format --check .
uv run rumdl check .
uv run mkdocs build --strict
uv run pytest --cov=text_toolkit --cov-report=term-missing
uv run mypy
uv build --no-sources
For documentation-only changes, code checks may not always be necessary.
However, review the rendered Markdown on GitHub.
Red flags
The project may need cleanup if:
- [ ] many unrelated changes appear in one pull request
- [ ] commit messages are vague
- [ ] tests are missing
- [ ] CI is failing
- [ ] generated files are committed
- [ ] dependencies are installed manually but not recorded
- [ ] configuration files are copied without being understood
- [ ] the project cannot be set up from a clean clone
These are not reasons to panic.
They are signals that the workflow needs attention.
Minimal healthy project
A small healthy Python project should answer these questions:
What is this project?
How do I install it?
Where is the code?
Where are the tests?
How do I run the tests?
How do I inspect test coverage?
How do I check formatting and linting?
How do I lint Markdown documentation?
How do I preview and validate the documentation site?
How do I check type annotations?
How do I build distribution files?
What happens before code is merged?
If the repository answers these questions clearly, it has a strong foundation.
Rule of thumb
A clean project is not necessarily a large project.
A clean project is one where another person can understand the structure, run the checks, and make a small change safely.
Start simple.
Keep changes small.
Explain decisions.
Let the project grow gradually.