Execute git commit, tag, and push operations with configurable patterns for any project type
Executes git commit, tag, and push operations with configurable patterns for any project type
npx claudepluginhub jayteealao/agent-skillsThis skill inherits all available tools. When active, it can use any tool Claude has access to.
Executes the git operations for a release: running pre-release hooks, staging modified files, creating a commit with proper formatting and attribution, creating an annotated git tag with configurable patterns, and running post-release hooks. Works with any project type.
Requires:
detect-project-type skillUse configuration from detect-project-type:
tag_pattern - Pattern for git tag (e.g., "v{version}", "{package}-v{version}")tag_message - Message template for annotated tagcommit_message_template - Template for commit messagepre_release_hook - Script to run before git operations (optional)post_release_hook - Script to run after successful push (optional)If preReleaseHook is configured, execute it before any git operations:
if [ -n "$pre_release_hook" ]; then
echo "Running pre-release hook: $pre_release_hook"
if [ -x "$pre_release_hook" ]; then
# Run hook and capture output
if ! hook_output=$($pre_release_hook 2>&1); then
# Hook failed - abort release
echo "✗ Pre-release hook failed:"
echo "$hook_output"
exit 1
else
echo "✓ Pre-release hook succeeded"
echo "$hook_output"
fi
else
echo "⚠️ Pre-release hook not executable: $pre_release_hook"
exit 1
fi
fi
Common pre-release hook use cases:
npm test, cargo test, go test ./...npm run build, cargo build --releasenpm run lint, cargo clippynpm run docsnpm pack --dry-run, twine check dist/*Stage all files that were modified during the release process:
git add {file1} {file2} {file3} ...
Files typically include:
Verify staging succeeded:
git status --short
Create commit with the provided message, ensuring proper formatting and attribution:
git commit -m "$(cat <<'EOF'
{commit-message}
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
EOF
)"
Commit message format:
Release {scope} v{version}
{changelog-body}
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Important: Use heredoc (<<'EOF') to preserve formatting and handle multi-line messages correctly.
Capture commit hash:
git rev-parse HEAD
Create an annotated tag (not lightweight) using configurable pattern from configuration:
Build tag name from pattern:
# Get pattern from config (e.g., "v{version}", "{package}-v{version}")
tag_pattern="v{version}" # from config
# Replace placeholders
tag_name="${tag_pattern//\{version\}/$new_version}"
# For monorepo/plugins, also replace {package}
if [[ "$tag_pattern" == *"{package}"* ]]; then
tag_name="${tag_name//\{package\}/$package_name}"
fi
# Examples:
# Pattern: "v{version}" → Tag: "v1.2.0"
# Pattern: "release-{version}" → Tag: "release-1.2.0"
# Pattern: "{package}-v{version}" → Tag: "my-lib-v1.2.0"
Build tag message from template:
# Get template from config (default: "Release v{version}")
tag_message_template="Release v{version}" # from config
# Replace placeholders
tag_message="${tag_message_template//\{version\}/$new_version}"
tag_message="${tag_message//\{package\}/$package_name}"
# Example: "Release v1.2.0"
Create tag:
git tag -a "$tag_name" -m "$tag_message"
Verify tag created:
if git tag -l "$tag_name" | grep -q "$tag_name"; then
echo "✓ Created tag: $tag_name"
else
echo "✗ Failed to create tag: $tag_name"
exit 1
fi
Do NOT automatically push. Instead, prepare information for the command to display:
# Get remote URL
git remote get-url origin
# Get current branch
git branch --show-current
# Show what will be pushed
git log origin/{branch}..HEAD --oneline
Return push command for user to execute:
git push origin {branch} --follow-tags
Or if using --force-with-lease after rebase:
git push origin {branch} --follow-tags --force-with-lease
Note: This section is executed by the /release command AFTER successful push, not within this skill.
If postReleaseHook is configured, execute it after git push succeeds:
if [ -n "$post_release_hook" ]; then
echo "Running post-release hook: $post_release_hook"
if [ -x "$post_release_hook" ]; then
# Run hook and capture output
if ! hook_output=$($post_release_hook 2>&1); then
# Hook failed - warn but don't abort (release already pushed)
echo "⚠️ Post-release hook failed:"
echo "$hook_output"
# Continue anyway - release is already public
else
echo "✓ Post-release hook succeeded"
echo "$hook_output"
fi
else
echo "⚠️ Post-release hook not executable: $post_release_hook"
fi
fi
Common post-release hook use cases:
npm publish, cargo publish, twine upload dist/*netlify deploy, vercel --prod./scripts/notify-slack.sh, ./scripts/post-to-discord.sh./scripts/deploy-docs.shcurl -X POST $CI_WEBHOOK_URLgh release create $TAG_NAMECollect information for post-release summary:
Return:
{
"commit_hash": "a1b2c3d",
"commit_hash_full": "a1b2c3d4e5f6g7h8i9j0",
"tag_name": "daily-carry-v1.2.0",
"files_committed": [
"plugins/daily-carry/.claude-plugin/plugin.json",
"plugins/daily-carry/CHANGELOG.md",
".claude-plugin/marketplace.json"
],
"files_count": 3,
"branch": "master",
"remote_url": "https://github.com/jayteealao/agent-skills.git",
"push_command": "git push origin master --follow-tags",
"success": true
}
Input:
plugin:daily-carry1.2.0Release plugin:daily-carry v1.2.0
Added:
- New deployment command
Fixed:
- Git push error handling
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
["plugins/daily-carry/.claude-plugin/plugin.json", "plugins/daily-carry/CHANGELOG.md", ".claude-plugin/marketplace.json"]Operations:
# Stage files
git add plugins/daily-carry/.claude-plugin/plugin.json
git add plugins/daily-carry/CHANGELOG.md
git add .claude-plugin/marketplace.json
# Create commit
git commit -m "$(cat <<'EOF'
Release plugin:daily-carry v1.2.0
Added:
- New deployment command
Fixed:
- Git push error handling
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
EOF
)"
# Create tag
git tag -a "daily-carry-v1.2.0" -m "Release plugin:daily-carry v1.2.0"
Output:
{
"commit_hash": "f7e8d9c",
"commit_hash_full": "f7e8d9c6b5a4e3d2c1b0a9f8e7d6c5b4",
"tag_name": "daily-carry-v1.2.0",
"files_committed": [
"plugins/daily-carry/.claude-plugin/plugin.json",
"plugins/daily-carry/CHANGELOG.md",
".claude-plugin/marketplace.json"
],
"files_count": 3,
"branch": "master",
"remote_url": "https://github.com/jayteealao/agent-skills.git",
"push_command": "git push origin master --follow-tags",
"success": true
}
Input:
marketplace1.1.0[".claude-plugin/marketplace.json", "CHANGELOG.md", "README.md"]Tag created: marketplace-v1.1.0
Output:
{
"commit_hash": "b4c5d6e",
"tag_name": "marketplace-v1.1.0",
"files_count": 3,
"branch": "master",
"push_command": "git push origin master --follow-tags",
"success": true
}
Input:
variants2.0.0["variants/variants.json", "variants/CHANGELOG.md"]Tag created: variants-v2.0.0
Error: File doesn't exist or permission denied
Response:
{
"success": false,
"error": "Failed to stage files",
"details": "git add failed: {error-message}",
"suggestion": "Verify files exist and are writable"
}
Error: Nothing to commit, commit hook failed, etc.
Response:
{
"success": false,
"error": "Failed to create commit",
"details": "{git-error-message}",
"suggestion": "Check git status and pre-commit hooks"
}
Rollback: If commit fails, unstage files:
git reset HEAD
Error: Tag already exists, invalid tag name, etc.
Response:
{
"success": false,
"error": "Failed to create tag",
"details": "{git-error-message}",
"commit_hash": "f7e8d9c",
"suggestion": "Tag may already exist. Use 'git tag -d {tag}' to delete or choose different version"
}
Rollback: Offer to undo commit:
git reset --soft HEAD~1
Warning: (non-blocking)
Response:
{
"success": true,
"commit_hash": "f7e8d9c",
"tag_name": "daily-carry-v1.2.0",
"remote_url": null,
"push_command": null,
"warning": "No git remote configured - cannot push"
}
This skill is invoked by the /release command in Phase 6. The command will:
git push origin {branch} --follow-tags
-a flag) for releases (contains metadata)--follow-tags when pushing to include annotated tags--force-with-leaseTo maintain linear git history:
git merge --no-ffYou MUST use this before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation.