Version Control for Claude Code Skills: Git Strategies
Master Git workflows for Claude Code skill development including branching strategies, versioning conventions, collaboration patterns, and CI/CD pipelines.
Version Control for Claude Code Skills: Git Strategies
Skills are code, and code belongs in version control. This guide covers Git strategies specifically designed for Claude Code skill development, from solo projects to team collaboration at scale.
Repository Structure
Single Skill Repository
For focused, single-purpose skills:
my-skill/
├── .github/
│ └── workflows/
│ ├── test.yml
│ ├── publish.yml
│ └── security-scan.yml
├── src/
│ ├── prompts/
│ │ └── system.md
│ ├── lib/
│ │ ├── parser.ts
│ │ └── validator.ts
│ └── index.ts
├── tests/
│ ├── unit/
│ │ └── parser.test.ts
│ └── integration/
│ └── skill.test.ts
├── examples/
│ ├── basic-usage.md
│ └── advanced-usage.md
├── SKILL.md
├── CHANGELOG.md
├── package.json
├── tsconfig.json
└── README.md
Monorepo for Multiple Skills
For organizations maintaining multiple related skills:
skills-monorepo/
├── .github/
│ └── workflows/
│ └── ci.yml
├── packages/
│ ├── core/ # Shared utilities
│ │ ├── src/
│ │ └── package.json
│ ├── skill-code-review/
│ │ ├── src/
│ │ ├── SKILL.md
│ │ └── package.json
│ ├── skill-documentation/
│ │ ├── src/
│ │ ├── SKILL.md
│ │ └── package.json
│ └── skill-testing/
│ ├── src/
│ ├── SKILL.md
│ └── package.json
├── tools/
│ ├── skill-validator/
│ └── prompt-linter/
├── docs/
│ └── contributing.md
├── pnpm-workspace.yaml
├── package.json
└── README.md
Branching Strategy
Git Flow for Skills
A modified Git Flow optimized for skill development:
main (production)
├── develop (integration)
│ ├── feature/add-caching
│ ├── feature/improve-prompts
│ └── feature/new-output-format
├── release/v1.2.0
└── hotfix/security-patch
Branch Types:
| Branch | Purpose | Merges To | Naming |
|---|---|---|---|
| main | Production-ready skills | - | main |
| develop | Integration branch | main | develop |
| feature | New functionality | develop | feature/description |
| release | Release preparation | main, develop | release/vX.Y.Z |
| hotfix | Emergency fixes | main, develop | hotfix/description |
Simplified Flow for Solo Developers
main
├── feature/add-caching
├── feature/improve-prompts
└── fix/parsing-bug
Direct merges to main with feature branches for larger changes.
Branch Protection Rules
# .github/branch-protection.yml (reference)
branches:
main:
protection:
required_status_checks:
strict: true
contexts:
- "test"
- "security-scan"
- "skill-validation"
required_pull_request_reviews:
required_approving_review_count: 1
dismiss_stale_reviews: true
restrictions:
users: []
teams: ["maintainers"]
enforce_admins: true
develop:
protection:
required_status_checks:
contexts:
- "test"
Versioning Strategy
Semantic Versioning for Skills
Follow SemVer with skill-specific considerations:
MAJOR.MINOR.PATCH
MAJOR: Breaking changes to skill behavior or output format
MINOR: New features, backward-compatible
PATCH: Bug fixes, prompt improvements (same behavior)
Examples:
| Change | Version Bump | Example |
|---|---|---|
| Change output format | MAJOR | 1.0.0 -> 2.0.0 |
| Add new parameter | MINOR | 1.0.0 -> 1.1.0 |
| Fix typo in prompt | PATCH | 1.0.0 -> 1.0.1 |
| Improve accuracy | PATCH | 1.0.0 -> 1.0.1 |
| Change required inputs | MAJOR | 1.0.0 -> 2.0.0 |
| Add optional feature | MINOR | 1.0.0 -> 1.1.0 |
Version in SKILL.md
# SKILL.md
---
name: code-review
version: 1.2.3
minClaudeVersion: "1.0.0"
---
Changelog Management
# CHANGELOG.md
## [1.2.0] - 2025-01-15
### Added
- Support for TypeScript 5.0 features
- New `--strict` flag for pedantic mode
### Changed
- Improved detection of security issues
- Updated prompts for better accuracy
### Fixed
- Parsing error with JSX fragments
## [1.1.0] - 2025-01-01
### Added
- Multi-file analysis support
- JSON output format option
## [1.0.0] - 2024-12-15
### Added
- Initial release
- Basic code review functionality
Automated Version Bumping
// scripts/bump-version.ts
import * as fs from 'fs';
import * as semver from 'semver';
type BumpType = 'major' | 'minor' | 'patch';
async function bumpVersion(type: BumpType): Promise<void> {
// Read current version from SKILL.md
const skillMd = fs.readFileSync('SKILL.md', 'utf-8');
const versionMatch = skillMd.match(/version:\s*["']?(\d+\.\d+\.\d+)["']?/);
if (!versionMatch) {
throw new Error('Could not find version in SKILL.md');
}
const currentVersion = versionMatch[1];
const newVersion = semver.inc(currentVersion, type);
if (!newVersion) {
throw new Error('Failed to bump version');
}
// Update SKILL.md
const updatedSkillMd = skillMd.replace(
/version:\s*["']?\d+\.\d+\.\d+["']?/,
`version: "${newVersion}"`
);
fs.writeFileSync('SKILL.md', updatedSkillMd);
// Update package.json if exists
if (fs.existsSync('package.json')) {
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
pkg.version = newVersion;
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
}
console.log(`Version bumped: ${currentVersion} -> ${newVersion}`);
}
// Usage: npx ts-node scripts/bump-version.ts minor
const type = process.argv[2] as BumpType;
bumpVersion(type);
Commit Conventions
Conventional Commits
Use conventional commits for clear history:
<type>(<scope>): <description>
[optional body]
[optional footer]
Types for Skills:
| Type | Description | Example |
|---|---|---|
| feat | New feature | feat(parser): add JSON output |
| fix | Bug fix | fix(prompt): correct typo |
| prompt | Prompt changes | prompt: improve accuracy |
| docs | Documentation | docs: update examples |
| test | Testing | test: add edge cases |
| perf | Performance | perf: reduce token usage |
| refactor | Code refactor | refactor: extract helper |
| chore | Maintenance | chore: update deps |
Commit Message Examples
# Feature commit
git commit -m "feat(review): add security vulnerability detection
- Add pattern matching for SQL injection
- Add XSS detection in templates
- Include severity ratings in output
Closes #42"
# Prompt improvement
git commit -m "prompt: improve code review accuracy
Restructure system prompt to reduce false positives.
Testing shows 15% improvement in precision."
# Bug fix
git commit -m "fix(parser): handle empty input gracefully
Previously threw undefined error on empty string input.
Now returns helpful error message.
Fixes #37"
Git Hooks for Commit Validation
#!/bin/bash
# .git/hooks/commit-msg
commit_regex='^(feat|fix|prompt|docs|test|perf|refactor|chore)(\([a-z-]+\))?!?: .{1,72}$'
if ! grep -qE "$commit_regex" "$1"; then
echo "ERROR: Invalid commit message format"
echo "Expected: type(scope): description"
echo "Types: feat, fix, prompt, docs, test, perf, refactor, chore"
exit 1
fi
CI/CD Pipeline
GitHub Actions Workflow
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run unit tests
run: npm test
- name: Run integration tests
run: npm run test:integration
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate SKILL.md
run: |
# Check required fields
grep -q "^name:" SKILL.md || (echo "Missing name" && exit 1)
grep -q "^version:" SKILL.md || (echo "Missing version" && exit 1)
grep -q "^description:" SKILL.md || (echo "Missing description" && exit 1)
- name: Lint prompts
run: npm run lint:prompts
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Security scan
run: |
# Check for secrets
! grep -rE "(sk-[a-zA-Z0-9]{32}|ghp_[a-zA-Z0-9]{36})" . --include="*.ts" --include="*.md"
# Check for dangerous patterns
! grep -r "dangerouslyDisableSandbox" . --include="*.ts" --include="*.md"
publish:
needs: [test, validate, security]
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Get version
id: version
run: |
VERSION=$(grep "version:" SKILL.md | head -1 | sed 's/version:\s*["'"'"']\?\([0-9.]*\)["'"'"']\?/\1/')
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Create release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: v${{ steps.version.outputs.version }}
release_name: Release v${{ steps.version.outputs.version }}
draft: false
prerelease: false
Release Automation
# .github/workflows/release.yml
name: Release
on:
push:
tags:
- 'v*'
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Build
run: npm run build
- name: Package skill
run: |
mkdir -p dist
cp SKILL.md dist/
cp -r src/prompts dist/
tar -czf skill-package.tar.gz dist/
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
files: skill-package.tar.gz
generate_release_notes: true
- name: Publish to registry
run: |
# Publish to skill registry if configured
echo "Publishing to skill registry..."
env:
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
Collaboration Patterns
Pull Request Template
<!-- .github/pull_request_template.md -->
## Description
<!-- What does this PR do? -->
## Type of Change
- [ ] Bug fix (non-breaking change fixing an issue)
- [ ] New feature (non-breaking change adding functionality)
- [ ] Breaking change (fix or feature causing existing functionality to change)
- [ ] Prompt improvement (changes to AI prompts)
- [ ] Documentation update
## Testing
<!-- How was this tested? -->
- [ ] Unit tests pass
- [ ] Integration tests pass
- [ ] Manual testing completed
## Prompt Changes
<!-- If prompts were modified -->
- [ ] Tested with diverse inputs
- [ ] Verified no regression in output quality
- [ ] Token usage impact assessed
## Checklist
- [ ] Code follows project style guidelines
- [ ] Self-review completed
- [ ] Documentation updated
- [ ] CHANGELOG.md updated
- [ ] Version bumped appropriately
Code Review Guidelines
<!-- docs/REVIEWING.md -->
# Reviewing Claude Code Skills
## Prompt Review Checklist
- [ ] Is the system prompt clear and unambiguous?
- [ ] Are edge cases handled in the prompt?
- [ ] Is the output format well-specified?
- [ ] Are there examples in the prompt?
- [ ] Is the prompt concise (token-efficient)?
## Security Review Checklist
- [ ] No hardcoded secrets or API keys
- [ ] Sandbox configuration is appropriate
- [ ] User input is validated
- [ ] Output is sanitized if needed
- [ ] No path traversal vulnerabilities
## Quality Review Checklist
- [ ] Tests cover main functionality
- [ ] Error handling is appropriate
- [ ] Performance is acceptable
- [ ] Documentation is complete
- [ ] CHANGELOG is updated
CODEOWNERS
# .github/CODEOWNERS
# Default owners
* @team-lead
# Prompt changes require senior review
*.md @prompt-engineer @team-lead
# Security-sensitive files
**/security/** @security-team
**/auth/** @security-team
# Core library changes
packages/core/** @core-maintainers
Skill Registry Integration
Publishing to Registry
// scripts/publish.ts
interface SkillPackage {
name: string;
version: string;
description: string;
author: string;
repository: string;
skillMd: string;
prompts: Record<string, string>;
checksum: string;
}
async function publishToRegistry(): Promise<void> {
const skillMd = await fs.readFile('SKILL.md', 'utf-8');
const metadata = parseSkillMetadata(skillMd);
// Read all prompt files
const prompts = await readPromptFiles('src/prompts');
// Create package
const pkg: SkillPackage = {
name: metadata.name,
version: metadata.version,
description: metadata.description,
author: metadata.author,
repository: getRepoUrl(),
skillMd,
prompts,
checksum: calculateChecksum(skillMd, prompts),
};
// Publish to registry
const response = await fetch('https://registry.example.com/skills', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.REGISTRY_TOKEN}`,
},
body: JSON.stringify(pkg),
});
if (!response.ok) {
throw new Error(`Failed to publish: ${response.statusText}`);
}
console.log(`Published ${pkg.name}@${pkg.version}`);
}
function parseSkillMetadata(skillMd: string): Record<string, string> {
// Parse YAML frontmatter
const match = skillMd.match(/^---\n([\s\S]*?)\n---/);
if (!match) return {};
const lines = match[1].split('\n');
const metadata: Record<string, string> = {};
for (const line of lines) {
const [key, ...valueParts] = line.split(':');
if (key && valueParts.length) {
metadata[key.trim()] = valueParts.join(':').trim().replace(/^["']|["']$/g, '');
}
}
return metadata;
}
async function readPromptFiles(dir: string): Promise<Record<string, string>> {
const prompts: Record<string, string> = {};
// Implementation to read all .md files in prompts directory
return prompts;
}
function getRepoUrl(): string {
// Read from package.json or git remote
return '';
}
function calculateChecksum(skillMd: string, prompts: Record<string, string>): string {
const crypto = require('crypto');
const content = skillMd + JSON.stringify(prompts);
return crypto.createHash('sha256').update(content).digest('hex');
}
Best Practices Summary
Repository Organization
- Use clear directory structure
- Separate prompts from code
- Include comprehensive documentation
- Add examples for users
Branching
- Protect main branch
- Use feature branches for changes
- Require reviews for merges
- Tag releases consistently
Versioning
- Follow semantic versioning
- Maintain CHANGELOG
- Automate version bumping
- Document breaking changes
CI/CD
- Run tests on every push
- Validate SKILL.md format
- Scan for security issues
- Automate releases
Collaboration
- Use PR templates
- Define CODEOWNERS
- Document review guidelines
- Require prompt review for changes
Conclusion
Version control for Claude Code skills follows familiar Git patterns with skill-specific considerations:
- Structure: Organize prompts, code, and tests clearly
- Branching: Protect production with branch rules
- Versioning: Use SemVer with prompt-aware bumping
- Commits: Follow conventions for clear history
- CI/CD: Automate testing, validation, and publishing
- Collaboration: Review prompts as carefully as code
With these practices, teams can maintain high-quality skills while enabling rapid iteration and safe collaboration.
Ready to master the skill format? Continue to The SKILL.md Format for the complete specification.