|
| 1 | +--- |
| 2 | +name: commit-message |
| 3 | +description: This skill should be used when the user asks to "create a commit", "generate commit message", "commit changes", "make a commit", mentions "conventional commits", or discusses commit message formatting. Provides guided workflow for creating properly formatted commit messages with line length validation and required trailers. |
| 4 | +version: 0.2.0 |
| 5 | +--- |
| 6 | + |
| 7 | +# Conventional Commit Message Creation |
| 8 | + |
| 9 | +Create properly formatted conventional commit messages following project standards with line length validation and required trailers. |
| 10 | + |
| 11 | +## Purpose |
| 12 | + |
| 13 | +Generate commit messages that: |
| 14 | + |
| 15 | +- Follow conventional commits format (`type(scope): description`) |
| 16 | +- Use component names or GitHub issue numbers as scope |
| 17 | +- Respect line length limits (50 for subject, 72 for body) |
| 18 | +- Include required trailers (Signed-off-by, Assisted-by) |
| 19 | +- Follow the validation rules below |
| 20 | + |
| 21 | +## Quick Workflow |
| 22 | + |
| 23 | +1. **Analyze changes**: Run git status and git diff to understand modifications |
| 24 | +2. **Determine scope**: Use component name from changed files, or GitHub issue number if available |
| 25 | +3. **Generate message**: Create conventional commit message with proper formatting |
| 26 | +4. **Add trailers**: Include Signed-off-by and Assisted-by trailers |
| 27 | +5. **Confirm with user**: Display message and wait for approval before committing |
| 28 | + |
| 29 | +**CRITICAL**: Never commit without explicit user confirmation. |
| 30 | + |
| 31 | +## Conventional Commit Format |
| 32 | + |
| 33 | +### Structure |
| 34 | + |
| 35 | +```text |
| 36 | +<type>(<scope>): <description> |
| 37 | +
|
| 38 | +[optional body] |
| 39 | +
|
| 40 | +Signed-off-by: <name> <email> |
| 41 | +Assisted-by: <model-name> (via Cursor) |
| 42 | +``` |
| 43 | + |
| 44 | +### Type Selection |
| 45 | + |
| 46 | +Choose the appropriate commit type based on changes: |
| 47 | + |
| 48 | +| Type | Description | Example | |
| 49 | +| ------ | ------------- | --------- | |
| 50 | +| `feat` | New features | `feat(pipeline): add start --output flag` | |
| 51 | +| `fix` | Bug fixes | `fix(taskrun): resolve log streaming race` | |
| 52 | +| `docs` | Documentation | `docs(README): update installation steps` | |
| 53 | +| `refactor` | Code refactoring | `refactor(actions): simplify CRUD helpers` | |
| 54 | +| `test` | Test changes | `test(pipelinerun): add describe unit tests` | |
| 55 | +| `chore` | Maintenance | `chore(deps): update go dependencies` | |
| 56 | +| `build` | Build system | `build(Makefile): add vendor target` | |
| 57 | +| `ci` | CI/CD changes | `ci(github): add golangci-lint action` | |
| 58 | +| `perf` | Performance | `perf(log): optimize pod log streaming` | |
| 59 | +| `style` | Code style | `style(format): run goimports formatter` | |
| 60 | +| `revert` | Revert commit | `revert: undo breaking CLI flag change` | |
| 61 | + |
| 62 | +For complete type reference, see `references/commit-types.md`. |
| 63 | + |
| 64 | +### Scope Rules |
| 65 | + |
| 66 | +#### Priority 1: Component from changed files |
| 67 | + |
| 68 | +Analyze staged files to identify the primary component: |
| 69 | + |
| 70 | +```bash |
| 71 | +git diff --cached --name-only |
| 72 | +``` |
| 73 | + |
| 74 | +| File pattern | Scope | Example commit | |
| 75 | +| ------------ | ----- | -------------- | |
| 76 | +| `pkg/cmd/pipeline/*` | `pipeline` | `feat(pipeline): add start --dry-run flag` | |
| 77 | +| `pkg/cmd/task/*` | `task` | `fix(task): resolve list filtering` | |
| 78 | +| `pkg/cmd/pipelinerun/*` | `pipelinerun` | `feat(pipelinerun): add cancel subcommand` | |
| 79 | +| `pkg/cmd/taskrun/*` | `taskrun` | `fix(taskrun): correct log streaming` | |
| 80 | +| `pkg/actions/*` | `actions` | `refactor(actions): simplify CRUD` | |
| 81 | +| `pkg/formatted/*` | `formatted` | `feat(formatted): add JSON output` | |
| 82 | +| `pkg/log/*` | `log` | `fix(log): handle container restart` | |
| 83 | +| `pkg/pods/*` | `pods` | `fix(pods): resolve container lookup` | |
| 84 | +| `pkg/cli/*` | `cli` | `refactor(cli): extract client setup` | |
| 85 | +| `pkg/flags/*` | `flags` | `feat(flags): add --output flag` | |
| 86 | +| `pkg/plugins/*` | `plugins` | `feat(plugins): add discovery logic` | |
| 87 | +| `pkg/version/*` | `version` | `fix(version): correct server detection` | |
| 88 | +| `docs/*` | `docs` or filename | `docs(README): update steps` | |
| 89 | +| `test/*` | component being tested | `test(pipeline): add E2E tests` | |
| 90 | +| `cmd/*` | command name | `feat(tkn): add new subcommand` | |
| 91 | +| Root files | filename | `chore(Makefile): add target` | |
| 92 | +| `AGENTS.md`, `CLAUDE.md` | `docs` | `docs(AGENTS.md): update conventions` | |
| 93 | + |
| 94 | +#### Priority 2: GitHub issue number (optional) |
| 95 | + |
| 96 | +If the work is tracked in a GitHub issue and the user provides one, it can be used as the scope: |
| 97 | + |
| 98 | +```text |
| 99 | +# Branch: fix-123-log-race |
| 100 | +# Scope: #123 or component name |
| 101 | +# Result: fix(log): resolve streaming race condition |
| 102 | +
|
| 103 | +Fixes #123 |
| 104 | +``` |
| 105 | + |
| 106 | +Add `Fixes #NNN` or `Closes #NNN` in the commit body (not the scope) — this is the standard GitHub convention for auto-closing issues. |
| 107 | + |
| 108 | +#### Priority 3: Ask user |
| 109 | + |
| 110 | +If changed files span multiple components or scope is unclear, ask the user which component is the primary focus. |
| 111 | + |
| 112 | +## Line Length Requirements |
| 113 | + |
| 114 | +### Subject Line |
| 115 | + |
| 116 | +- **Target**: 50 characters maximum |
| 117 | +- **Hard limit**: 72 characters |
| 118 | +- **Format**: `type(scope): description` counts toward limit |
| 119 | +- **Tips**: Use present tense, no period at end |
| 120 | + |
| 121 | +```text |
| 122 | +# Good (40 chars) |
| 123 | +feat(pipeline): add start --dry-run |
| 124 | +
|
| 125 | +# Too long - exceeds 72 char hard limit |
| 126 | +feat(pipeline): add comprehensive dry-run support with preview output for pipeline start command |
| 127 | +``` |
| 128 | + |
| 129 | +### Body |
| 130 | + |
| 131 | +- **Wrap at 72 characters per line** |
| 132 | +- **Blank line** required between subject and body |
| 133 | +- **Content**: Explain why, not what (code shows what) |
| 134 | +- **Format**: Wrap manually or use heredoc in git commit |
| 135 | + |
| 136 | +```text |
| 137 | +feat(pipeline): add start --dry-run |
| 138 | +
|
| 139 | +Add dry-run flag to pipeline start command that previews the |
| 140 | +PipelineRun YAML without creating it. Useful for validating |
| 141 | +parameters and workspace bindings before submission. |
| 142 | +
|
| 143 | +Signed-off-by: Developer Name <developer@example.com> |
| 144 | +Assisted-by: Claude Sonnet 4.5 (via Cursor) |
| 145 | +``` |
| 146 | + |
| 147 | +## Required Trailers |
| 148 | + |
| 149 | +### Signed-off-by |
| 150 | + |
| 151 | +**Always include**: `Signed-off-by: <name> <email>` |
| 152 | + |
| 153 | +This certifies the Developer Certificate of Origin (DCO) — required by tektoncd upstream. |
| 154 | + |
| 155 | +**Detection priority order**: |
| 156 | + |
| 157 | +1. Environment variables: `$GIT_AUTHOR_NAME` and `$GIT_AUTHOR_EMAIL` |
| 158 | +2. Git config: `git config user.name` and `git config user.email` |
| 159 | +3. If neither configured, ask user to provide details |
| 160 | + |
| 161 | +```bash |
| 162 | +echo "$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" |
| 163 | +git config user.name |
| 164 | +git config user.email |
| 165 | +``` |
| 166 | + |
| 167 | +If neither is configured, ask the user to provide their name and email. |
| 168 | + |
| 169 | +### Assisted-by |
| 170 | + |
| 171 | +**Always include**: `Assisted-by: <model-name> (via Cursor)` |
| 172 | + |
| 173 | +**Format examples**: |
| 174 | + |
| 175 | +```text |
| 176 | +Assisted-by: Claude Sonnet 4.5 (via Cursor) |
| 177 | +Assisted-by: Claude Opus 4.5 (via Cursor) |
| 178 | +``` |
| 179 | + |
| 180 | +Use the actual model name (Claude Sonnet 4.5, Claude Opus 4.5, etc.). |
| 181 | + |
| 182 | +## User Confirmation Requirement |
| 183 | + |
| 184 | +**CRITICAL RULE**: Always ask for user confirmation before executing `git commit`. |
| 185 | + |
| 186 | +### Confirmation Workflow |
| 187 | + |
| 188 | +1. **Generate** the commit message following all rules above |
| 189 | +2. **Display** the complete message to the user with separator |
| 190 | +3. **Ask**: "Should I commit with this message? (y/n)" |
| 191 | +4. **Wait** for user response |
| 192 | +5. **Commit** only if user confirms (yes/y/affirmative) |
| 193 | + |
| 194 | +### Example Interaction |
| 195 | + |
| 196 | +```text |
| 197 | +Generated commit message: |
| 198 | +--- |
| 199 | +feat(pipeline): add JSON output support |
| 200 | +
|
| 201 | +Add --output=json flag to pipeline list and describe commands. |
| 202 | +Uses the existing formatted package JSON helpers. |
| 203 | +
|
| 204 | +Signed-off-by: Developer Name <developer@example.com> |
| 205 | +Assisted-by: Claude Sonnet 4.5 (via Cursor) |
| 206 | +--- |
| 207 | +
|
| 208 | +Should I commit with this message? (y/n) |
| 209 | +``` |
| 210 | + |
| 211 | +Wait for user response before proceeding. |
| 212 | + |
| 213 | +## Commit Execution |
| 214 | + |
| 215 | +Use heredoc format for proper multi-line handling: |
| 216 | + |
| 217 | +```bash |
| 218 | +git commit -m "$(cat <<'EOF' |
| 219 | +feat(pipeline): add JSON output support |
| 220 | +
|
| 221 | +Add --output=json flag to pipeline list and describe commands. |
| 222 | +
|
| 223 | +Signed-off-by: Developer Name <developer@example.com> |
| 224 | +Assisted-by: Claude Sonnet 4.5 (via Cursor) |
| 225 | +EOF |
| 226 | +)" |
| 227 | +``` |
| 228 | + |
| 229 | +**Never use**: |
| 230 | + |
| 231 | +- `--no-verify` (skips pre-commit hooks) |
| 232 | +- `--no-gpg-sign` (skips signing) |
| 233 | +- `--amend` (unless explicitly requested and safe) |
| 234 | + |
| 235 | +## Complete Examples |
| 236 | + |
| 237 | +### Feature with component scope |
| 238 | + |
| 239 | +```text |
| 240 | +feat(pipeline): add start --dry-run |
| 241 | +
|
| 242 | +Add dry-run flag to pipeline start command that previews the |
| 243 | +PipelineRun YAML without creating it on the cluster. |
| 244 | +
|
| 245 | +Signed-off-by: Jane Developer <jane@example.com> |
| 246 | +Assisted-by: Claude Sonnet 4.5 (via Cursor) |
| 247 | +``` |
| 248 | + |
| 249 | +### Bug fix closing a GitHub issue |
| 250 | + |
| 251 | +```text |
| 252 | +fix(log): resolve concurrent streaming panic |
| 253 | +
|
| 254 | +Prevent nil pointer dereference when multiple containers stream |
| 255 | +logs simultaneously during a TaskRun. |
| 256 | +
|
| 257 | +Fixes #789 |
| 258 | +
|
| 259 | +Signed-off-by: John Developer <john@example.com> |
| 260 | +Assisted-by: Claude Sonnet 4.5 (via Cursor) |
| 261 | +``` |
| 262 | + |
| 263 | +### Documentation update |
| 264 | + |
| 265 | +```text |
| 266 | +docs(AGENTS.md): update architecture conventions |
| 267 | +
|
| 268 | +Add command tree structure and clarify golden-file testing |
| 269 | +rules for contributors. |
| 270 | +
|
| 271 | +Signed-off-by: Jane Developer <jane@example.com> |
| 272 | +Assisted-by: Claude Sonnet 4.5 (via Cursor) |
| 273 | +``` |
| 274 | + |
| 275 | +### Breaking change |
| 276 | + |
| 277 | +```text |
| 278 | +feat(cli)!: remove deprecated --namespace flag |
| 279 | +
|
| 280 | +Remove the deprecated short-form --namespace flag from all |
| 281 | +commands. Use -n instead. Deprecated since v0.30. |
| 282 | +
|
| 283 | +BREAKING CHANGE: Removed --namespace long flag from all |
| 284 | +commands. Use -n or --ns instead. |
| 285 | +
|
| 286 | +Signed-off-by: John Developer <john@example.com> |
| 287 | +Assisted-by: Claude Sonnet 4.5 (via Cursor) |
| 288 | +``` |
| 289 | + |
| 290 | +## Validation Rules |
| 291 | + |
| 292 | +Every commit message must pass these checks: |
| 293 | + |
| 294 | +1. **Subject line format**: Must match `type(scope): description` (conventional commits) |
| 295 | +2. **Subject line length**: Target 50 chars, hard limit 72 chars |
| 296 | +3. **No trailing punctuation**: Subject must not end with `.` `!` `?` `,` `:` `;` (exception: `!` for breaking changes like `feat!:`) |
| 297 | +4. **No trailing whitespace**: On any line |
| 298 | +5. **Blank line after subject**: Required before body text |
| 299 | +6. **Body line length**: Wrap at 72 characters per line |
| 300 | +7. **Valid commit type**: Must be one of: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`, `build`, `ci`, `perf`, `revert` |
| 301 | +8. **Signed-off-by trailer**: Required — `Signed-off-by: Name <email>` |
| 302 | +9. **Assisted-by trailer**: Required when AI assists — `Assisted-by: Model (via Tool)` |
| 303 | +10. **Trailer spacing**: Blank line before trailers, no blank lines between them, no trailing blank lines |
| 304 | + |
| 305 | +## Auto-Detection Summary |
| 306 | + |
| 307 | +When generating commit messages: |
| 308 | + |
| 309 | +1. Run `git status` (without -uall flag) |
| 310 | +2. Run `git diff` for staged and unstaged changes |
| 311 | +3. Identify primary component from staged file paths |
| 312 | +4. If scope unclear, ask user |
| 313 | +5. If user mentions a GitHub issue number, add `Fixes #NNN` to body |
| 314 | +6. Analyze staged files to determine commit type |
| 315 | +7. Generate appropriate scope and description |
| 316 | +8. Detect author info from environment variables or git config |
| 317 | +9. Ensure subject line is ≤50 characters (max 72) |
| 318 | +10. Wrap body text at 72 characters per line |
| 319 | +11. Add required trailers (Signed-off-by and Assisted-by) |
| 320 | +12. Format according to conventional commits standard |
| 321 | +13. **Display message and ask for user confirmation** |
| 322 | +14. Only commit after receiving confirmation |
| 323 | + |
| 324 | +## Additional Resources |
| 325 | + |
| 326 | +For detailed information: |
| 327 | + |
| 328 | +- **`references/commit-types.md`** - Complete commit type reference with descriptions |
0 commit comments