3. Conventions¶
The rules every change follows.
Code¶
- Use the
maketargets (make help): CI runs the same ones. - Docstrings on public functions and classes (Google style): they generate the API reference.
- Settings through
ApplicationSettings(settings.py, pydantic-settings), notos.environscattered in the code. -
Logging with the package's loguru logger, not
print: -
Log, then raise; do not swallow exceptions:
if not path.exists(): logger.error(f"File not found: {path}. Current directory: {Path.cwd()}") raise FileNotFoundError(path)In an
exceptblock,logger.exception(...)logs the message and the stack trace. Not raising is fine only when a loop must go on after one failure. -
Large data: Polars. CPU-bound work:
multiprocessingpool map. - System-changing actions (installs,
chezmoi apply, drivers,sudo) always go through the TUI's confirmation dialog.
Branches and pull requests¶
- Comment on (or create) the issue and wait to be assigned.
- Branch off
dev:feature/<name>orbugfix/<name>. Stay up to date withgit merge dev(branch already pushed) orgit rebase dev(local only). - Run
make check(4. Testing), then open a pull request todev. Its title follows the commit convention below: it becomes the squash commit and decides the version. - When
devis ready, a pull requestdevโmainreleases it. - After a release, merge
mainback intodev(merge commit, direct push). On conflicts onCHANGELOG.mdor apyproject.tomlversion, keepmain's and regenerateuv.lockwithuv lock.
| Merge | Strategy | Why |
|---|---|---|
feature/* โ dev |
squash | one conventional commit per feature |
dev โ main |
squash | one commit for semantic-release to evaluate |
main โ dev (sync) |
merge commit, direct push | syncs stable metadata; [skip ci] in the release commit prevents a spurious RC |
Never edit a version in pyproject.toml or create a tag by hand: semantic-release does both.
Commit convention¶
[emoji] <type>[(<scope>)][!]: <description>, the emoji is optional (Gitmoji).
| Emoji | Type | Aliases | Release |
|---|---|---|---|
| ๐ | fix |
bugfix, hotfix |
patch |
| โก๏ธ | perf |
patch | |
| โจ | feat |
feature |
minor |
| ๐ฅ | feat! |
BREAKING CHANGE: footer |
major |
| โป๏ธ ๐ ๐จ ๐งช ๐ง ๐ท ๐ฆ | refactor, docs, style, test, chore, ci, build |
none |
A ! or a BREAKING CHANGE: footer makes any allowed type a breaking change (major release).
โจ feat(auth): add GitHub App token rotation
๐ fix(llm): handle empty response from the API
๐ฅ feat!(api): remove the v1 endpoint
feat(auth): redesign token flow
BREAKING CHANGE: /v1/token removed, use /v2/auth instead
On dev, a releasable commit increments the release-candidate counter (1.1.0-rc.1 โ 1.1.0-rc.2)
unless a larger bump is needed (for example, a breaking change โ 2.0.0-rc.1 when the last stable
release was 1.0.0).
Scopes are optional. Common scopes: tui, wsl, chezmoi, frontend, ci, deps. The commit message is checked on commit
(commitizen) and the pull request title by ci.yml.
Secrets¶
- Never write a credential to a file of this public repository, even untracked; use environment variables or
gh auth login. detect-secretsruns on commit. For a line that intentionally references a secret placeholder (${{ secrets.X }}), add# pragma: allowlist secret. Keep suppressions inline; never exclude a whole file to silence one line.
Environment variables¶
Adding, renaming or removing one, in the same change: the setting in settings.py, and the workflow env: if CI
needs it.
Update the release credentials if a release target reads it.
Dependencies (Renovate)¶
Renovate (.github/renovate.json) opens pull requests to dev with the renovate and dependencies labels;
most routine updates have a 7-day cooldown; security fixes are not grouped and open at once. Runtime
dependencies include exact pins and ranges; uv.lock makes builds reproducible. Review every Renovate
pull request; a dependency dashboard issue lists the pending ones.
- Renovate does not widen the Python range. The supported interpreter moves by hand, together with the CI action and this document.
- PyPI updates use strict Python compatibility filtering. Weekly lockfile maintenance refreshes versions already permitted by dependency ranges; review the lockfile and CI results too.
- Renovate updates dependency files, GitHub Actions and pre-commit revisions; update README and developer documentation when the supported Python range changes. Docs are not rewritten automatically.
- Renovate tracks the Node pin used by pre-commit. Stable updates wait seven days and use
chore; major upgrades require dependency dashboard approval.