A Copier project template that
bootstraps repos with a complete set of standardized conventions: go-task
Taskfile, lefthook git hooks, conventional commits, GitHub Actions CI (with
Claude Code plan/implement/review workflows), gitleaks/snyk/CodeQL security,
Renovate, CodeRabbit, a dual-profile devcontainer (AI bot + human) with GHCR
prebuilds, a docs tree, and AI steering docs (canonical AGENTS.md). It can
also be applied to existing repos to standardize them.
Author: Evan Harmon
This repo is part of harmon-stack — my personal stack of homelab, dev-tooling, and automation repos that work together.
| Repo | What it is |
|---|---|
| harmon-init (this repo) | Copier template that bootstraps & standardizes new repos (CI/CD, devcontainers, AI steering, tooling). |
| harmon-devkit | Reusable boilerplates & code templates, standalone scripts, and AI assets (skills, prompts, agents). |
| harmon-dotfiles | Shell & app dotfiles, managed declaratively with chezmoi. |
| harmon-ops | Personal machine bootstrapping, package management & dev-environment setup across macOS/Windows/Linux. |
| harmon-infra | Homelab infrastructure as code — Terraform, Ansible, and Docker Compose services. |
copier copy harmon-init new-project --trustKey questions: project_type (general | web-astro | web-app | iac | docs),
github_org, ci_runner (ubuntu-latest | self-hosted), devcontainer,
include_terraform / include_ansible, license. Hidden defaults (author
identity, org info, directories) live in copier.yml under when: false —
customize those once before first use.
After generation, work through the project's docs/CHECKLIST.md (branch
ruleset import, Dependabot alerts, Renovate/CodeRabbit apps, Actions secrets,
framework scaffolding for web projects).
cd existing-project
copier update --trust # if it was generated from this template
# or adopt the template in a repo that wasn't:
copier copy --trust ~/git/harmon-init . --vcs-ref=HEADcopier copy from a local path renders the latest git tag by default —
NOT your working tree. When testing template changes, always pass
--vcs-ref=HEAD. With it, copier auto-includes dirty/untracked changes via a
throwaway commit in a temp clone (DirtyLocalWarning); your working tree is
never touched. task test:template handles this for you.
- Root — tooling for maintaining the template itself (this Taskfile, lefthook, CI). The root dogfoods the same conventions the template generates.
template/— the Copier template root (_subdirectory: template). Everything here becomes the generated project.
Template files use [[ var ]] and [% if x %] (set via _envops in
copier.yml) so GitHub Actions ${{ }}, go-task {{.VAR}}, and lefthook
{staged_files} appear verbatim with zero escaping. Rules of thumb:
- Never use bash
[[ ]]tests inside.jinjafiles — use[ ]. - An inline
[% endif %]at end-of-line eats the next newline (trim_blocks) — write[% endif +%]. - Shell scripts that don't need substitution stay plain (not
.jinja).
task verify # lint + full generation matrix
task test:template # all answer profiles (minimal/web/iac/full)
task test:template:web # one profileEach profile renders into a temp dir and validates the output: symlinks
(CLAUDE.md/GEMINI.md → AGENTS.md), Taskfile parses, no leaked copier
variables, actionlint, yamllint, lefthook config, shellcheck/shfmt on
rendered scripts, JSON validity, devcontainer read-configuration (CI), and
gitleaks. CI runs the same matrix on every PR (template-test jobs in
build.yml).
Releases are intentional — task release:patch|minor|major. Nothing
auto-releases on merge to main. Generated projects render from the latest
tag, so tag a release after merging template changes you want consumers
to receive.
v3.0.0 was a breaking redesign: new question set (project_type,
github_org, ci_runner, ...), custom jinja delimiters, lefthook+gitleaks
replacing pre-commit+whispers, manual releases, dual-profile devcontainer,
and canonical AGENTS.md. Projects generated from v2 should be re-templated
(copier copy over the repo and reconcile) rather than copier updated.
| Command | What it does |
|---|---|
task verify |
Lint + template generation matrix (merge gate) |
task check |
Root linters (template/ excluded — jinja isn't valid YAML) |
task security:secrets |
gitleaks scan |
task install |
Brewfile deps + lefthook hooks |
task release:patch |
Tag + GitHub release (also :minor/:major) |