From 2ea2bfcc1518077e793f5be65cfd586ca5702acc Mon Sep 17 00:00:00 2001 From: Jacob Dahl Date: Tue, 17 Mar 2026 18:54:50 -0800 Subject: [PATCH] ci(claude): add Claude Code skills for commit, pr, and rebase Add reusable skill definitions for common contributor workflows: - commit: creates conventional commits with proper type(scope) format - pr: creates PRs with conventional commit titles - rebase-onto-main: handles rebasing onto main when parent branches were squash-merged --- .claude/skills/commit/SKILL.md | 34 +++++++++++ .claude/skills/pr/SKILL.md | 22 +++++++ .claude/skills/rebase-onto-main/SKILL.md | 73 ++++++++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 .claude/skills/commit/SKILL.md create mode 100644 .claude/skills/pr/SKILL.md create mode 100644 .claude/skills/rebase-onto-main/SKILL.md diff --git a/.claude/skills/commit/SKILL.md b/.claude/skills/commit/SKILL.md new file mode 100644 index 0000000000..78d3db5f62 --- /dev/null +++ b/.claude/skills/commit/SKILL.md @@ -0,0 +1,34 @@ +--- +name: commit +description: Create a conventional commit for PX4 changes +disable-model-invocation: true +argument-hint: "[optional: description of changes]" +allowed-tools: Bash, Read, Glob, Grep +--- + +# PX4 Conventional Commit + +Create a git commit: `type(scope): description` + +**NEVER add Co-Authored-By lines. No Claude attribution in commits.** + +## Steps + +1. Check branch (`git branch --show-current`). If on `main`, create a feature branch. Use `/` format where `` comes from `gh api user --jq .login`. If unavailable, just use ``. +2. Run `git status` and `git diff --staged`. If nothing staged, ask what to stage. +3. Pick **type**: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert` +4. Pick **scope** from changed file paths (e.g. `ekf2`, `mavlink`, `sensors`). +5. Write concise imperative description, lowercase, no period, under 72 chars. +6. Breaking changes: `type(scope)!: description` +7. Body (if needed): explain **why**, not what. +8. Stage and commit. No `Co-Authored-By`. + +## Examples + +``` +feat(ekf2): add height fusion timeout +fix(mavlink): correct BATTERY_STATUS_V2 parsing +refactor(navigator): simplify RTL altitude logic +``` + +If the user provided arguments, use them as context: $ARGUMENTS diff --git a/.claude/skills/pr/SKILL.md b/.claude/skills/pr/SKILL.md new file mode 100644 index 0000000000..09463d89e6 --- /dev/null +++ b/.claude/skills/pr/SKILL.md @@ -0,0 +1,22 @@ +--- +name: pr +description: Create a pull request with conventional commit title and description +disable-model-invocation: true +argument-hint: "[optional: target branch or description]" +allowed-tools: Bash, Read, Glob, Grep +--- + +# PX4 Pull Request + +**No Claude attribution anywhere (no Co-Authored-By, no "Generated with Claude").** + +## Steps + +1. Check branch. If on `main`, create a feature branch. Use `/` format where `` comes from `gh api user --jq .login`. If unavailable, just use ``. +2. Gather context: `git status`, `git log --oneline main..HEAD`, `git diff main...HEAD --stat`, check if remote tracking branch exists. +3. PR **title**: `type(scope): description` — under 72 chars, describes the overall change across all commits. This becomes the squash-merge commit message. +4. PR **body**: brief summary + bullet points for key changes. No filler. +5. Push with `-u` if needed, then `gh pr create`. Default base is `main` unless user says otherwise. +6. Return the PR URL. + +If the user provided arguments, use them as context: $ARGUMENTS diff --git a/.claude/skills/rebase-onto-main/SKILL.md b/.claude/skills/rebase-onto-main/SKILL.md new file mode 100644 index 0000000000..04e57882f2 --- /dev/null +++ b/.claude/skills/rebase-onto-main/SKILL.md @@ -0,0 +1,73 @@ +--- +name: rebase-onto-main +description: Rebase a branch onto main, handling squash-merged parent branches cleanly +argument-hint: "[optional: branch name, defaults to current branch]" +allowed-tools: Bash, Read, Glob, Grep, Agent +--- + +# Rebase Branch onto Main + +Rebase the current (or specified) branch onto `main`, correctly handling the case where the branch was built on top of another branch that has since been squash-merged into `main`. + +## Background + +When a parent branch is squash-merged, its individual commits become a single new commit on `main` with a different hash. A normal `git rebase main` will try to replay the parent's original commits, causing messy conflicts. The fix is to **cherry-pick only the commits unique to this branch** onto a fresh branch from `main`. + +## Steps + +1. **Identify the branch.** Use `$ARGUMENTS` if provided, otherwise use the current branch. + +2. **Fetch and update main:** + ``` + git fetch origin main:main + ``` + +3. **Find the merge base** between the branch and `main`: + ``` + git merge-base main + ``` + +4. **List all commits** on the branch since the merge base: + ``` + git log --oneline .. + ``` + +5. **Identify which commits are unique to this branch** vs. inherited from a parent branch. Look for: + - Squash-merged commits on `main` that correspond to a group of commits at the bottom of the branch's history (check PR titles, commit message keywords). + - The boundary commit: the first commit that belongs to *this* branch's work, not the parent's. + - If ALL commits are unique (no parent branch), just do a normal `git rebase main` and skip the rest. + +6. **Create a fresh branch from `main`:** + ``` + git checkout -b -rebase main + ``` + +7. **Cherry-pick only the unique commits** (oldest first): + ``` + git cherry-pick ^.. + ``` + The `A^..B` range means "from the parent of A through B inclusive." + +8. **Handle conflicts** if any arise during cherry-pick. Resolve and `git cherry-pick --continue`. + +9. **Replace the old branch:** + ``` + git branch -m -old + git branch -m -rebase + ``` + +10. **Verify** the result: + ``` + git log --oneline main.. + ``` + Confirm only the expected commits are present. + +11. **Ask the user** before force-pushing. When approved: + ``` + git push origin --force-with-lease + ``` + +12. **Clean up** the old branch: + ``` + git branch -D -old + ```