versioning
Component Versioning Strategy
This guide covers semantic versioning for GitLab CI/CD components and version management across 70+ projects.
Semantic Versioning
GitLab CI/CD Components must use semantic versioning (SemVer) when published to the catalog.
Version Format
MAJOR.MINOR.PATCH[-PRERELEASE][+BUILDMETA]
Examples:
1.0.0 # Stable release
1.2.5 # Patch update
2.0.0 # Major version with breaking changes
3.1.0-beta.1 # Beta pre-release
3.1.0-rc.2 # Release candidate
1.4.3+20260108 # With build metadata
Version Components
MAJOR Version (X.0.0)
Increment when making incompatible API changes.
Breaking changes include:
- Removing component inputs
- Renaming component inputs
- Changing input types (string † number)
- Removing component jobs
- Changing job behavior in backward-incompatible ways
- Removing component entirely
Example:
# Version 1.x.x - Old spec: inputs: cluster_name: # Old name type: string # Version 2.0.0 - Breaking change spec: inputs: cluster: # Renamed (breaking!) type: string
MINOR Version (x.Y.0)
Increment when adding backward-compatible functionality.
Non-breaking additions include:
- Adding new optional inputs (with defaults)
- Adding new component jobs
- Adding new features that don't affect existing behavior
- Deprecating inputs (but keeping them functional)
Example:
# Version 1.0.0 spec: inputs: environment: type: string # Version 1.1.0 - New optional input spec: inputs: environment: type: string enable_monitoring: # New, optional, has default type: boolean default: false
PATCH Version (x.x.Z)
Increment when making backward-compatible bug fixes.
Patch updates include:
- Bug fixes
- Performance improvements
- Documentation updates
- Security patches (non-breaking)
- Internal refactoring
Example:
# Version 1.0.0 - Bug: timeout too short deploy: script: - timeout 60 deploy.sh # Bug: 60s too short # Version 1.0.1 - Bug fix deploy: script: - timeout 300 deploy.sh # Fixed: 300s timeout
Pre-Release Versions
Used for testing before stable release:
1.0.0-alpha.1 # Early alpha
1.0.0-beta.1 # Feature-complete beta
1.0.0-rc.1 # Release candidate
1.0.0 # Stable release
Precedence:
1.0.0-alpha.1 < 1.0.0-beta.1 < 1.0.0-rc.1 < 1.0.0
Version References
Exact Version (Recommended for Production)
component: gitlab.com/org/comp/deploy@1.2.3
Use when:
- Production environments
- Critical pipelines
- Strict change control required
Pros: Predictable, no surprises Cons: Manual updates needed
Partial Version (Latest Patch)
component: gitlab.com/org/comp/deploy@~1.2
Selects the latest 1.2.x version (e.g., 1.2.0, 1.2.1, 1.2.2).
Use when:
- Staging environments
- Want automatic bug fixes
- Trust component maintainers
Pros: Auto-receive patch updates Cons: Could introduce unintended behavior changes
Partial Version (Latest Minor)
component: gitlab.com/org/comp/deploy@~1
Selects the latest 1.x.x version (e.g., 1.0.0, 1.5.2, 1.9.8).
Use when:
- Development environments
- Want new features automatically
- Experimental pipelines
Pros: Auto-receive features and bug fixes Cons: Higher risk of unexpected behavior
Latest Version
component: gitlab.com/org/comp/deploy@~latest
Selects the absolute latest version in the catalog.
Use when:
- Local development only
- Testing component updates
- Temporary pipelines
Pros: Always cutting edge Cons: Extremely risky, can break anytime
** Never use ~latest in production!**
Commit SHA
component: gitlab.com/org/comp/deploy@e3262fdd0914fa823210cdb79a8c421e2cef79d8
Use when:
- Testing unreleased component changes
- Debugging specific commits
- Pre-release validation
Pros: Exact commit reference Cons: Not discoverable in catalog, manual management
Version Strategy by Environment
Production Strategy
# .gitlab-ci.yml (production) # Pin to exact stable version deploy-production: include: - component: gitlab.com/org/comp/k8s-deploy@2.1.5 inputs: environment: production replicas: 10 rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
Policy:
- Exact version only
- Update after thorough testing
- Require approval for version changes
- Document version change in MR
Staging Strategy
# .gitlab-ci.yml (staging) # Use latest patch version deploy-staging: include: - component: gitlab.com/org/comp/k8s-deploy@~2.1 inputs: environment: staging replicas: 3 rules: - if: $CI_COMMIT_BRANCH == "staging"
Policy:
- Latest patch in minor version series
- Automatically receive bug fixes
- Test ground for production updates
Development Strategy
# .gitlab-ci.yml (development) # Use latest minor version deploy-dev: include: - component: gitlab.com/org/comp/k8s-deploy@~2 inputs: environment: development replicas: 1 rules: - if: $CI_MERGE_REQUEST_IID
Policy:
- Latest minor version
- Early exposure to new features
- Catch issues before staging/production
Version Lifecycle
Stage 1: Development
Pre-release versions for testing:
# Alpha: Early testing git tag 2.0.0-alpha.1 git push origin 2.0.0-alpha.1 # Beta: Feature-complete, testing git tag 2.0.0-beta.1 git push origin 2.0.0-beta.1 # RC: Final testing before release git tag 2.0.0-rc.1 git push origin 2.0.0-rc.1
Testing projects use pre-release versions:
# test-project/.gitlab-ci.yml include: - component: gitlab.com/org/comp/deploy@2.0.0-beta.1
Stage 2: Stable Release
Release stable version:
git tag 2.0.0 git push origin 2.0.0
Announce to teams:
# Component v2.0.0 Released Stable release available. Ready for gradual rollout. **Breaking changes:** - Input `cluster_name` renamed to `cluster` **New features:** - Helm support - Auto-rollback on failure **Migration guide:** See docs/migration-v1-to-v2.md
Stage 3: Active Support
Patch versions for bug fixes:
# Bug fix git tag 2.0.1 git push origin 2.0.1 # Security patch git tag 2.0.2 git push origin 2.0.2 # Performance improvement git tag 2.0.3 git push origin 2.0.3
Projects using ~2.0 automatically receive patches.
Stage 4: Maintenance
Minor version released, previous enters maintenance:
# New minor version git tag 2.1.0 git push origin 2.1.0
Version 2.0.x enters maintenance mode:
- Security patches only
- Critical bug fixes only
- No new features
Stage 5: Deprecated
Announce deprecation with migration deadline:
# Version 2.0.x Deprecation Notice **Deprecated:** 2.0.x series **Replacement:** 2.1.x or 3.0.x **End of Support:** 2026-06-01 (90 days) **Support Status:** Security patches only Please migrate to 2.1.x or 3.0.x before EOL.
Stage 6: End of Life (EOL)
Version no longer supported:
# Version 2.0.x End of Life **EOL Date:** 2026-06-01 **Status:** No support, no patches **Action Required:** Migrate to 2.1.x or 3.0.x immediately Projects still using 2.0.x: - [ ] legacy-project-1 - [ ] legacy-project-2
Remove from catalog (optional):
# Yank version if security risk glab release delete 2.0.5 --repo org/gitlab_components
Version Support Policy
Support Tiers
| Version | Status | Support Level | Duration |
|---|---|---|---|
| Current | Active | Full support | Until next minor |
| Previous | Maintenance | Security + Critical | 6 months |
| Older | Deprecated | Security only | 3 months |
| EOL | Unsupported | None | N/A |
Example Timeline
2025-12-01: v2.0.0 released (Current)
2026-03-01: v2.1.0 released
- v2.1.0 becomes Current
- v2.0.x enters Maintenance (security + critical bugs)
2026-06-01: v2.2.0 released
- v2.2.0 becomes Current
- v2.1.x enters Maintenance
- v2.0.x enters Deprecated (security only)
2026-09-01: v2.0.x EOL
- v2.0.x no longer supported
- All projects must be on v2.1.x or v2.2.x
Version Change Management
CHANGELOG.md
Maintain comprehensive changelog:
# Changelog All notable changes to gitlab_components documented here. Format: [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) Versioning: [Semantic Versioning](https://semver.org/spec/v2.0.0.html) ## [Unreleased] ### Added - New terraform component for infrastructure deployment ## [2.1.0] - 2026-03-01 ### Added - Helm deployment component - Auto-rollback feature in k8s-deploy - Monitoring integration for all deploy components ### Changed - Improved error messages in docker-build - Performance: 30% faster Docker builds ### Deprecated - `cluster_name` input (use `cluster` instead) ### Fixed - Bug: k8s-deploy timeout too short - Bug: docker-build failed with multi-stage Dockerfiles ### Security - Updated base images to address CVE-2026-12345 ## [2.0.0] - 2025-12-01 ### Added - Complete rewrite with semantic versioning - Typed inputs with validation - Published to CI/CD Catalog ### Changed - **BREAKING**: All components now require semantic version references - **BREAKING**: Renamed `cluster_name` to `cluster` ### Removed - **BREAKING**: Removed deprecated v1 components ## [1.9.5] - 2025-11-15 ### Fixed - Final bug fixes before v2.0.0 [Unreleased]: https://gitlab.com/org/comp/compare/2.1.0...HEAD [2.1.0]: https://gitlab.com/org/comp/compare/2.0.0...2.1.0 [2.0.0]: https://gitlab.com/org/comp/compare/1.9.5...2.0.0 [1.9.5]: https://gitlab.com/org/comp/releases/1.9.5
Migration Guides
Provide detailed migration docs:
# Migration Guide: v1.x to v2.0 ## Overview Version 2.0 introduces breaking changes. This guide helps migrate. ## Breaking Changes ### 1. Component References **Before (v1.x):** ```yaml include: - project: org/components ref: main file: templates/deploy.yml
After (v2.0):
include: - component: gitlab.com/org/components/deploy@2.0.0
2. Input Names
Before (v1.x):
variables: CLUSTER_NAME: production NAMESPACE_NAME: app
After (v2.0):
include: - component: gitlab.com/org/components/k8s-deploy@2.0.0 inputs: cluster: production # Renamed from cluster_name namespace: app # Renamed from namespace_name
3. Removed Components
The following components were removed:
legacy-deploy† Usek8s-deployinsteadold-build† Usedocker-buildinstead
Step-by-Step Migration
Step 1: Update Component References
Replace project includes with component syntax.
Step 2: Rename Inputs
Update all renamed inputs per table above.
Step 3: Test in Development
Test updated pipeline in development environment.
Step 4: Deploy to Staging
After dev validation, deploy to staging.
Step 5: Deploy to Production
After staging validation, deploy to production.
Need Help?
- Slack: #gitlab-components
- Issues: https://gitlab.com/org/components/issues
- Migration support: @platform-team
## Automated Version Management
### Semantic Release Integration
```yaml
# .gitlab-ci.yml
release:
stage: release
image: node:20
script:
# semantic-release automatically:
# - Analyzes commits
# - Determines version bump
# - Generates changelog
# - Creates git tag
# - Publishes release
- npx semantic-release
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
// .releaserc.json { "branches": ["main"], "plugins": [ ["@semantic-release/commit-analyzer", { "preset": "conventionalcommits", "releaseRules": [ {"type": "feat", "release": "minor"}, {"type": "fix", "release": "patch"}, {"type": "perf", "release": "patch"}, {"type": "docs", "release": false}, {"breaking": true, "release": "major"} ] }], "@semantic-release/release-notes-generator", "@semantic-release/changelog", "@semantic-release/gitlab" ] }
Conventional Commits
Use conventional commits to auto-determine version bumps:
# Patch version (1.0.0 † 1.0.1) git commit -m "fix: correct timeout in k8s-deploy" # Minor version (1.0.1 † 1.1.0) git commit -m "feat: add Helm deployment component" # Major version (1.1.0 † 2.0.0) git commit -m "feat!: rename cluster_name to cluster BREAKING CHANGE: Input cluster_name renamed to cluster"
Version Bump Calculator
// calculate-version-bump.ts import { parseCommits } from './git-utils'; interface VersionBump { current: string; next: string; type: 'major' | 'minor' | 'patch'; commits: string[]; } function calculateVersionBump( currentVersion: string, commitsSinceLastRelease: string[] ): VersionBump { const commits = parseCommits(commitsSinceLastRelease); // Check for breaking changes if (commits.some(c => c.breaking)) { return { current: currentVersion, next: bumpMajor(currentVersion), type: 'major', commits: commits.filter(c => c.breaking).map(c => c.message) }; } // Check for features if (commits.some(c => c.type === 'feat')) { return { current: currentVersion, next: bumpMinor(currentVersion), type: 'minor', commits: commits.filter(c => c.type === 'feat').map(c => c.message) }; } // Default to patch return { current: currentVersion, next: bumpPatch(currentVersion), type: 'patch', commits: commits.filter(c => c.type === 'fix').map(c => c.message) }; }
Version Compliance
Enforcement Policies
Policy 1: Production must use exact versions
# GitLab CI/CD compliance check check-production-versions: stage: validate script: - | if [ "$CI_ENVIRONMENT_NAME" = "production" ]; then # Fail if using ~latest or partial versions if grep -E 'component:.*@~' .gitlab-ci.yml; then echo "ERROR: Production must use exact versions" exit 1 fi fi
Policy 2: No deprecated versions
check-deprecated-versions: stage: validate script: - | # Fail if using deprecated version if grep 'component:.*@1\.' .gitlab-ci.yml; then echo "ERROR: Version 1.x is deprecated (EOL: 2026-01-01)" echo "Please upgrade to 2.x" exit 1 fi
Version Audit Report
// audit-component-versions.ts interface VersionAudit { project: string; components: ComponentUsage[]; compliance: { production_exact_version: boolean; no_deprecated_versions: boolean; latest_available: string; current_version: string; needs_update: boolean; }; } async function auditProject(project: string): Promise<VersionAudit> { const ciConfig = await fetchCIConfig(project); const components = extractComponents(ciConfig); return { project, components, compliance: { production_exact_version: checkExactVersions(components), no_deprecated_versions: checkNoDeprecated(components), latest_available: await fetchLatestVersion(), current_version: components[0].version, needs_update: compareVersions(components[0].version, latestVersion) < 0 } }; } // Generate report for all 70 projects const audits = await Promise.all( projects.map(p => auditProject(p)) ); // Alert on non-compliance const nonCompliant = audits.filter(a => !a.compliance.no_deprecated_versions); if (nonCompliant.length > 0) { await sendAlert(`${nonCompliant.length} projects using deprecated versions`); }
Best Practices
DO:
- Use semantic versioning - Required for GitLab catalog
- Pin production versions - Exact versions only
- Automate version bumps - Use semantic-release
- Maintain changelog - Document all changes
- Provide migration guides - Help users upgrade
- Support multiple versions - Maintain 2-3 versions
- Communicate changes - Announce releases clearly
- Test before release - Use beta/RC versions
- Follow conventions - Conventional commits
- Deprecate gracefully - Give 90 days notice
DON'T:
- Don't use
~latestin production - Too risky - Don't break compatibility without major bump - Follow semver
- Don't skip versions - 1.0.0 † 3.0.0 confuses users
- Don't reuse tags - Never delete and recreate tags
- Don't force updates - Let projects upgrade at their pace
- Don't forget documentation - Always update README
- Don't rush releases - Test thoroughly
- Don't ignore feedback - Listen to beta testers
- Don't support too many versions - Maintenance burden
- Don't surprise users - Communicate breaking changes early
Next Steps
- Governance: Change approval and management processes
- Patterns: Common component patterns and use cases
- Testing: Component testing strategies