235 lines
11 KiB
Markdown
235 lines
11 KiB
Markdown
---
|
|
description: Auto-generate commit message, commit and create tag
|
|
agent: build
|
|
---
|
|
|
|
# auto-commit
|
|
|
|
Auto-generate commit message for staged files, commit to local repository.
|
|
|
|
## Features
|
|
|
|
- **Create tag**: Automatically generate version number and create tag by default
|
|
- **Skip tag**: Skip creating tag when user inputs "skip" or "skip tag"
|
|
|
|
> Version number update is **consistent** with git tag: AI will automatically update version number based on project type and changes, and create tag with the same version number.
|
|
|
|
## Steps
|
|
|
|
### 1. Check Staging Area
|
|
|
|
Run `git diff --cached --name-only` to check if there are files in staging area.
|
|
|
|
**If staging area is empty**:
|
|
- Output prompt: "No files in staging area, please use `git add` to add files first."
|
|
- **Terminate command execution**, do not continue
|
|
|
|
### 2. Collect Information (Execute in parallel)
|
|
|
|
- Run `git status` to view current status
|
|
- Run `git diff --cached` to view specific changes in staging area
|
|
- Run `git log --oneline -10` to view recent commit history, understand project's commit style
|
|
- Run `git tag --list | sort -V | tail -5` to view recent tags
|
|
- Read `AGENTS.md` file (if exists), understand project type, structure and **version update rules**
|
|
|
|
### 3. Detect Repository Type
|
|
|
|
**Detect repository type (polyrepo or monorepo)**:
|
|
|
|
- Check if `AGENTS.md` file indicates **monorepo**, if `AGENTS.md` doesn't exist or doesn't clearly indicate, default to **polyrepo**
|
|
|
|
**If monorepo, analyze change scope**:
|
|
|
|
- Based on changed files from step 1, analyze if changes only affect a specific subproject
|
|
- If only single subproject is affected, record subproject name (e.g., extract `user-service` from path `packages/user-service/src/index.ts`)
|
|
|
|
### 4. Detect Project Type and Determine Version Number
|
|
|
|
**Prioritize reading version update rules from AGENTS.md**:
|
|
|
|
If `AGENTS.md` defines version update rules (such as version file path, version field name, etc.), prioritize using that rule.
|
|
|
|
**Auto-detect project type** (when AGENTS.md is not defined):
|
|
|
|
AI needs to intelligently identify project type and determine version file, common project types include but not limited to:
|
|
|
|
| Project Type | Version File | Version Field/Location |
|
|
| --- | --- | --- |
|
|
| iOS | `*.xcodeproj/project.pbxproj` | `MARKETING_VERSION` |
|
|
| npm/Node.js | `package.json` | `version` |
|
|
| Android (Groovy) | `app/build.gradle` | `versionName` |
|
|
| Android (Kotlin DSL) | `app/build.gradle.kts` | `versionName` |
|
|
| Python (pyproject) | `pyproject.toml` | `[project] version` or `[tool.poetry] version` |
|
|
| Python (setup) | `setup.py` | `version` parameter |
|
|
| Rust | `Cargo.toml` | `[package] version` |
|
|
| Go | Usually only uses git tag | - |
|
|
| Flutter | `pubspec.yaml` | `version` |
|
|
| .NET | `*.csproj` | `<Version>` or `<PackageVersion>` |
|
|
|
|
> AI should determine project type based on files that actually exist in repository, can check multiple possible version files if necessary.
|
|
|
|
**Read current version number**:
|
|
|
|
1. Read current version number from identified version file
|
|
2. Parse as `major.minor.patch`:
|
|
- If parsing fails or doesn't exist: treat as `0.1.0`
|
|
- If current version only has `major.minor` format, auto-complete to `major.minor.0`
|
|
|
|
**Calculate new version number** (based on change type):
|
|
|
|
Version number uses **semantic versioning format**: `0.1.0`, `0.2.0`, ..., `0.9.0`, `1.0.0`, `1.1.0`, `1.1.1`...
|
|
- **Default starting version**: `0.1.0`
|
|
- **Increment rules**:
|
|
- **Major/breaking changes**: `1.2.3` -> `2.0.0` (major +1, minor and patch reset to zero)
|
|
- **New feature (feat)**: `1.2.3` -> `1.3.0` (minor +1, patch reset to zero)
|
|
- **Bug fix (fix)**: `1.2.3` -> `1.2.4` (patch +1)
|
|
|
|
**Determine if version number update is needed**:
|
|
|
|
> Core principle: **Version number reflects "user-perceivable changes"**. Ask yourself: Has the product that users download/use changed?
|
|
|
|
**Need to update version number** (packaged into final product, user-perceivable):
|
|
|
|
| commit type | version change | description |
|
|
| --- | --- | --- |
|
|
| `feat` | minor +1 | new feature |
|
|
| `fix` | patch +1 | user-perceivable bug fix |
|
|
| `perf` | patch +1 | performance optimization (user-perceivable improvement) |
|
|
| breaking change (`!`) | major +1 | API/protocol incompatible changes |
|
|
|
|
**No need to update version number** (doesn't affect final product, user-imperceptible):
|
|
|
|
| commit type | description | example |
|
|
| --- | --- | --- |
|
|
| `chore` | miscellaneous/toolchain | build scripts, CI config, dependency updates |
|
|
| `ci` | CI/CD config | `.github/workflows/*.yml`, `release.mjs` |
|
|
| `docs` | documentation | README, comments, API docs |
|
|
| `test` | test code | unit tests, E2E tests |
|
|
| `refactor` | refactoring | code reorganization without changing external behavior |
|
|
| `style` | code style | formatting, spaces, semicolons |
|
|
| `build` | build config | `tsconfig.json`, `biome.json`, `webpack.config.js` |
|
|
|
|
**Judgment tips**:
|
|
|
|
1. **Will the file be packaged into final product?**
|
|
- `scripts/`, `.github/`, `*.config.js` -> No -> Don't update version
|
|
- `src/`, `lib/`, `app/` -> Yes -> May need to update version
|
|
|
|
2. **Does the change only affect developers?**
|
|
- Dev tool config, CI scripts, build process -> Only affects developers -> Don't update version
|
|
- Feature code, UI, API -> Affects users -> Update version
|
|
|
|
3. **If project type cannot be identified or no version file** -> Only create git tag, don't update version file
|
|
|
|
### 5. Generate Commit Message
|
|
|
|
Based on changes in staging area, **analyze and generate meaningful commit message by AI**:
|
|
|
|
- Analyze changed code content, understand the purpose and intent of this modification
|
|
- Reference project's commit history style
|
|
- Use [Conventional Commits](https://www.conventionalcommits.org/) specification
|
|
- Commit message should concisely but accurately describe "why" rather than just "what"
|
|
- Common types: `feat` (new feature), `fix` (fix), `docs` (documentation), `refactor` (refactoring), `chore` (miscellaneous), `test` (test), etc.
|
|
- **If monorepo and this commit only affects single subproject, include subproject name in commit message**:
|
|
- Format: `<type>(<scope>): <description>`, where `<scope>` is subproject name
|
|
- Example: `feat(ios): support OGG Opus upload` or `fix(electron): fix clipboard injection failure`
|
|
- If affecting multiple subprojects or entire repository, no need to add scope
|
|
|
|
### 6. Update Project Version Number
|
|
|
|
> Only execute when step 4 determines version number update is needed and version file is identified
|
|
|
|
**Execution steps**:
|
|
|
|
1. Based on version file and field identified in step 4, update version number to calculated new version
|
|
2. Add version file to staging area: `git add <version file>`
|
|
3. **Verify staging area**: Run `git diff --cached --name-only` to confirm version file is in staging area
|
|
|
|
### 7. Execute Commit
|
|
|
|
Execute commit with generated commit message (staging area now includes user's changes and version number update).
|
|
|
|
**Windows encoding issue solution:**
|
|
|
|
Cursor's Shell tool has encoding issues when passing Chinese parameters on Windows, causing garbled Git commit messages.
|
|
|
|
**Correct approach**: Use **English** commit message
|
|
|
|
```powershell
|
|
# Single line commit
|
|
git commit -m "feat(android): add new feature"
|
|
|
|
# Multi-line commit (use --message multiple times)
|
|
git commit --message="fix(android): fix code review issues" --message="- Fix syntax error" --message="- Use JSONObject instead of manual JSON"
|
|
```
|
|
|
|
**Prohibited methods** (will cause garbled text):
|
|
- No Chinese commit messages - Cursor Shell tool encoding error when passing Chinese parameters
|
|
- No `Out-File -Encoding utf8` - writes UTF-8 with BOM
|
|
- No Write tool to write temp files - encoding uncontrollable
|
|
- No PowerShell here-string `@"..."@` - newline parsing issues
|
|
|
|
**For Chinese commit messages**: Please manually execute `git commit` in terminal, or use Git GUI tools other than Cursor.
|
|
|
|
**macOS/Linux alternative** (supports Chinese):
|
|
|
|
```bash
|
|
git commit -m "$(cat <<'EOF'
|
|
feat(android): new feature description
|
|
|
|
- Detail 1
|
|
- Detail 2
|
|
EOF
|
|
)"
|
|
```
|
|
|
|
### 8. Create Tag
|
|
|
|
> **Executed by default**. Only skip this step when user explicitly inputs "skip" or "skip tag".
|
|
> Only create tag when step 4 determines version number update is needed (docs/chore types don't create tag).
|
|
|
|
**Tag annotation content requirements**:
|
|
|
|
- **Use the same content as commit message for tag annotation**
|
|
- Tag annotation will be used as Release notes by CI/CD scripts, should include detailed change content
|
|
- If commit message has multiple lines, tag annotation should also be multi-line
|
|
|
|
**polyrepo**:
|
|
```bash
|
|
git tag -a "<version>" -m "<commit title>" -m "" -m "<commit body line 1>" -m "<commit body line 2>" ...
|
|
```
|
|
|
|
**monorepo**:
|
|
```bash
|
|
git tag -a "<subproject>-<version>" -m "<commit title>" -m "" -m "<commit body line 1>" -m "<commit body line 2>" ...
|
|
```
|
|
|
|
Examples (single line commit):
|
|
- polyrepo: `git tag -a "1.2.0" -m "feat: add user authentication"`
|
|
- monorepo: `git tag -a "android-1.2.0" -m "feat(android): add user authentication"`
|
|
|
|
Examples (multi-line commit, more recommended):
|
|
- polyrepo:
|
|
```bash
|
|
git tag -a "1.2.1" -m "fix: resolve bluetooth connection timeout" -m "" -m "- Increase connection timeout to 30s" -m "- Add retry mechanism for failed connections" -m "- Improve error messages"
|
|
```
|
|
- monorepo:
|
|
```bash
|
|
git tag -a "android-1.2.1" -m "fix(android): resolve bluetooth connection timeout" -m "" -m "- Increase connection timeout to 30s" -m "- Add retry mechanism for failed connections" -m "- Improve error messages"
|
|
```
|
|
|
|
## Notes
|
|
|
|
- **Staging area check first**: Must check if staging area has files first, if not, terminate immediately, don't execute any subsequent operations.
|
|
- **AGENTS.md priority**: If `AGENTS.md` defines version update rules, prioritize using that rule; otherwise AI auto-detects project type.
|
|
- **Smart detection**: AI should intelligently determine project type and version file location based on files that actually exist in repository.
|
|
- **Version number and tag consistency**: Project version number and git tag use the same version number, ensure consistency.
|
|
- **Version number format**: Use `major.minor.patch` semantic versioning format (e.g., `0.1.0`, `1.1.0`, `1.1.1`), default starting `0.1.0`.
|
|
- **Create tag by default**: Unless user inputs "skip" or "skip tag", create tag by default.
|
|
- **Update version before commit**: First determine version number and modify version file, then commit at once, avoid using `--amend`.
|
|
- **Version file must be verified**: After updating version number and `git add`, must run `git diff --cached --name-only` to confirm version file is in staging area before executing commit.
|
|
- **Windows encoding issues**: Cursor Shell tool garbles Chinese parameters, must use **English** commit messages. For Chinese, please manually execute in terminal.
|
|
- **monorepo scope**: If staging area only affects single subproject, commit message should have scope; if affecting multiple subprojects, no scope needed.
|
|
- **monorepo tag format**: Use `<subproject>-<version>` format (e.g., `ios-0.1.0`, `android-1.1.0`).
|
|
- **No version file case**: If project type cannot be identified or no version file (like pure Go project), only create git tag, don't update any files.
|