Wat is GitVersion?
GitVersion is een tool die automatisch Semantic Version nummers kan genereren op basis van de Git History. Een Semantic Version is als volgt opgebouwd: MAJOR.MINOR.PATCH. Hierbij wordt het Major-versie opgehoogd bij wijzigingen die ervoor zorgen dat de bestaande functionaliteit breekt. Het Minor-versie wordt opgehoogd wanneer er extra functionaliteit wordt toegevoegd, zonder dat de bestaande functionaliteit breekt. Het Patch-versie wordt opgehoogd bij bug fixes en optimalisaties die geen functionaliteit toevoegen of breken.
Wat zijn Conventional Commits?
Conventional Commits is geen tool, maar een conventie. Hierbij wordt iedere commit message voorzien van een klein beetje informatie waarmee wordt aangegeven of de commit; features, fixes, of breaking changes bevat. Zo beschrijft de prefix in de commit message `fix: dit is een bug die we hebben opgelost` dat in deze commit een fix is doorgevoerd.
De combinatie
Door deze tool en conventie te combineren kun je door het toevoegen van de juiste messages aan je commit, volledig automatisch de versies van je software releases laten genereren. Hiervoor hoef je slechts een klein stukje configuratie op te nemen in een GitVersion.yml in je git repository:
major-version-bump-message: "^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\\([\\w\\s-]*\\))?(!:|:.*\\n\\n((.+\\n)+\\n)?BREAKING CHANGE:.*)"
minor-version-bump-message: "^(feat)(\\([\\w\\s-]*\\))?:"
patch-version-bump-message: "^(build|chore|ci|docs|fix|perf|refactor|revert|style|test)(\\([\\w\\s-]*\\))?:"
Het resultaat:
# Stel, je hebt een Git repo met een tag 1.0.0
git commit -m "fix: dit is een bugfix die alleen de PATCH versie ophoogt"
# GitVersion zal als output 1.0.1 geven
git commit -m "feat: dit is een feature die de MINOR versie ophoogt"
# GitVersion zal als output 1.1.0 geven
git commit -m "feat: dit is een feature die normaal de MINOR versie ophoogt" -m "BREAKING CHANGE: maar door deze toevoeging wordt de MAJOR versie opgehoogd"
# GitVersion zal als output 2.0.0 geven
Als extra tip, gebruik pre-commit om af te dwingen dat iedere commit de conventional commits hanteert. Hiervoor kun je onderstaande configuratie opnemen in je pre-commit-config.yaml
repos:
- repo: https://github.com/compilerla/conventional-pre-commit
rev: v3.6.0
hooks:
- id: conventional-pre-commit
stages: [commit-msg]
args: [build, chore, ci, cd, docs, feat, fix, perf, refactor, revert, style, test]
CI/CD
De kunst is om dit alles volledig binnen je CI/CD pipeline af te handelen:
- Genereer een nieuwe versie met GitVersion
- Gebruik deze versie bij het bouwen van je artifact, bijvoorbeeld als tag voor je docker image of als versie die je aan gradle of poetry meegeeft.
- Leg in git een tag vast met dit versienummer
- (optioneel) maak een release binnen GitHub of Gitlab met dit versienummer
Het handmatig toekennen van versies aan software releases is verleden tijd dankzij de combinatie van GitVersion en Conventional Commits. GitVersion automatiseert het genereren van Semantic Version-nummers op basis van de Git-geschiedenis, terwijl Conventional Commits een gestandaardiseerde manier biedt om commit messages te schrijven die GitVersion kan interpreteren.