From f478096bc2e2caaac7c20a44fecf397fd0ff6393 Mon Sep 17 00:00:00 2001 From: Louis King Date: Wed, 11 Feb 2026 00:01:51 +0000 Subject: [PATCH] Add Claude Code skills for git branching, PRs, and releases --- .claude/skills/git-branch/SKILL.md | 49 +++++++++++++ .claude/skills/git-pr/SKILL.md | 94 ++++++++++++++++++++++++ .claude/skills/release/SKILL.md | 114 +++++++++++++++++++++++++++++ 3 files changed, 257 insertions(+) create mode 100644 .claude/skills/git-branch/SKILL.md create mode 100644 .claude/skills/git-pr/SKILL.md create mode 100644 .claude/skills/release/SKILL.md diff --git a/.claude/skills/git-branch/SKILL.md b/.claude/skills/git-branch/SKILL.md new file mode 100644 index 0000000..b83d3e1 --- /dev/null +++ b/.claude/skills/git-branch/SKILL.md @@ -0,0 +1,49 @@ +--- +name: git-branch +description: Create a new branch from latest main with the project's naming convention (feat/fix/chore). Use when starting new work on a feature, bug fix, or chore. +--- + +# Git Branch + +Create a new branch from the latest `main` branch using the project's naming convention. + +## Arguments + +The user may provide arguments in the format: `/` + +- `type` — one of `feat`, `fix`, or `chore` +- `description` — short kebab-case description (e.g., `add-map-clustering`) + +If not provided, ask the user for the branch type and description. + +## Process + +1. **Fetch latest main:** + +```bash +git fetch origin main +``` + +2. **Determine branch name:** + + - If the user provided arguments (e.g., `/git-branch feat/add-map-clustering`), use them directly. + - Otherwise, ask the user for: + - **Branch type**: `feat`, `fix`, or `chore` + - **Short description**: a brief kebab-case slug describing the work + - Construct the branch name as `{type}/{slug}` (e.g., `feat/add-map-clustering`). + +3. **Create and switch to the new branch:** + +```bash +git checkout -b {branch_name} origin/main +``` + +4. **Confirm** by reporting the new branch name to the user. + +## Rules + +- Branch names MUST follow the `{type}/{slug}` convention. +- Valid types are `feat`, `fix`, and `chore` only. +- The slug MUST be kebab-case (lowercase, hyphens, no spaces or underscores). +- Always branch from `origin/main`, never from the current branch. +- Do NOT push the branch — just create it locally. diff --git a/.claude/skills/git-pr/SKILL.md b/.claude/skills/git-pr/SKILL.md new file mode 100644 index 0000000..b4268eb --- /dev/null +++ b/.claude/skills/git-pr/SKILL.md @@ -0,0 +1,94 @@ +--- +name: git-pr +description: Create a pull request to main from the current branch. Runs quality checks, commits changes, pushes, and opens a PR via gh CLI. Use when ready to submit work for review. +--- + +# Git PR + +Create a pull request to `main` from the current feature branch. + +## Process + +### Phase 1: Pre-flight Checks + +1. **Verify branch:** + +```bash +git branch --show-current +``` + + - The current branch must NOT be `main`. If on `main`, tell the user to create a feature branch first (e.g., `/git-branch`). + +2. **Check for uncommitted changes:** + +```bash +git status +``` + + - If there are uncommitted changes, ask the user for a commit message and commit them using the `/git-commit` skill conventions (no Claude authoring details). + +### Phase 2: Quality Checks + +1. **Determine changed components** by comparing against `main`: + +```bash +git diff --name-only main...HEAD +``` + +2. **Run targeted tests** based on changed files: + - `tests/test_web/` for web-only changes (templates, static JS, web routes) + - `tests/test_api/` for API changes + - `tests/test_collector/` for collector changes + - `tests/test_interface/` for interface/sender/receiver changes + - `tests/test_common/` for common models/schemas/config changes + - Run the full `pytest` if changes span multiple components + +3. **Run pre-commit checks:** + +```bash +pre-commit run --all-files +``` + + - If checks fail and auto-fix files, commit the fixes and re-run until clean. + +4. If tests or checks fail and cannot be auto-fixed, report the issues to the user and stop. + +### Phase 3: Push and Create PR + +1. **Push the branch to origin:** + +```bash +git push -u origin HEAD +``` + +2. **Generate PR content:** + - **Title**: Derive from the branch name. Convert `feat/add-map-clustering` to `Add map clustering`, `fix/login-error` to `Fix login error`, etc. Keep under 70 characters. + - **Body**: Generate a summary from the commit history: + +```bash +git log main..HEAD --oneline +``` + +3. **Create the PR:** + +```bash +gh pr create --title "{title}" --body "$(cat <<'EOF' +## Summary +{bullet points summarizing the changes} + +## Test plan +{checklist of testing steps} +EOF +)" +``` + +4. **Return the PR URL** to the user. + +## Rules + +- Do NOT create a PR from `main`. +- Do NOT skip quality checks — tests and pre-commit must pass. +- Do NOT force-push. +- Always target `main` as the base branch. +- Keep the PR title concise (under 70 characters). +- If quality checks fail, fix issues or report to the user — do NOT create the PR with failing checks. diff --git a/.claude/skills/release/SKILL.md b/.claude/skills/release/SKILL.md new file mode 100644 index 0000000..f7d4cfd --- /dev/null +++ b/.claude/skills/release/SKILL.md @@ -0,0 +1,114 @@ +--- +name: release +description: Full release workflow — quality gate, semantic version tag, push, and GitHub release. Use when ready to cut a new release from main. +--- + +# Release + +Run the full release workflow: quality checks, version tagging, push, and GitHub release creation. + +## Arguments + +The user may optionally provide a version number (e.g., `/release 1.2.0`). If not provided, one will be suggested based on commit history. + +## Process + +### Phase 1: Pre-flight Checks + +1. **Verify on `main` branch:** + +```bash +git branch --show-current +``` + + - Must be on `main`. If not, tell the user to switch to `main` first. + +2. **Verify working tree is clean:** + +```bash +git status --porcelain +``` + + - If there are uncommitted changes, tell the user to commit or stash them first. + +3. **Pull latest:** + +```bash +git pull origin main +``` + +### Phase 2: Quality Gate + +1. **Run full test suite:** + +```bash +pytest +``` + +2. **Run pre-commit checks:** + +```bash +pre-commit run --all-files +``` + +3. If either fails, report the issues and stop. Do NOT proceed with a release that has failing checks. + +### Phase 3: Determine Version + +1. **Get the latest tag:** + +```bash +git describe --tags --abbrev=0 2>/dev/null || echo "none" +``` + +2. **List commits since last tag:** + +```bash +git log {last_tag}..HEAD --oneline +``` + + If no previous tag exists, list the last 20 commits: + +```bash +git log --oneline -20 +``` + +3. **Determine next version:** + - If the user provided a version, use it. + - Otherwise, suggest a version based on commit prefixes: + - Any commit starting with `feat` or `Add` → **minor** bump + - Only `fix` or `Fix` commits → **patch** bump + - If no previous tag, suggest `0.1.0` + - Present the suggestion and ask the user to confirm or provide a different version. + +### Phase 4: Tag and Release + +1. **Create annotated tag:** + +```bash +git tag -a v{version} -m "Release v{version}" +``` + +2. **Push tag to origin:** + +```bash +git push origin v{version} +``` + +3. **Create GitHub release:** + +```bash +gh release create v{version} --title "v{version}" --generate-notes +``` + +4. **Report** the release URL to the user. + +## Rules + +- MUST be on `main` branch with a clean working tree. +- MUST pass all quality checks before tagging. +- Tags MUST follow the `v{major}.{minor}.{patch}` format (e.g., `v1.2.0`). +- Always create an annotated tag, not a lightweight tag. +- Always confirm the version with the user before tagging. +- Do NOT skip quality checks under any circumstances. +- Do NOT force-push tags.