How to Create a New Version in Git
This guide walks you through creating new versions/releases for the build-certs project using proper git workflows.
Quick Reference
# 1. Prepare for release
git status # Check current state
git add . # Stage changes
git commit -m "message" # Commit changes
# 2. Create and tag version
git tag -a v2.1.0 -m "Version 2.1.0 - Description"
git push origin main # Push commits
git push origin v2.1.0 # Push tag
# 3. Update version info in files
# Edit build-certs.sh header
# Update CHANGELOG.md
# Update README.md if needed
Detailed Step-by-Step Process
Step 1: Prepare Your Changes
Check current status:
git status git log --oneline -5 # See recent commits
Make sure you’re on the right branch:
git branch # See current branch git checkout main # Switch to main if needed
Test your changes:
./build-certs.sh --help # Test basic functionality ./build-certs.sh freepbx.conf # Test certificate generation
Step 2: Update Version Information
Update the script header in
build-certs.sh:# Change from: # build-certs.sh v2.0 # To: # build-certs.sh v2.1.0
Update CHANGELOG.md (add new section at top):
## Version 2.1.0 (2025-10-XX) ### New Features - Added feature X - Improved feature Y ### Bug Fixes - Fixed issue with Z ### Changes - Updated documentation
Update README.md if there are significant changes:
# build-certs.sh v2.1.0 — README
Step 3: Commit Your Changes
Stage all changes:
git add . # Or be selective: git add build-certs.sh CHANGELOG.md README.md
Commit with descriptive message:
git commit -m "Prepare version 2.1.0 release - Add new feature X - Fix bug Y - Update documentation - Bump version to 2.1.0"
Step 4: Create Version Tag
Create annotated tag:
git tag -a v2.1.0 -m "Version 2.1.0 - Brief description of main changes - Major feature or fix - Other important changes - Any breaking changes or notes"
Verify tag was created:
git tag -l # List all tags git show v2.1.0 # Show tag details
Step 5: Push Everything
Push commits:
git push origin main
Push tags:
git push origin v2.1.0 # Push specific tag # OR git push origin --tags # Push all tags
Step 6: Verify Release
Check remote repository:
git ls-remote --tags origin # See all remote tags
Test clean checkout:
# In a different directory: git clone /path/to/your/repo test-checkout cd test-checkout git checkout v2.1.0 ./build-certs.sh --help
Version Numbering Guidelines
Use Semantic Versioning: MAJOR.MINOR.PATCH
MAJOR (v3.0.0): Breaking changes, major rewrites
MINOR (v2.1.0): New features, backwards compatible
PATCH (v2.0.1): Bug fixes, backwards compatible
Examples for build-certs
v2.0.1: Fix typo in help text
v2.1.0: Add new
--list-certsoptionv3.0.0: Change command-line argument format
Working with Branches (Advanced)
Feature Branch Workflow
Create feature branch:
git checkout -b feature/new-validation # Make changes... git add . git commit -m "Add certificate validation feature"
Merge to main:
git checkout main git merge feature/new-validation git branch -d feature/new-validation # Delete feature branch
Then follow normal versioning steps
Release Branch Workflow
Create release branch:
git checkout -b release/v2.1.0 # Update version numbers, changelog, etc. git commit -m "Prepare v2.1.0 release"
Merge to main and tag:
git checkout main git merge release/v2.1.0 git tag -a v2.1.0 -m "Version 2.1.0" git push origin main git push origin v2.1.0
Version Control Workflows
Different projects benefit from different branching strategies. Here are the most common approaches:
Simple Workflow (Recommended for Solo Projects)
When to use: Small projects, solo development, quick iterations
# Work directly on main branch
git add .
git commit -m "Add new validation feature"
git commit -m "Fix bug in certificate parsing"
git commit -m "Update documentation"
# When ready to release
git tag -a v2.1.0 -m "Version 2.1.0 - Add validation and bug fixes"
git push origin main
git push origin v2.1.0
Pros: Simple, fast, no overhead
Cons: No development isolation, harder to manage multiple features
Feature Branch Workflow (Recommended for Team Projects)
When to use: Multiple developers, want to isolate features, code reviews
# Create feature branch for each new feature
git checkout -b feature/certificate-validation
# ... develop the feature ...
git add .
git commit -m "Add certificate validation logic"
git commit -m "Add validation tests"
# When feature is complete
git checkout main
git merge feature/certificate-validation
git branch -d feature/certificate-validation
# Repeat for other features...
git checkout -b feature/improved-logging
# ... develop ...
git checkout main
git merge feature/improved-logging
# When ready to release (after all features merged)
git tag -a v2.1.0 -m "Version 2.1.0 - Validation and logging improvements"
git push origin main
git push origin v2.1.0
Pros: Feature isolation, easy code review, parallel development
Cons: More complex, requires merge discipline
Version Branch Workflow
When to use: Major version development, long development cycles
# Create version branch for major development
git checkout -b version2
# ... develop multiple features for v2.0 ...
git commit -m "Rewrite certificate generation"
git commit -m "Add new ECC curves"
git commit -m "Improve error handling"
git commit -m "Update documentation"
# When v2.0 development is complete
git checkout main
git merge version2
git tag -a v2.0.0 -m "Version 2.0.0 - Major rewrite"
git push origin main
git push origin v2.0.0
# Option: Keep version2 branch for future v2.x work
# Or delete it: git branch -d version2
Pros: Isolates major version work, clear development focus
Cons: Can diverge significantly from main, large merges
Release Branch Workflow (GitFlow Style)
When to use: Formal release process, multiple environments, complex projects
# Normal development on main
git commit -m "Add feature A"
git commit -m "Add feature B"
# When ready to prepare release
git checkout -b release/v2.1.0
# ... make release-specific changes ...
vim build-certs.sh # Update version number
vim CHANGELOG.md # Add release notes
git commit -m "Prepare v2.1.0 release"
# Optional: Continue bug fixes on release branch
git commit -m "Fix last-minute bug"
# When release is ready
git checkout main
git merge release/v2.1.0
git tag -a v2.1.0 -m "Version 2.1.0"
git push origin main
git push origin v2.1.0
git branch -d release/v2.1.0 # Clean up
Pros: Dedicated release preparation, hotfix capability
Cons: Most complex, overhead for small projects
Choosing the Right Workflow
For build-certs Project
Based on your project characteristics:
Current State: Solo development, shell script, certificate tool
Recommendation: Feature Branch Workflow or Simple Workflow
Simple Workflow (Current Approach)
# Continue as you have been
git add .
git commit -m "Improve certificate validation"
git tag -a v2.1.0 -m "Version 2.1.0"
git push origin main && git push origin v2.1.0
Feature Branch Workflow (Recommended Evolution)
# For each improvement
git checkout -b feature/add-renewal-check
# ... work on renewal checking ...
git commit -m "Add certificate renewal checking"
git checkout main
git merge feature/add-renewal-check
git branch -d feature/add-renewal-check
# When ready for release
git checkout -b prepare-v2.1.0
vim build-certs.sh CHANGELOG.md # Update versions
git commit -m "Prepare v2.1.0 release"
git checkout main
git merge prepare-v2.1.0
git tag -a v2.1.0 -m "Version 2.1.0"
git push origin main
git push origin v2.1.0
Decision Matrix
Workflow |
Project Size |
Team Size |
Release Frequency |
Complexity |
|---|---|---|---|---|
Simple |
Small |
1 |
Any |
Low |
Feature Branch |
Any |
1-5 |
Regular |
Medium |
Version Branch |
Large |
Any |
Major versions |
Medium |
Release Branch |
Enterprise |
5+ |
Formal process |
High |
Practical Examples
Example 1: Adding New Feature with Feature Branch
# Current state: v2.1.0 released
git checkout main
git pull origin main
# Start new feature
git checkout -b feature/dry-run-mode
echo "# Add --dry-run option" >> TODO.md
git add TODO.md
git commit -m "Plan dry-run feature"
# Implement feature
vim build-certs.sh # Add dry-run functionality
git add build-certs.sh
git commit -m "Add --dry-run option for testing"
# Test and refine
git commit -m "Fix dry-run output formatting"
git commit -m "Add dry-run tests"
# Feature complete - merge to main
git checkout main
git merge feature/dry-run-mode
git branch -d feature/dry-run-mode
# Prepare release
git checkout -b prepare-v2.2.0
vim build-certs.sh CHANGELOG.md README.md
git add .
git commit -m "Prepare v2.2.0 release - Add dry-run mode"
# Release
git checkout main
git merge prepare-v2.2.0
git tag -a v2.2.0 -m "Version 2.2.0 - Add dry-run testing mode"
git push origin main
git push origin v2.2.0
git branch -d prepare-v2.2.0
Example 2: Version Branch for Major Rewrite
# Current state: v2.1.1 released
git checkout main
# Start version 3.0 development (breaking changes)
git checkout -b version3
echo "# v3.0 Planning" > V3_PLAN.md
git add V3_PLAN.md
git commit -m "Start v3.0 planning"
# Major development work
git commit -m "Rewrite config parser for YAML support"
git commit -m "Add plugin architecture"
git commit -m "Breaking: Change command line interface"
git commit -m "Add comprehensive test suite"
# Continue development over weeks/months...
git commit -m "Update all documentation for v3.0"
git commit -m "Final v3.0 testing and validation"
# When v3.0 is ready
git checkout main
git merge version3
git tag -a v3.0.0 -m "Version 3.0.0 - Major rewrite with breaking changes"
git push origin main
git push origin v3.0.0
# Keep version3 branch for future v3.x maintenance
# Or delete: git branch -d version3
Best Practices
Branch Naming Conventions
# Feature branches
feature/add-validation
feature/improve-logging
feature/yaml-config
# Version branches
version2
version3
v2-development
# Release branches
release/v2.1.0
release/v3.0.0-rc1
# Hotfix branches
hotfix/security-fix
hotfix/critical-bug
Commit Message Patterns
# Feature development
git commit -m "Add certificate validation logic"
git commit -m "Improve error messages in validation"
git commit -m "Add tests for validation feature"
# Release preparation
git commit -m "Prepare v2.1.0 release"
git commit -m "Update version to v2.1.0"
git commit -m "Add v2.1.0 changelog entries"
# Maintenance
git commit -m "Fix typo in help text"
git commit -m "Update documentation links"
Merge vs. Rebase
# Merge (preserves feature branch history)
git checkout main
git merge feature/new-validation
# Rebase (linear history, cleaner)
git checkout feature/new-validation
git rebase main
git checkout main
git merge feature/new-validation # Fast-forward merge
Common Scenarios
Fixing a Bug in Released Version
# Make the fix
git add .
git commit -m "Fix critical bug in certificate validation"
# Create patch version
git tag -a v2.0.1 -m "Version 2.0.1 - Fix certificate validation bug"
git push origin main
git push origin v2.0.1
Adding a New Feature
# Implement feature
git add .
git commit -m "Add --dry-run option for testing certificate generation"
# Update version info files (build-certs.sh, CHANGELOG.md)
git add .
git commit -m "Prepare v2.1.0 release - Add dry-run option"
# Create minor version
git tag -a v2.1.0 -m "Version 2.1.0 - Add dry-run testing option"
git push origin main
git push origin v2.1.0
Emergency Hotfix
# Create hotfix branch from latest tag
git checkout v2.0.0
git checkout -b hotfix/critical-security-fix
# Make fix
git add .
git commit -m "Fix security vulnerability in certificate validation"
# Merge back to main
git checkout main
git merge hotfix/critical-security-fix
# Create patch release
git tag -a v2.0.1 -m "Version 2.0.1 - Security fix"
git push origin main
git push origin v2.0.1
Troubleshooting
Mistake in Tag
# Delete local tag
git tag -d v2.1.0
# Delete remote tag
git push origin :refs/tags/v2.1.0
# Create new tag
git tag -a v2.1.0 -m "Corrected version message"
git push origin v2.1.0
Forgot to Update Version Numbers
# Make the updates
vim build-certs.sh CHANGELOG.md
# Amend the last commit (if not pushed yet)
git add .
git commit --amend -m "Prepare v2.1.0 release with version updates"
# Re-create tag
git tag -d v2.1.0
git tag -a v2.1.0 -m "Version 2.1.0 - Complete release"
Check What Changed Since Last Version
# See commits since last tag
git log v2.0.0..HEAD --oneline
# See file changes since last tag
git diff v2.0.0..HEAD --name-only
# Detailed diff since last tag
git diff v2.0.0..HEAD
Automation Ideas
Simple Release Script
Create scripts/release.sh:
#!/bin/bash
VERSION="$1"
if [ -z "$VERSION" ]; then
echo "Usage: $0 v2.1.0"
exit 1
fi
echo "Creating release $VERSION"
git add .
git commit -m "Prepare $VERSION release"
git tag -a "$VERSION" -m "Version $VERSION"
git push origin main
git push origin "$VERSION"
echo "Release $VERSION created!"
Usage: ./scripts/release.sh v2.1.0
Git Configuration for Modern Workflows
Setting Up Default Branch as ‘main’
To ensure all new repositories use main instead of master by default:
On Git Server (git@devel)
# Set global default branch for new repositories
git config --global init.defaultBranch main
# Verify configuration
git config --global --list | grep defaultBranch
On All Client Machines (VS Code, development hosts)
# Set global default branch for new repositories
git config --global init.defaultBranch main
# Verify configuration
git config --global --list | grep defaultBranch
For New Bare Repositories
When creating new bare repositories on the server:
# Create bare repository with main as default
git init --bare new-project.git
cd new-project.git
git symbolic-ref HEAD refs/heads/main # Explicitly set default branch
Viewing Git Configuration
# Show all Git configuration (global + local + system)
git config --list
# Show only global configuration
git config --global --list
# Show only local repository configuration
git config --local --list
# Show where each setting comes from
git config --list --show-origin
# Show specific settings
git config user.name
git config user.email
git config init.defaultBranch
What This Configuration Does
New Local Repos:
git initcreates repositories withmainbranchNew Bare Repos: Server repositories default to
mainbranchFirst Push: When you push to a new bare repo,
mainbecomes the defaultClones: New clones automatically check out the
mainbranchConsistency: All team members get the same branch naming
Verification
Test that your configuration works:
# Test local repository creation
git init test-repo
cd test-repo
git branch # Should show 'main' after first commit
# Test bare repository creation (on server)
git init --bare test-bare.git
cd test-bare.git
git symbolic-ref HEAD # Should show 'refs/heads/main'
This guide should help you create consistent, professional releases for your build-certs project!