Versioning Schemes
Versioning Schemes are naming conventions used to identify different versions of infrastructure components. This reference documents common schemes and when to use each. Different version management patterns work best with specific schemes.
Choosing the right versioning scheme depends on your operational model and how you track component evolution. Schemes fall into two broad categories: number-based (fixed points representing immutable versions) and label-based (moving targets representing stages or channels).
You will learn
- Number-based schemes (SemVer, CalVer) create immutable version identifiers
- Label-based schemes (Maturity Levels, Environment Names) represent stages that evolve
- Different patterns work best with specific schemes
- Schemes can be mixed for different operational needs
Number-Based Schemes
Number-based schemes create fixed points - each identifier refers to a specific, immutable version. These work well with Strict Version Pinning where you need explicit version tracking.
Semantic Versioning (SemVer)
Uses MAJOR.MINOR.PATCH format (e.g., 1.2.3, 2.0.0) following semver.org conventions:
- MAJOR: Breaking changes, incompatible API changes
- MINOR: New features, backward compatible
- PATCH: Bug fixes, backward compatible
SemVer Example
When to use:
- Vendoring from external sources with semantic versioning
- Managing component libraries with clear API contracts
- Need to communicate change impact (breaking vs. non-breaking)
Examples:
vpc/1.2.3- VPC component version 1.2.3eks/2.0.0- EKS component version 2.0.0 (breaking changes from 1.x)rds/1.14.2- RDS component version 1.14.2
Calendar Versioning (CalVer)
Uses date-based formats (e.g., 2024.10.1, 2024-10-01) where version reflects when it was created:
- YYYY.MM.DD: Full date format
- YYYY.MM.MICRO: Year.Month with incrementing counter
- YY.MM: Short year and month
CalVer Example
When to use:
- Time-based release cycles (monthly updates, quarterly releases)
- Compliance requirements for temporal tracking
- Want to immediately see age of component versions
Examples:
vpc/2024.10.1- VPC component from October 2024, first releaseplatform/2024-Q4-1- Platform component from Q4 2024security/24.10- Security component from October 2024
Sequential Versioning
Simple incrementing numbers (e.g., v1, v2, v3) without semantic meaning:
Sequential Example
When to use:
- Rapid prototyping where semantic versioning is overhead
- Internal components without strict API contracts
- Simple progression without communicating change type
Examples:
vpc/v1,vpc/v2,vpc/v3app/r1,app/r2(using "r" for release)
Major/Minor Versioning
Simplified SemVer using only MAJOR.MINOR (e.g., 1.0, 2.0, 1.1):
Major/Minor Example
When to use:
- Want semantic meaning without patch-level granularity
- Smaller teams with less frequent releases
- Balance between simplicity and meaning
Examples:
vpc/1.0- VPC major version 1eks/2.1- EKS version 2.1 with enhancementsplatform/3.0- Platform version 3 (breaking changes)
Label-Based Schemes
Label-based schemes create moving targets - the label stays the same but points to different versions over time. These work well with Release Tracks/Channels where environments follow stages that evolve.
Maturity Levels
Uses stability indicators (e.g., alpha, beta, stable, rc) showing component readiness:
Maturity Levels Example
Common maturity levels:
- alpha: Experimental, frequent changes, not production-ready
- beta: Feature complete, stabilizing, release candidate
- rc (Release Candidate): Final testing before stable
- stable: Production-ready, minimal changes
- lts (Long-Term Support): Extended support window
When to use:
- Technology-focused teams comfortable with software release terms
- Need clear stability expectations independent of environments
- Components at different maturity levels
Examples:
alpha/vpc- VPC in alpha testingbeta/platform- Platform in beta stagestable/security- Stable security components
Environment Names
Uses deployment stage names (e.g., dev, staging, prod) aligned with infrastructure tiers:
Environment Names Example
Common environment names:
- dev / development: Development environment track
- staging / preprod: Pre-production validation
- prod / production: Production environment track
- sandbox: Experimental playground
- qa: Quality assurance/testing
When to use:
- Direct mapping to infrastructure environments
- Teams think in terms of deployment stages
- Idiomatic with Git Flow where branches map to environments
Examples:
dev/vpc- VPC for development environmentsstaging/platform- Platform for stagingprod/security- Security for production
Hybrid Approaches
Combining schemes for specific operational needs:
Version + Stage
Combine number with label for explicit tracking within stages:
Hybrid: Version + Stage
Date + Maturity
Combine CalVer with maturity for temporal and stability tracking:
Hybrid: Date + Maturity
When to use hybrids:
- Need both temporal tracking AND stability indication
- Complex compliance requirements
- Multiple teams with different needs
Choosing a Versioning Scheme
Consider these factors when selecting a scheme:
| Factor | Number-Based (SemVer, CalVer) | Label-Based (Maturity, Environment) |
|---|---|---|
| Immutability | Fixed versions never change | Labels point to evolving versions |
| Use Case | Strict version pinning | Release tracks/channels |
| Rollback | Pin to specific version number | Revert entire track/channel |
| Promotion | Update pins to new version | Promote version to next label |
| Overhead | Track many version numbers | Manage fewer labels |
| Pattern Fit | Strict Version Pinning | Release Tracks/Channels |
Pattern-Specific Recommendations
Different version management patterns work best with specific schemes:
- Recommended: SemVer, CalVer, Major/Minor, Sequential
- Creates immutable version folders
- Example:
vpc/1.2.3,platform/2024.10.1
- Recommended: Maturity Levels, Environment Names
- Creates moving track folders
- Example:
alpha/vpc,dev/platform
Git Flow: Branches as Channels
- Recommended: Environment Names (branches ARE environments)
- Branches carry version semantics
- Example:
channels/dev,channels/staging,channels/prod
- Recommended: Simple naming, Sequential if needed
- Explicit folder structure without complex versioning
- Example:
vpc/,eks/, orvpc-v1/,vpc-v2/
Best Practices
1. Be Consistent Within Components
Use the same scheme across all versions of a component:
# GOOD: Consistent SemVer
vpc/1.0.0/
vpc/1.1.0/
vpc/2.0.0/
# BAD: Mixing schemes
vpc/1.0.0/
vpc/stable/
vpc/2024.10/
2. Document Your Scheme
Maintain clear documentation of which schemes you're using and why:
docs/versioning-policy.md
3. Match Scheme to Operational Model
Choose schemes that align with how your team thinks about versions:
- Technology teams: Maturity Levels (alpha, beta, stable)
- Operations teams: Environment Names (dev, staging, prod)
- Compliance-driven: CalVer for temporal tracking
- Library management: SemVer for clear API contracts
4. Consider Migration Paths
Plan for scheme changes as your needs evolve:
- Start simple (Sequential, Simple folders)
- Add semantic meaning as needed (SemVer, Maturity Levels)
- Maintain backward compatibility during transitions
Summary
Versioning schemes provide naming conventions for component versions. Choose based on whether you need:
- Fixed points (SemVer, CalVer, Sequential) → Use with Strict Version Pinning
- Moving targets (Maturity Levels, Environment Names) → Use with Release Tracks/Channels
The right scheme depends on your operational model, team culture, and which version management pattern you're implementing. Start with simpler schemes and add complexity only when the benefits justify the overhead.
Different components can use different schemes based on their needs. Platform components might use SemVer while application components use maturity levels.
Related Patterns
- Strict Version Pinning - Works with number-based schemes
- Release Tracks/Channels - Works with label-based schemes
- Git Flow: Branches as Channels - Idiomatic with environment names
- Folder-Based Versioning - Works with simple naming