Skip to content

The Template⚓︎

The template generates a package structure that reflects common best practices for Python projects. The layout shown below represents the full set of files and directories that may be created by the template. Depending on the configuration choices you made during setup, some of these files or components may be omitted automatically.

<PROJECT> ---------------------- # your freshly created project!
├── .copier-answers.yml -------- # Copier Answer to update project
├── .gitignore ----------------- #
├── .gitlab-ci.yml ------------- # Gitlab CI Config
├── .pre-commit-config.yml ----- #
├── .python-version ------------ #
├── CONTRIBUTING.md ------------ #
├── CHANGELOG.md --------------- #
├── Justfile ------------------- # Taskrunner
├── LICENSE -------------------- #
├── README.md ------------------ #
├── pyproject.toml ------------- # Project Config
├── src/<PROJECT> -------------- # Python Package   └── __init__.py ------------ #
├── tests ---------------------- # Tests for the Package   └── test_meta.py ----------- #
├── docs ----------------------- # Documentation pages   └── index.md --------------- #
├── zensical.toml -------------- #
└── .github -------------------- # Github CI Config
    └── ... -------------------- #

Github CI⚓︎

The template includes a set of GitHub Actions workflows that automate common development and release tasks. These workflows ensure code quality, reliability, and consistency without requiring manual intervention.

Under .github/workflows, the configuration is split into focused pipelines:

  • linting, formatting and typechecking with ruff and ty
  • running tests with coverage (also produces a coverage badge)
  • validating the package across multiple platforms and Python versions
  • publishing the documentation to GitHub Pages
  • creating GitHub releases with version tagging
  • releasing the package to PyPI

Together, these workflows provide a lightweight but complete CI/CD setup that supports the project from development through distribution.

└── .github -------------------- # Github CI Config
    ├── actions/setup ---------- #
       └── action.yml --------- #
    └── workflows -------------- #
        ├── code_quality.yml --- # Lint, Format and Typechecking
        ├── docs.yml ----------- # Documentation on Github Pages
        ├── publish.yml -------- # Publish to PyPi
        ├── release.yml -------- # GitHub release workflow
        ├── test_coverage.yml -- # Run tests with coverage
        └── test_platform.yml -- # Test different platforms and versions

Task Orchestration with Justfile⚓︎

The template uses a Justfile to provide a simple and consistent interface for task orchestration. It groups common development, quality assurance, and release tasks behind short, memorable commands, reducing the need to remember long tool-specific invocations. Most commands are built on top of uv, ensuring fast and reproducible execution.

Here are some of the core tasks provided:

  • just Lists all available tasks and aliases.
  • just info Display system and project information.
  • just check or just q Run linting and formatting with ruff and type checking with ty.
  • just test or just t Run the test suite.
  • just testall Run the test suite against all supported Python versions (3.10, 3.12, 3.14).
  • just ci [python] Execute formatting, linting, type checks, and tests in a single command, mirroring the CI pipeline locally. Optional python parameter specifies the Python version (default: 3.12).
  • just clean or just c Remove build artifacts, caches, and test outputs.
  • just venv Install and synchronize all project dependencies into the local virtual environment.
  • just update Update all dependencies and upgrade the lockfile.
  • just hooks or just h Install the pre-commit hooks.
  • just changelog Write the changelog using git-changelog.
  • just release <target> Make a new release. The target can be major, minor, patch, or a specific semver version.
  • just dist or just d Build the source distribution and wheel.
  • just docs Serve the documentation locally.
  • just init Initialize a Git repository, install dependencies and hooks, and create the initial commit.

One-time Initialization

The just init command is a one-time initialization recipe that:

  1. Initializes the git repository
  2. Installs dependencies (venv)
  3. Runs pre-commit hooks on all files to ensure code quality
  4. Removes itself (init.just) from the project
  5. Creates the initial commit

After running just init, the recipe file is automatically deleted since git is now initialized.


Pre-commit Hooks⚓︎

