# Generic Automatic Version Increment System for Any Repository Here's a generalized implementation guide for adding automatic versioning to any project: ## Core Concept **Automatic patch version increment with each build** - Every build automatically increments the patch version: v0.1.0 → v0.1.1 → v0.1.2, etc. ## Implementation Steps ### 1. Add Version Increment Function to Build Script Add this function to your build script (bash example): ```bash # Function to automatically increment version increment_version() { echo "[INFO] Incrementing version..." # Check if we're in a git repository if ! git rev-parse --git-dir > /dev/null 2>&1; then echo "[WARNING] Not in a git repository - skipping version increment" return 0 fi # Get the highest version tag (not chronologically latest) LATEST_TAG=$(git tag -l 'v*.*.*' | sort -V | tail -n 1 || echo "v0.1.0") if [[ -z "$LATEST_TAG" ]]; then LATEST_TAG="v0.1.0" fi # Extract version components (remove 'v' prefix) VERSION=${LATEST_TAG#v} # Parse major.minor.patch using regex if [[ $VERSION =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then MAJOR=${BASH_REMATCH[1]} MINOR=${BASH_REMATCH[2]} PATCH=${BASH_REMATCH[3]} else echo "[ERROR] Invalid version format in tag: $LATEST_TAG" echo "[ERROR] Expected format: v0.1.0" return 1 fi # Increment patch version NEW_PATCH=$((PATCH + 1)) NEW_VERSION="v${MAJOR}.${MINOR}.${NEW_PATCH}" echo "[INFO] Current version: $LATEST_TAG" echo "[INFO] New version: $NEW_VERSION" # Create new git tag if git tag "$NEW_VERSION" 2>/dev/null; then echo "[SUCCESS] Created new version tag: $NEW_VERSION" else echo "[WARNING] Tag $NEW_VERSION already exists - using existing version" NEW_VERSION=$LATEST_TAG fi # Update VERSION file for compatibility echo "${NEW_VERSION#v}" > VERSION echo "[SUCCESS] Updated VERSION file to ${NEW_VERSION#v}" } ``` ### 2. Generate Version Header Files (For C/C++ Projects) Add this to the increment_version function: ```bash # Generate version.h header file (adjust path as needed) cat > src/version.h << EOF /* * Auto-Generated Version Header * DO NOT EDIT THIS FILE MANUALLY - Generated by build script */ #ifndef VERSION_H #define VERSION_H #define VERSION_MAJOR ${MAJOR} #define VERSION_MINOR ${MINOR} #define VERSION_PATCH ${NEW_PATCH} #define VERSION_STRING "${MAJOR}.${MINOR}.${NEW_PATCH}" #define VERSION_TAG "${NEW_VERSION}" /* Build information */ #define BUILD_DATE "$(date +%Y-%m-%d)" #define BUILD_TIME "$(date +%H:%M:%S)" #define BUILD_TIMESTAMP "$(date '+%Y-%m-%d %H:%M:%S')" /* Git information */ #define GIT_HASH "$(git rev-parse --short HEAD 2>/dev/null || echo 'unknown')" #define GIT_BRANCH "$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo 'unknown')" /* Display versions */ #define VERSION_DISPLAY "${NEW_VERSION}" #define VERSION_FULL_DISPLAY "${NEW_VERSION} ($(date '+%Y-%m-%d %H:%M:%S'), $(git rev-parse --short HEAD 2>/dev/null || echo 'unknown'))" /* Version API functions */ const char* get_version(void); const char* get_version_full(void); const char* get_build_info(void); #endif /* VERSION_H */ EOF # Generate version.c implementation file cat > src/version.c << EOF /* * Auto-Generated Version Implementation * DO NOT EDIT THIS FILE MANUALLY - Generated by build script */ #include "version.h" const char* get_version(void) { return VERSION_TAG; } const char* get_version_full(void) { return VERSION_FULL_DISPLAY; } const char* get_build_info(void) { return "Built on " BUILD_DATE " at " BUILD_TIME " from commit " GIT_HASH " on branch " GIT_BRANCH; } EOF ``` ### 3. Generate Version File for Other Languages **Python (`src/__version__.py`):** ```bash cat > src/__version__.py << EOF """Auto-generated version file""" __version__ = "${MAJOR}.${MINOR}.${NEW_PATCH}" __version_tag__ = "${NEW_VERSION}" __build_date__ = "$(date +%Y-%m-%d)" __build_time__ = "$(date +%H:%M:%S)" __git_hash__ = "$(git rev-parse --short HEAD 2>/dev/null || echo 'unknown')" __git_branch__ = "$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo 'unknown')" EOF ``` **JavaScript/Node.js (update `package.json`):** ```bash # Update package.json version field if [ -f package.json ]; then sed -i "s/\"version\": \".*\"/\"version\": \"${MAJOR}.${MINOR}.${NEW_PATCH}\"/" package.json fi ``` **Rust (update `Cargo.toml`):** ```bash if [ -f Cargo.toml ]; then sed -i "s/^version = \".*\"/version = \"${MAJOR}.${MINOR}.${NEW_PATCH}\"/" Cargo.toml fi ``` **Go (generate `version.go`):** ```bash cat > version.go << EOF // Auto-generated version file package main const ( VersionMajor = ${MAJOR} VersionMinor = ${MINOR} VersionPatch = ${NEW_PATCH} VersionString = "${MAJOR}.${MINOR}.${NEW_PATCH}" VersionTag = "${NEW_VERSION}" BuildDate = "$(date +%Y-%m-%d)" BuildTime = "$(date +%H:%M:%S)" GitHash = "$(git rev-parse --short HEAD 2>/dev/null || echo 'unknown')" GitBranch = "$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo 'unknown')" ) EOF ``` **Java (generate `Version.java`):** ```bash cat > src/main/java/Version.java << EOF // Auto-generated version class public class Version { public static final int VERSION_MAJOR = ${MAJOR}; public static final int VERSION_MINOR = ${MINOR}; public static final int VERSION_PATCH = ${NEW_PATCH}; public static final String VERSION_STRING = "${MAJOR}.${MINOR}.${NEW_PATCH}"; public static final String VERSION_TAG = "${NEW_VERSION}"; public static final String BUILD_DATE = "$(date +%Y-%m-%d)"; public static final String BUILD_TIME = "$(date +%H:%M:%S)"; public static final String GIT_HASH = "$(git rev-parse --short HEAD 2>/dev/null || echo 'unknown')"; public static final String GIT_BRANCH = "$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo 'unknown')"; } EOF ``` ### 4. Integrate into Build Targets Call `increment_version` before your main build commands: ```bash build_library() { increment_version echo "[INFO] Building library..." # Your actual build commands here make clean && make } build_release() { increment_version echo "[INFO] Building release..." # Your release build commands } build_package() { increment_version echo "[INFO] Building package..." # Your packaging commands } ``` ### 5. Update .gitignore Add generated version files to `.gitignore`: ```gitignore # Auto-generated version files src/version.h src/version.c src/__version__.py version.go src/main/java/Version.java VERSION ``` ### 6. Update Build System Files **For Makefile projects:** ```makefile # Add version.c to your source files SOURCES = main.c utils.c version.c ``` **For CMake projects:** ```cmake # Add version files to your target target_sources(your_target PRIVATE src/version.c) ``` **For Node.js projects:** ```json { "scripts": { "build": "node build.js && increment_version", "version": "node -e \"console.log(require('./package.json').version)\"" } } ``` ### 7. Create Initial Version Tag ```bash # Start with initial version git tag v0.1.0 ``` ## Usage Pattern ```bash ./build.sh # v0.1.0 → v0.1.1 ./build.sh release # v0.1.1 → v0.1.2 ./build.sh package # v0.1.2 → v0.1.3 ``` ## Manual Version Control ### Major/Minor Version Bumps ```bash # For feature releases (minor bump) git tag v0.2.0 # Next build: v0.2.1 # For breaking changes (major bump) git tag v1.0.0 # Next build: v1.0.1 ``` ### Version Reset ```bash # Delete incorrect tags (if needed) git tag -d v0.2.1 git push origin --delete v0.2.1 # If pushed to remote # Create correct base version git tag v0.2.0 # Next build will create v0.2.1 ``` ## Example Build Script Template ```bash #!/bin/bash set -e # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' print_status() { echo -e "${BLUE}[INFO]${NC} $1"; } print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; } print_error() { echo -e "${RED}[ERROR]${NC} $1"; } # Insert increment_version function here case "${1:-build}" in build) increment_version print_status "Building project..." # Your build commands ;; clean) print_status "Cleaning build artifacts..." # Your clean commands ;; test) print_status "Running tests..." # Your test commands (no version increment) ;; release) increment_version print_status "Building release..." # Your release commands ;; *) echo "Usage: $0 {build|clean|test|release}" exit 1 ;; esac ``` ## Benefits 1. **Zero maintenance** - No manual version editing 2. **Build traceability** - Every build has unique version + metadata 3. **Git integration** - Automatic version tags 4. **Language agnostic** - Adapt generation for any language 5. **CI/CD friendly** - Works in automated environments 6. **Rollback friendly** - Easy to revert to previous versions ## Troubleshooting ### Version Not Incrementing - Ensure you're in a git repository - Check that git tags exist: `git tag --list` - Verify tag format matches `v*.*.*` pattern ### Tag Already Exists If a tag already exists, the build continues with existing version: ``` [WARNING] Tag v0.2.1 already exists - using existing version ``` ### Missing Git Information If git is unavailable, version files show "unknown" for git hash and branch.