|
| 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 | +- Pass gitlint validation |
| 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 | +```text |
| 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(tektonpipeline): add HA support` | |
| 51 | +| `fix` | Bug fixes | `fix(reconciler): resolve race condition` | |
| 52 | +| `docs` | Documentation | `docs(README): update installation steps` | |
| 53 | +| `refactor` | Code refactoring | `refactor(installerset): simplify logic` | |
| 54 | +| `test` | Test changes | `test(tektonchain): add 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(cache): optimize lookup speed` | |
| 59 | +| `style` | Code style | `style(format): run fumpt formatter` | |
| 60 | +| `revert` | Revert commit | `revert: undo breaking API 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 | +# Get list of staged files |
| 72 | +git diff --cached --name-only |
| 73 | +```text |
| 74 | +
|
| 75 | +| File pattern | Scope | Example commit | |
| 76 | +| ------------ | ----- | -------------- | |
| 77 | +| `pkg/reconciler/kubernetes/tektonpipeline/*` | `tektonpipeline` | `fix(tektonpipeline): resolve status update` | |
| 78 | +| `pkg/reconciler/kubernetes/tektonchain/*` | `tektonchain` | `feat(tektonchain): add OCI support` | |
| 79 | +| `pkg/reconciler/openshift/*` | component name | `fix(tektondashboard): fix route creation` | |
| 80 | +| `pkg/reconciler/common/*` | `common` | `refactor(common): simplify installerset` | |
| 81 | +| `pkg/apis/*` | `api` | `feat(api): add new CRD field` | |
| 82 | +| `docs/*` | `docs` or filename | `docs(README): update steps` | |
| 83 | +| `test/*` | component being tested | `test(tektonchain): add unit tests` | |
| 84 | +| `cmd/*` | command name | `feat(operator): add new flag` | |
| 85 | +| Root files | filename | `chore(Makefile): add target` | |
| 86 | +| `AGENTS.md`, `CLAUDE.md` | `docs` | `docs(AGENTS.md): update conventions` | |
| 87 | +
|
| 88 | +#### Priority 2: GitHub issue number (optional) |
| 89 | +
|
| 90 | +If the work is tracked in a GitHub issue and the user provides one, it can be used as the scope: |
| 91 | +
|
| 92 | +```text |
| 93 | +# Branch: fix-123-installerset-race |
| 94 | +# Scope: #123 or component name |
| 95 | +# Result: fix(installerset): resolve race condition |
| 96 | +
|
| 97 | +Fixes #123 |
| 98 | +```text |
| 99 | +
|
| 100 | +Add `Fixes #NNN` or `Closes #NNN` in the commit body (not the scope) — this is the standard GitHub convention for auto-closing issues. |
| 101 | +
|
| 102 | +#### Priority 3: Ask user |
| 103 | +
|
| 104 | +If changed files span multiple components or scope is unclear, ask the user which component is the primary focus. |
| 105 | +
|
| 106 | +## Line Length Requirements |
| 107 | +
|
| 108 | +### Subject Line |
| 109 | +
|
| 110 | +- **Target**: 50 characters maximum |
| 111 | +- **Hard limit**: 72 characters (gitlint enforced) |
| 112 | +- **Format**: `type(scope): description` counts toward limit |
| 113 | +- **Tips**: Use present tense, no period at end |
| 114 | +
|
| 115 | +```text |
| 116 | +# Good (44 chars) |
| 117 | +feat(tektonpipeline): add HA support |
| 118 | +
|
| 119 | +# Too long - will fail gitlint |
| 120 | +feat(tektonpipeline): add comprehensive high-availability support for pipeline controller |
| 121 | +```text |
| 122 | +
|
| 123 | +### Body |
| 124 | +
|
| 125 | +- **Wrap at 72 characters per line** |
| 126 | +- **Blank line** required between subject and body |
| 127 | +- **Content**: Explain why, not what (code shows what) |
| 128 | +- **Format**: Wrap manually or use heredoc in git commit |
| 129 | +
|
| 130 | +```text |
| 131 | +feat(tektonpipeline): add HA support |
| 132 | +
|
| 133 | +Enable leader election in the pipeline reconciler to support |
| 134 | +high-availability deployments. This prevents split-brain issues |
| 135 | +when multiple operator replicas are running. |
| 136 | +
|
| 137 | +Signed-off-by: Developer Name <developer@example.com> |
| 138 | +Assisted-by: Claude Sonnet 4.5 (via Cursor) |
| 139 | +```text |
| 140 | +
|
| 141 | +## Required Trailers |
| 142 | +
|
| 143 | +### Signed-off-by |
| 144 | +
|
| 145 | +**Always include**: `Signed-off-by: <name> <email>` |
| 146 | +
|
| 147 | +This certifies the Developer Certificate of Origin (DCO) — required by tektoncd upstream. |
| 148 | +
|
| 149 | +**Detection priority order**: |
| 150 | +
|
| 151 | +1. Environment variables: `$GIT_AUTHOR_NAME` and `$GIT_AUTHOR_EMAIL` |
| 152 | +2. Git config: `git config user.name` and `git config user.email` |
| 153 | +3. If neither configured, ask user to provide details |
| 154 | +
|
| 155 | +```bash |
| 156 | +# Check environment variables first |
| 157 | +echo "$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" |
| 158 | +
|
| 159 | +# Fallback to git config |
| 160 | +git config user.name |
| 161 | +git config user.email |
| 162 | +```text |
| 163 | +
|
| 164 | +For complete detection logic, see `references/trailer-detection.md`. |
| 165 | +
|
| 166 | +### Assisted-by |
| 167 | +
|
| 168 | +**Always include**: `Assisted-by: <model-name> (via Cursor)` |
| 169 | +
|
| 170 | +**Format examples**: |
| 171 | +
|
| 172 | +```text |
| 173 | +Assisted-by: Claude Sonnet 4.5 (via Cursor) |
| 174 | +Assisted-by: Claude Opus 4.5 (via Cursor) |
| 175 | +```text |
| 176 | +
|
| 177 | +Use the actual model name (Claude Sonnet 4.5, Claude Opus 4.5, etc.). |
| 178 | +
|
| 179 | +## User Confirmation Requirement |
| 180 | +
|
| 181 | +**CRITICAL RULE**: Always ask for user confirmation before executing `git commit`. |
| 182 | +
|
| 183 | +### Confirmation Workflow |
| 184 | +
|
| 185 | +1. **Generate** the commit message following all rules above |
| 186 | +2. **Display** the complete message to the user with separator |
| 187 | +3. **Ask**: "Should I commit with this message? (y/n)" |
| 188 | +4. **Wait** for user response |
| 189 | +5. **Commit** only if user confirms (yes/y/affirmative) |
| 190 | +
|
| 191 | +### Example Interaction |
| 192 | +
|
| 193 | +```text |
| 194 | +Generated commit message: |
| 195 | +--- |
| 196 | +feat(tektonchain): add OCI bundle support |
| 197 | +
|
| 198 | +Enable storing Tekton Chains signatures in OCI registries. This |
| 199 | +allows signing artifacts without requiring a separate storage |
| 200 | +backend. |
| 201 | +
|
| 202 | +Signed-off-by: Developer Name <developer@example.com> |
| 203 | +Assisted-by: Claude Sonnet 4.5 (via Cursor) |
| 204 | +--- |
| 205 | +
|
| 206 | +Should I commit with this message? (y/n) |
| 207 | +```text |
| 208 | +
|
| 209 | +Wait for user response before proceeding. |
| 210 | +
|
| 211 | +## Commit Execution |
| 212 | +
|
| 213 | +Use heredoc format for proper multi-line handling: |
| 214 | +
|
| 215 | +```bash |
| 216 | +git commit -m "$(cat <<'EOF' |
| 217 | +feat(tektonchain): add OCI bundle support |
| 218 | +
|
| 219 | +Enable storing Tekton Chains signatures in OCI registries. |
| 220 | +
|
| 221 | +Signed-off-by: Developer Name <developer@example.com> |
| 222 | +Assisted-by: Claude Sonnet 4.5 (via Cursor) |
| 223 | +EOF |
| 224 | +)" |
| 225 | +```text |
| 226 | +
|
| 227 | +**Never use**: |
| 228 | +
|
| 229 | +- `--no-verify` (skips pre-commit hooks) |
| 230 | +- `--no-gpg-sign` (skips signing) |
| 231 | +- `--amend` (unless explicitly requested and safe) |
| 232 | +
|
| 233 | +## Complete Examples |
| 234 | +
|
| 235 | +### Feature with component scope |
| 236 | +
|
| 237 | +```text |
| 238 | +feat(tektonpipeline): add HA leader election |
| 239 | +
|
| 240 | +Enable leader election in the pipeline reconciler to support |
| 241 | +high-availability deployments with multiple operator replicas. |
| 242 | +
|
| 243 | +Signed-off-by: Jane Developer <jane@example.com> |
| 244 | +Assisted-by: Claude Sonnet 4.5 (via Cursor) |
| 245 | +```text |
| 246 | +
|
| 247 | +### Bug fix closing a GitHub issue |
| 248 | +
|
| 249 | +```text |
| 250 | +fix(installerset): resolve concurrent reconcile panic |
| 251 | +
|
| 252 | +Prevent nil pointer dereference when two reconcile loops run |
| 253 | +concurrently on the same InstallerSet object. |
| 254 | +
|
| 255 | +Fixes #789 |
| 256 | +
|
| 257 | +Signed-off-by: John Developer <john@example.com> |
| 258 | +Assisted-by: Claude Sonnet 4.5 (via Cursor) |
| 259 | +```text |
| 260 | +
|
| 261 | +### Documentation update |
| 262 | +
|
| 263 | +```text |
| 264 | +docs(AGENTS.md): update architecture conventions |
| 265 | +
|
| 266 | +Add InstallerSet naming patterns and clarify platform split |
| 267 | +rules for contributors. |
| 268 | +
|
| 269 | +Signed-off-by: Jane Developer <jane@example.com> |
| 270 | +Assisted-by: Claude Sonnet 4.5 (via Cursor) |
| 271 | +```text |
| 272 | +
|
| 273 | +### Breaking change |
| 274 | +
|
| 275 | +```text |
| 276 | +feat(api)!: remove deprecated TektonConfig fields |
| 277 | +
|
| 278 | +Remove fields deprecated in v0.60 from TektonConfig spec. |
| 279 | +Operators upgrading from v0.60 must migrate before upgrading. |
| 280 | +
|
| 281 | +BREAKING CHANGE: Removed spec.targetNamespace and spec.profile |
| 282 | +from TektonConfig. Use spec.config instead. See migration guide. |
| 283 | +
|
| 284 | +Signed-off-by: John Developer <john@example.com> |
| 285 | +Assisted-by: Claude Sonnet 4.5 (via Cursor) |
| 286 | +```text |
| 287 | +
|
| 288 | +## Gitlint Integration |
| 289 | +
|
| 290 | +This project uses gitlint to enforce commit message format. Ensure all commit messages pass gitlint validation. |
| 291 | +
|
| 292 | +**Common gitlint rules**: |
| 293 | +
|
| 294 | +- Conventional commit format required |
| 295 | +- Subject line length limits (50 soft, 72 hard) |
| 296 | +- Required trailers (Signed-off-by) |
| 297 | +- No trailing whitespace |
| 298 | +- Body line wrapping at 72 characters |
| 299 | +
|
| 300 | +For complete gitlint rules, see `references/gitlint-rules.md`. |
| 301 | +
|
| 302 | +## Auto-Detection Summary |
| 303 | +
|
| 304 | +When generating commit messages: |
| 305 | +
|
| 306 | +1. Run `git status` (without -uall flag) |
| 307 | +2. Run `git diff` for staged and unstaged changes |
| 308 | +3. Identify primary component from staged file paths |
| 309 | +4. If scope unclear, ask user |
| 310 | +5. If user mentions a GitHub issue number, add `Fixes #NNN` to body |
| 311 | +6. Analyze staged files to determine commit type |
| 312 | +7. Generate appropriate scope and description |
| 313 | +8. Detect author info from environment variables or git config |
| 314 | +9. Ensure subject line is ≤50 characters (max 72) |
| 315 | +10. Wrap body text at 72 characters per line |
| 316 | +11. Add required trailers (Signed-off-by and Assisted-by) |
| 317 | +12. Format according to conventional commits standard |
| 318 | +13. **Display message and ask for user confirmation** |
| 319 | +14. Only commit after receiving confirmation |
| 320 | +
|
| 321 | +## Additional Resources |
| 322 | +
|
| 323 | +For detailed information: |
| 324 | +
|
| 325 | +- **`references/commit-types.md`** - Complete commit type reference with descriptions |
| 326 | +- **`references/gitlint-rules.md`** - Gitlint validation rules and configuration |
| 327 | +- **`references/trailer-detection.md`** - Author detection logic and priority order |
0 commit comments