version-management
npx skills add https://github.com/hitoshura25/claude-devtools --skill version-management
Agent 安装分布
Skill 文档
Version Management
A technology-agnostic version management system using Git tags as the source of truth, with platform-specific adapters.
Overview
Design Philosophy:
- Git tags are the source of truth for versions
- Committed version files (
version.properties,package.json, etc.) cache the version for fast builds - Release workflows update both git tags and version files
- Supports semantic versioning (major.minor.patch)
Prerequisites
- Git repository initialized
- Git tags enabled
- Bash shell available
- Write access to project directory
Inputs
| Input | Required | Default | Description |
|---|---|---|---|
| project_path | Yes | . | Project root directory |
| platform | Yes | gradle | Platform adapter: gradle, npm, python |
Process
Step 1: Create Core Version Manager Script
Create scripts/version-manager.sh (technology-agnostic):
#!/bin/bash
# Core version manager - technology agnostic
# Handles: tag parsing, semver calculation, version bumping
set -euo pipefail
# === CONFIGURATION ===
BASE_VERSION="${BASE_VERSION:-1.0}"
TAG_PREFIX="${TAG_PREFIX:-v}"
# === CORE FUNCTIONS ===
get_latest_version() {
local prefix="${1:-$TAG_PREFIX}"
git tag -l "${prefix}*" 2>/dev/null |
sed "s/^${prefix}//" |
sort -V |
tail -1 || echo "0.0.0"
}
bump_version() {
local version="$1"
local bump_type="${2:-patch}"
IFS='.' read -r major minor patch <<< "$version"
major="${major:-0}"; minor="${minor:-0}"; patch="${patch:-0}"
case "$bump_type" in
major) major=$((major + 1)); minor=0; patch=0 ;;
minor) minor=$((minor + 1)); patch=0 ;;
patch) patch=$((patch + 1)) ;;
esac
echo "${major}.${minor}.${patch}"
}
generate_version() {
local bump_type="${1:-patch}"
local latest
latest=$(get_latest_version)
if [[ "$latest" == "0.0.0" ]]; then
echo "${BASE_VERSION}.0"
else
bump_version "$latest" "$bump_type"
fi
}
output_version() {
local version="$1"
local is_prerelease="${2:-false}"
if [[ -n "${GITHUB_OUTPUT:-}" ]]; then
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "is-prerelease=$is_prerelease" >> "$GITHUB_OUTPUT"
echo "tag=${TAG_PREFIX}${version}" >> "$GITHUB_OUTPUT"
fi
echo "$version"
}
main() {
local command="${1:-generate}"
local arg="${2:-patch}"
case "$command" in
generate) output_version "$(generate_version "$arg")" "false" ;;
latest) get_latest_version ;;
bump) bump_version "$(get_latest_version)" "$arg" ;;
*) echo "Usage: $0 {generate|latest|bump} [patch|minor|major]" >&2; exit 1 ;;
esac
}
main "$@"
Make it executable:
chmod +x scripts/version-manager.sh
Step 2: Create Platform Adapter
For Gradle/Android Projects
Create scripts/gradle-version.sh:
#!/bin/bash
# Gradle/Android version adapter
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/version-manager.sh"
# Convert semver to Android versionCode: "1.2.34" â 1002034
semver_to_version_code() {
local version="$1"
IFS='.' read -r major minor patch <<< "$version"
echo $((major * 1000000 + minor * 1000 + patch))
}
# Update version.properties
update_version_properties() {
local version="$1"
local version_code
version_code=$(semver_to_version_code "$version")
cat > version.properties << VERSIONEOF
# Auto-generated by release workflow - do not edit manually
VERSION_NAME=$version
VERSION_CODE=$version_code
VERSIONEOF
echo "Updated version.properties: VERSION_NAME=$version, VERSION_CODE=$version_code"
}
# Output Android-specific values to GitHub Actions
output_android_version() {
local version="$1"
local version_code
version_code=$(semver_to_version_code "$version")
if [[ -n "${GITHUB_OUTPUT:-}" ]]; then
echo "version-code=$version_code" >> "$GITHUB_OUTPUT"
fi
}
main() {
local command="${1:-generate}"
shift || true
case "$command" in
generate)
local version
version=$(generate_version "${1:-patch}")
output_version "$version" "false"
output_android_version "$version"
;;
update)
local version="${1:-}"
[[ -z "$version" ]] && version=$(get_latest_version)
update_version_properties "$version"
;;
version-code)
local version="${1:-}"
[[ -z "$version" ]] && version=$(get_latest_version)
semver_to_version_code "$version"
;;
*)
# Delegate to core
source "$SCRIPT_DIR/version-manager.sh"
main "$command" "$@"
;;
esac
}
main "$@"
Make it executable:
chmod +x scripts/gradle-version.sh
Step 3: Create Initial Version File
For Gradle projects, create version.properties:
cat > version.properties << 'EOF'
# Auto-generated by release workflow - do not edit manually
VERSION_NAME=1.0.0
VERSION_CODE=1000000
EOF
Step 4: Update Build Configuration
For Gradle Projects
Update app/build.gradle.kts to read from version.properties:
import java.util.Properties
// Read version from version.properties (fast, no git commands)
val versionProps = Properties().apply {
val versionFile = rootProject.file("version.properties")
if (versionFile.exists()) {
versionFile.inputStream().use { load(it) }
}
}
android {
defaultConfig {
versionName = versionProps.getProperty("VERSION_NAME", "0.0.1-dev")
versionCode = versionProps.getProperty("VERSION_CODE", "1")?.toIntOrNull() ?: 1
}
}
Detection logic:
- Check if versionName/versionCode already set in build.gradle.kts
- If using a different version scheme, ask user if they want to migrate
Step 5: Commit Version File
git add version.properties scripts/
git commit -m "chore: add version management system"
Usage Examples
Local Development
# Get current version
./scripts/version-manager.sh latest
# Generate next patch version
./scripts/version-manager.sh generate patch
# Generate next minor version
./scripts/version-manager.sh generate minor
# Generate next major version
./scripts/version-manager.sh generate major
For Gradle Projects
# Generate version and update version.properties
./scripts/gradle-version.sh generate patch
# Update version.properties with specific version
./scripts/gradle-version.sh update 1.2.3
# Get version code for a version
./scripts/gradle-version.sh version-code 1.2.3
In GitHub Actions
See the release workflow created by android-playstore-setup skill for full integration example.
Verification
MANDATORY: Run these commands:
# Verify scripts exist
test -f scripts/version-manager.sh && echo "â Core script exists"
test -f scripts/gradle-version.sh && echo "â Gradle adapter exists"
# Verify scripts are executable
test -x scripts/version-manager.sh && echo "â Core script is executable"
test -x scripts/gradle-version.sh && echo "â Gradle adapter is executable"
# Test version generation
./scripts/version-manager.sh latest
./scripts/version-manager.sh generate patch
Expected output:
- â Core script exists
- â Gradle adapter exists
- â Core script is executable
- â Gradle adapter is executable
- Version numbers displayed
Outputs
| Output | Location | Description |
|---|---|---|
| Core script | scripts/version-manager.sh | Technology-agnostic version logic |
| Gradle adapter | scripts/gradle-version.sh | Android-specific version handling |
| Version cache | version.properties | Cached version for fast builds |
| Build config | app/build.gradle.kts | Updated to read from version file |
Troubleshooting
“No tags found”
Cause: No git tags exist yet Fix: First version will be 1.0.0 (or BASE_VERSION.0)
“version.properties not found”
Cause: File not created or committed
Fix: Run ./scripts/gradle-version.sh update 1.0.0 to create it
“Permission denied”
Cause: Scripts not executable
Fix: chmod +x scripts/*.sh
Platform Adapters
NPM (Future)
For npm projects, create scripts/npm-version.sh that updates package.json:
# Updates package.json with new version
update_package_json() {
local version="$1"
npm version "$version" --no-git-tag-version
}
Python (Future)
For Python projects, create scripts/python-version.sh that updates __version__:
# Updates __init__.py with new version
update_python_version() {
local version="$1"
sed -i "s/__version__ = .*/__version__ = \"$version\"/" src/__init__.py
}
Completion Criteria
-
scripts/version-manager.shexists and is executable - Platform adapter script exists and is executable
- Version file created (e.g.,
version.properties) - Build configuration updated to read from version file
- Scripts can generate and bump versions correctly
-
git tag -lshows version tags (after first release)