Skeleton setup for a repository that uses Python invoke tasks, reusable modules, uv for environment/dependency management, and AI Copilot prompts and instructions. Drop this into any project to get a consistent git workflow, linting, and session logging out of the box.
./setup.shCreates a .venv with uv and installs dependencies. Update properties.yml with the local repo
path before running tasks.
pyproject.toml # Dependencies (Python >=3.14), ruff/pylint config
invoke.yml # Invoke config (auto_dash_names: false)
setup.sh # Initial environment setup (uv venv + uv sync)
properties.yml # Project configuration (repo path/remote, skeleton path/remote)
modules/
common/ # cli.py, properties.py, utils.py — shared helpers
repo/ # pull.py, push.py, log.py, squash.py, rebase.py, pr.py — git/PR workflow modules
claude/ # sync.py — syncs .claude/commands/ from .github/prompts/
skeleton/ # sync.py — locates the shared skeleton repo for /sync-setup
versioning/ # lib.py, workflows.py — check pyproject.toml deps & workflow action refs vs. latest releases
tasks/
__init__.py # Wires the invoke Collection (claude, repo, ruff, skeleton, tests, uv, versioning, fix, test)
claude.py # claude.sync
repo.py # repo.pull, repo.push, repo.log, repo.squash, repo.rebase, repo.pr_diff, repo.pr_notes_save, repo.pr_create
ruff.py # ruff.fix, ruff.format
skeleton.py # skeleton.locate_source
tests.py # tests.actionlint, tests.pylint, tests.rufflint, tests.yamllint
uv.py # uv.upgrade
versioning.py # versioning.libs, versioning.workflows, versioning.all
combos.py # Top-level aliases: fix, test
.github/
instructions/ # Copilot instructions per concern
prompts/ # /push, /pull, /squash, /rebase, /fix, /test, /setup, /pr-notes, /pr, /punch-it-chewy, /sync-setup, /versioning — source of truth
workflows/
tests.yml # Reusable CI: ruff + pylint + yamllint + actionlint
feature_branches.yml # Runs tests.yml on pull_request
protected_branches.yml # Runs tests.yml on push to main
.claude/
commands/ # Claude Code slash commands, mirrored from .github/prompts/
.vscode/
extensions.json # Recommended VS Code extensions
settings.json # Ruff formatter + Python interpreter settings
addons/
shopfiy_dawn_theme/ # Shopify Dawn theme addon — see Addons below before using
uv run --no-sync invoke # List all available tasks
uv run --no-sync invoke test # Ruff + Pylint + yamllint + actionlint
uv run --no-sync invoke fix # Ruff autocorrect + format
uv run --no-sync invoke repo.pull # Pull from git remote (stash → pull --rebase → restore)
uv run --no-sync invoke repo.push # Push to git remote (fix → test → commit → push)
uv run --no-sync invoke repo.log # Save a session log to logs/
uv run --no-sync invoke repo.squash # Anchored squash all commits to root + optional force push
uv run --no-sync invoke repo.rebase # Rebase onto remote default branch (optionally squash first)
uv run --no-sync invoke repo.pr_diff # Print current branch's commit log/diff vs. its base branch
uv run --no-sync invoke repo.pr_notes_save # Save PR notes to tmp/pull_requests/ (--content=...)
uv run --no-sync invoke repo.pr_create # Open a GitHub PR via gh (--title=... --content=...)
uv run --no-sync invoke claude.sync # Sync .claude/commands/ from .github/prompts/ (additive; --force to overwrite)
uv run --no-sync invoke skeleton.locate_source # Resolve the shared skeleton repo's path for /sync-setup
uv run --no-sync invoke versioning.libs # Check pyproject.toml deps vs. latest releases, update version locks
uv run --no-sync invoke versioning.workflows # Check .github/workflows/ action refs vs. latest majors, update pins
uv run --no-sync invoke versioning.all # Run every version check (libs, workflows)
uv run --no-sync invoke uv.upgrade # Install the versions currently locked in pyproject.toml (uv sync)| Prompt | Command | Description |
|---|---|---|
/push |
uv run --no-sync invoke repo.push |
Fix, test, commit, and push to git |
/pull |
uv run --no-sync invoke repo.pull |
Stash, pull latest, restore stash |
/squash |
uv run --no-sync invoke repo.squash |
Anchored squash all commits to root |
/rebase |
uv run --no-sync invoke repo.rebase |
Rebase onto remote default branch |
/fix |
uv run --no-sync invoke fix |
Auto-fix Python linting issues |
/test |
uv run --no-sync invoke test |
Run all tests and linters |
/setup |
./setup.sh |
Run initial project setup |
/pr-notes |
uv run --no-sync invoke repo.pr_diff |
Draft PR notes vs. base branch; saves to tmp/pull_requests/ when run standalone |
/pr |
uv run --no-sync invoke repo.pr_create |
Draft PR notes and open a Pull Request via gh (does not push) |
/punch-it-chewy |
— | Push, then draft notes and open a Pull Request |
/sync-setup |
uv run --no-sync invoke skeleton.locate_source |
Pull shared tooling updates from the template_python skeleton repo into this project |
/versioning |
uv run --no-sync invoke versioning.all |
Check pyproject.toml deps and workflow action refs vs. latest releases, update locks (does not install or run) |
| Module | Purpose |
|---|---|
modules/common/ |
CLI helpers, properties.yml config reader, output/utility helpers |
modules/repo/ |
Git workflow and session logging |
modules/claude/ |
Sync .claude/commands/ from .github/prompts/ source of truth |
modules/skeleton/ |
Locate the shared skeleton repo for /sync-setup |
modules/versioning/ |
Check pyproject.toml deps and workflow action refs vs. latest releases, update locks |
See modules/README.md for full details.
Optional, project-specific extensions live under addons/<name>/ and mirror the root layout
(modules/, tasks/, .github/, .claude/). They are not usable from inside
template_python — they only work once their files are copied into the consuming repo's
actual root, merged with what's already there, because they:
- Import via root-relative paths (e.g.
from modules.dawn import list) - Have
applyToinstruction globs written for a root-level path (e.g.modules/dawn/**) - Need their
tasks/*.pytask module wired into that repo'stasks/__init__.pyCollectionby hand — nothing here auto-discovers them
They're excluded from ruff/pylint here (pyproject.toml extend-exclude/ignore-paths) since
they aren't meant to lint clean from this repo's root.
| Addon | Adds | Move these files to the consuming repo's root |
|---|---|---|
addons/shopfiy_dawn_theme/ |
dawn.list / dawn.upgrade invoke tasks for tracking and staging upstream Shopify/dawn theme upgrades |
modules/dawn/ (__init__.py, list.py, upgrade.py, README.md), tasks/dawn.py, .github/workflows/{deploy,promote,release,tests,upgrade}.yml, .github/instructions/dawn.instructions.md, .github/prompts/dawn.prompt.md, .claude/commands/dawn.md |
GitHub Actions runs Ruff, Pylint, yamllint, and actionlint on every push and pull request via
.github/workflows/tests.yml (invoked by feature_branches.yml and protected_branches.yml).