invoke-tasklib
Reusable Invoke tasks shared across Python
projects: formatting, linting, type-checking, testing, environment setup,
security auditing, releasing, documentation, and cleanup — all as a single
importable package instead of a tasks.py you copy-paste and let drift
between repositories.
📖 Full documentation: https://durandtibo.github.io/invoke-tasklib/
Install
uv add --dev invoke-tasklib
or with pip:
pip install invoke-tasklib
Quickstart
1. Add a tasks.py at the root of your project:
# tasks.py
from invoke_tasklib import ns
2. Add an invoke.yaml with, at minimum, your package name:
tasklib:
package:
name: my_package
3. List and run the tasks:
invoke --list
invoke format.check-python lint.check-lint
invoke test.unit
If a task fails because a tool like ruff or pytest isn't installed yet,
run invoke env.install first.
See the Get Started guide for a full walkthrough.
Tasks
Tasks are grouped into namespaces, one per module. Each task either checks/reports (read-only, exits non-zero on violations) or mutates (formats, builds, publishes) — the table below flags which.
| Namespace | Task | Behavior | Mutates? |
|---|---|---|---|
format |
format.check-python |
Check Python formatting with ruff | ❌ |
format |
format.fix-python |
Format Python code with ruff | ✅ |
format |
format.check-docstrings |
Check docstring formatting with docformatter | ❌ |
format |
format.fix-docstrings |
Format docstrings with docformatter | ✅ |
format |
format.check-shell |
Check shell scripts with shellcheck | ❌ |
format |
format.fix-shell |
Format shell scripts with shfmt | ✅ |
lint |
lint.check-lint |
Check linting with ruff | ❌ |
lint |
lint.fix |
Fix auto-fixable linting issues with ruff | ✅ |
imports |
imports.check-cycles |
Check for cyclic import dependencies | ❌ |
types |
types.check |
Check type hints with pyright | ❌ |
test |
test.doctest |
Run doctests on source code and markdown files | ❌ |
test |
test.doctest-src |
Run doctests on source code | ❌ |
test |
test.doctest-markdown |
Run doctests on Python examples in markdown files | ❌ |
test |
test.unit |
Run unit tests | ❌ |
test |
test.integration |
Run integration tests | ❌ |
test |
test.functional |
Run functional tests | ❌ |
test |
test.all |
Run unit, integration, and functional tests | ❌ |
test |
test.coverage-report |
Generate an HTML/terminal report from existing coverage data | ❌ |
test |
test.benchmark |
Run performance benchmarks | ❌ |
env |
env.create-venv |
Create a virtual environment and install invoke | ✅ |
env |
env.install |
Install project dependencies and the package (editable) | ✅ |
env |
env.update |
Update dependencies and pre-commit hooks | ✅ |
env |
env.show-installed-packages |
Show the installed packages | ❌ |
env |
env.show-python-config |
Show the Python configuration | ❌ |
release |
release.build |
Build the package and verify installation (--check also validates metadata with twine) |
✅ |
release |
release.pypi |
Build and publish the package to PyPI | ✅ |
doc |
doc.publish-dev |
Publish development (unstable) docs | ✅ |
doc |
doc.publish-latest |
Publish latest (stable) docs | ✅ |
security |
security.audit |
Audit installed dependencies for known vulnerabilities with pip-audit | ❌ |
| (top-level) | clean |
Remove build artifacts and caches | ✅ |
format.* and lint.* follow a naming convention: read-only checks are
named check_<target>, and the matching in-place fixer is named
fix_<target> (e.g. check_python/fix_python), so the counterpart of a
task is always easy to find. Follow this convention when adding new tasks
to these namespaces.
For task-by-task details, options (like --cov on test.* tasks), and the
tools each one wraps, see the
User Guide.
Configuration
Only tasklib.package.name is required — everything else has a sensible
default derived from it:
tasklib:
package:
name: my_package # required
python_version: "3.14" # used by env.create-venv
paths:
src: src/my_package # default: src/<package.name>
tests: tests
unit_tests: tests/unit # default: <tests>/unit
integration_tests: tests/integration # default: <tests>/integration
functional_tests: tests/functional # default: <tests>/functional
benchmarks: tests/benchmarks # default: <tests>/benchmarks
docs_config: docs/mkdocs.yml
See the Config reference for how each path default is derived.
Composing a custom subset of tasks
Need a different set of tasks, or a one-off task alongside the shared ones?
Import individual task modules instead of the pre-built ns:
from invoke import Collection
from invoke_tasklib import lint, test
from . import my_custom_task
ns = Collection(lint, test, my_custom_task)
Prefer adding a config knob to a shared task over forking it; reserve custom composition for things that are genuinely one-off to a single project.
API Stability
⚠️ invoke-tasklib is under active development and its API is not
yet stable — pin a specific version in your project's dependencies for
consistent behavior across releases.
Contributing
Contributions are welcome! Please open an issue first to discuss significant changes. See the developer guide for how to set up a development environment.
License
invoke-tasklib is licensed under the BSD 3-Clause "New" or "Revised"
license available in
LICENSE.
Release files for invoke-tasklib 0.0.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| invoke_tasklib-0.0.6.tar.gz | 14.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| invoke_tasklib-0.0.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 31.2 kB
Release files / invoke_tasklib-0.0.6.tar.gz
| Download URL | invoke_tasklib-0.0.6.tar.gz |
|---|---|
| Size | 14.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dbe32d4da6b1162eade07735ad1de5b7f3471dec6ccf3c685c6bd54c9f5c648c
|
|
BLAKE2b-256 checksum How to use checksums |
7a800a5020adc69ed505088d7fa5f9dc765cf3ffc8d30743f342d639cd9c87bb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency logRelease files / invoke_tasklib-0.0.6-py3-none-any.whl
| Download URL | invoke_tasklib-0.0.6-py3-none-any.whl |
|---|---|
| Size | 16.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3b9d43922ce443dbfdd5c8fcfdfa3eb0b9fad8dca62807dc2c97c701be42ce8f
|
|
BLAKE2b-256 checksum How to use checksums |
6998ac477d2f834c116e7b536383590328ddb19bfdadea11215fada645029591
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency log