Copier template for qgis plugins
  • Python 38.8%
  • Jinja 33.4%
  • Shell 25.7%
  • C++ 1.3%
  • CMake 0.8%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Agent (claude) 59bb011506
feat(skills): add human-review, rename .claude to .agents
Rename the bundled skill library from .claude/skills to .agents/skills so
it is agent-agnostic rather than tied to one assistant, updating every
reference (Makefile validate target, Forgejo CI step, ruff extend-exclude and
codespell skip, and the READMEs).

Add the human-review skill (maintainer-grade change review with
complexity/duplication/comment analysers and an optional pre-push hook) to the
library so generated plugins ship with it.

Assisted-by: Agent (claude) <ai@blobfish.icu>
2026-07-10 19:34:52 -04:00
template feat(skills): add human-review, rename .claude to .agents 2026-07-10 19:34:52 -04:00
copier.yml build(copier): add template config, tooling, render fixtures 2026-07-09 13:22:37 -04:00
README.md feat(skills): add human-review, rename .claude to .agents 2026-07-10 19:34:52 -04:00

copier-qgis-plugin

Copier QGIS

A Copier template for python-first QGIS plugins with an optional SIP-generated C++ extension, a Qt Designer UI, translations, a full lint / type / format toolchain, and a signed, auditable commit workflow.

Most existing QGIS plugin templates (Plugin Builder, pb_tool, older cookiecutters) are unmaintained or predate uv, ruff, and modern typing. This template targets the current ecosystem: uv for dependencies, qgis-plugin-ci for packaging and release, and Forgejo Actions for CI.

Repository layout

This repo follows the canonical Copier layout: the template content lives under template/ (Copier's _subdirectory), and only copier.yml and this README sit at the root.

copier.yml     template questions and engine config
template/       the rendered plugin tree (.jinja files are templated)
README.md       this file

Everything a generated project needs -- signing scripts, TAGS.md/SCOPES.md, pre-commit config, CI, docs -- is shipped inside template/, so generated plugins are self-governing.

What you get

A generated plugin includes:

  • a uv-managed pyproject.toml, ruff-formatted and mypy-clean out of the box;
  • a proper plugin package (classFactory, main class, metadata.txt) following the current PyQGIS structure;
  • a Qt Designer dialog (dialog_base.ui) loaded via uic.loadUi;
  • translation plumbing (i18n/*.ts, self.tr(...), pylupdate5/lrelease Make targets, a QTranslator loaded at startup);
  • an optional QGIS Processing provider with a sample algorithm;
  • an on-demand runtime dependency loader (dependencies.py + requirements-runtime.txt) that installs missing pure-python libraries via pip on first load, adapting the qgis-easy-dependencies pattern to a PEP 508 requirement list (headless-testable helpers);
  • an optional C++ extension wired through SIP + CMake, exporting compile_commands.json for clangd, clang-tidy, and clang-format;
  • pre-commit hooks (ruff, mypy, codespell, clang-format) and a commit-msg hook enforcing Conventional Commits with a mandatory scope;
  • README badges and a "Publishing to the QGIS Plugin Repository" guide;
  • an agent-agnostic .agents/skills/ library — qgis-validate (offline plugins.qgis.org pre-flight, also wired into make validate and CI), qgis-smoke-test (headless load in a real QGIS), qgis-run (deploy + run with the actual QGIS binary), and human-review (maintainer-grade change review with complexity/duplication analysers);
  • Forgejo Actions CI that lints, type-checks, tests, validates, and packages.

Requirements

copier and uv (and git). Building the optional C++ extension additionally needs a C++17 compiler, CMake, and the clang tools; translations need Qt 5's pylupdate5 / lrelease.

Quick start

uvx copier copy gh:youruser/copier-qgis-plugin path/to/new-plugin
cd path/to/new-plugin
uv sync --all-extras
uv run pre-commit install --install-hooks --hook-type commit-msg --hook-type pre-push
make deploy      # symlink into the active QGIS profile for live testing

Update a generated plugin when the template changes:

uvx copier update

Template questions

See copier.yml. Key choices: plugin_name, plugin_package, qgis_minimum_version, use_processing_provider, and use_cpp_extension (which toggles the entire SIP/CMake/clang chain).

Commit & signing workflow

The generated project bakes in two conventions so autonomous (agent) changes are attributable and verifiable; humans commit normally.

Agent commits go through scripts/git-agent-commit (exposed as git agent-commit): it sets the agent author/committer identity, signs the commit, and runs the normal hook path. Messages must be Conventional Commits with a mandatory scope (types in TAGS.md, scopes in SCOPES.md), enforced by the commit-msg hook.

Signing has two paths, auto-detected by the wrapper:

  • scripts/setup-signing-key.sh -- registers a short-lived ed25519 key to a Forgejo/Gitea account (needs ~/.config/forgejo-agent/env from your chezmoi state) so commits show a verified badge;
  • scripts/setup-local-signing.sh -- the same key without a forge, for sandboxes or before that env is deployed (signed, but no forge badge).

Put the wrapper on PATH once: ln -s "$PWD/scripts/git-agent-commit" ~/.local/bin/git-agent-commit.

Developing the template

Render with an answers file and run the generated project's own checks:

uvx copier copy --trust --data-file answers.yml --defaults . /tmp/out
cd /tmp/out && uv sync --all-extras && make check

License

MIT. Generated plugins default to GPL-3.0-or-later because they link the GPL QGIS API; choose another license at generation time if that does not apply.