template/is the generated project. Files ending in.jinjaare rendered with the answers fromcopier.yml(the suffix is dropped); all other files are copied verbatim, so GitHub Actions${{ }}expressions and Sphinx's autosummary templates need no escaping there. Inside a.jinjafile, wrap GitHub expressions in{% raw %}...{% endraw %}.- Values every project shares but nobody should be asked for (
python_max,uv_version) are computed questions (when: false) incopier.yml. Bump them there;copier updatecarries the change into each project. - In
justfile.jinja, recipes take arguments as"$@"(set positional-arguments) so just's{{ }}never collides with Jinja's.
You need uv and just.
just bake # render the working tree into $TMPDIR/python-template-bake
just test # bake twice (the yes/no questions answered yes, then no) and, in each, run
# quality-check, build-docs, every pre-commit hook, dist,
# and the tag/dev version checksBefore the checks, just test copies fixtures/ into the baked project:
always/ (a function whose docstring draws a figure, an .rst page with IPython
blocks) and, in the bake with docs_notebooks, notebooks/ (a Markdown page with
a code cell, a notebook). build-docs runs them, and just test checks that
their output reaches the HTML.
just test is what the Template workflow runs on every pull request.
pre-commit needs git 2.31 or newer.
Before tagging a template release, also run on a baked project:
uvx --from "sp-repo-review[cli]" sp-repo-review . # Scientific Python checks
uvx zizmor --offline .github # workflow securityProjects record the template version in .copier-answers.yml (_commit), and
copier update moves them to the newest tag. Tag releases vX.Y.Z: a new
major version for changes that need manual follow-up in projects, a minor one
for new tooling, a patch for fixes. Note what changed, and anything a project
must do by hand, in the release notes.
- Encode what the packages actually do; a convention earns its place here once it has proved itself in a real package.
- Keep generated projects passing
just test, repo-review, actionlint and zizmor. - Reference actions by a tag that exists. Most publish moving major tags
(
actions/checkout@v7); astral-sh/setup-uv stopped doing so in v8, so it is pinned to an exact release (@v10.2.0), which Dependabot keeps current. - Commit messages follow Conventional Commits.