The template comes with a curated set of pre-commit hooks that enforce code quality and repository hygiene before changes are committed. These hooks run automatically on each commit, providing fast feedback and preventing common issues from entering the codebase. They are designed to align with the checks performed in CI, ensuring consistency between local development and automated pipelines.

Provided hooks include:

  • Ruff linting and formatting Automatically lint and format Python code using ruff, applying fixes where possible to keep the codebase consistent.

  • Dependency lockfile synchronization Ensures the uv lockfile is kept up to date whenever dependencies change, preventing drift between configuration and resolved environments.

  • Whitespace and file hygiene checks Prevent common formatting issues such as trailing whitespace and missing end-of-file newlines.

  • Repository safety checks Detects accidentally committed private keys and blocks unusually large files from being added to the repository.

Together, these hooks act as a first line of defense, catching errors early and reducing friction during code review and continuous integration.

Pre-commit hook versions are pinned in .pre-commit-config.yaml and should be updated periodically. To upgrade all hooks to their latest compatible versions, run:

If the prek tool is installed.

prek autoupdate

If the prek tool is not installed.

uvx prek autoupdate


GitLab CI⚓︎

The template includes a lightweight GitLab CI configuration that mirrors the most important quality checks performed locally and in GitHub Actions. It is designed to provide fast feedback while remaining easy to adapt to project-specific requirements.

The pipeline is split into two stages, test and build, and relies on containerized tools to ensure reproducible execution.

Key components include:

  • Stage-based pipeline A test stage for executing the test suite and a build stage for static analysis and formatting checks.

  • uv-powered test job A dedicated job runs tests using uv inside an official container image, installing dependencies and executing the test suite with coverage reporting enabled.

  • Reusable Ruff base job A shared base configuration defines the ruff image and setup, reducing duplication across linting and formatting jobs.

  • Ruff linting with GitLab integration The linting job exports results in GitLab’s code quality format, allowing issues to be displayed directly in merge requests.

  • Ruff formatting checks A formatting job verifies that the codebase is properly formatted by running ruff format in diff mode.

Overall, this configuration provides a concise yet effective CI setup for GitLab, ensuring code quality and test coverage while keeping the pipeline easy to maintain.


Licenses⚓︎

The template allows you to choose between several widely used open-source licenses. Each option provides a different balance between permissiveness, attribution requirements, and legal protection. Selecting an appropriate license early helps set clear expectations for users and contributors of your project.

Choose a License

Checkout ChooseALicense to find more detailed explanations of the Licenses.

License Permissive Requires Attribution Patent Grant Warranty Disclaimer Typical Use Case
MIT Yes Yes No Yes Simple, permissive licensing with minimal requirements
Apache 2.0 Yes Yes Yes Yes Projects that want explicit patent protection and clear contribution terms
Unlicense Yes No No Yes Public-domain–like release with no usage restrictions

In short, MIT is a lightweight and popular choice, Apache 2.0 adds explicit patent protections, and Unlicense removes nearly all restrictions by dedicating the work to the public domain.


Copier Answers⚓︎

The template includes a .copier-answers.yml that records the choices you made when generating the project. This file allows the project to be updateable: when the template is updated in the future, Copier can reapply the changes to your existing project while preserving your customizations.

By maintaining this answers file, you ensure that updates to the template, such as new workflows, configuration improvements, or additional files, can be integrated safely and consistently without overwriting your work.


Pyproject⚓︎

The template includes a pyproject.toml configuration file that defines project-wide settings for tools like ruff. The linting rules follow a simple philosophy: enable all rules by default to maximize code quality, and disable only those that are non-sensical or conflict with project conventions.

This approach ensures comprehensive static analysis while minimizing unnecessary noise, helping maintain a clean and consistent codebase.


Changelog⚓︎

In order to keep a Changelog run the following command.

just changelog

For more details on the tool check out the Documentation of Git Changelog

Tip

For the Changelog to work correct, it is important to adhere to Conventional Commits