WORKS IN 2024
Azure DevOps Pipeline solution
@Kailash Uniyal does not have enough upvotes on their answer, nor @Newteq Developer on their comment.
First, you must allow your Build Service User the correct permissions:
- Bypass policies when completing pull requests: Allow
- Bypass policies when pushing: Allow
- Contribute: Allow
- Force push (rewrite history, delete branches and tags): Allow
Microsoft documentation for the checkout step accessing the system token
The clean: true
config option for the checkout step is crucial if you are creating a git tag or doing anything that might persist. "Certain kinds of changes to the local repository aren't automatically cleaned up by the build pipeline"
This is the only approach that worked for me out of all of the answers provided in 2024. (YAML below is for a very basic custom script for incrementing semantic versioning based on merged PRs containing Conventional Commit messages).
trigger:
- main
pool:
vmImage: "ubuntu-latest"
jobs:
- job: PreMergeValidation
displayName: "Pre-Merge Validation"
condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'))
steps:
- task: PowerShell@2
inputs:
targetType: "inline"
script: |
if ($env:SYSTEM_PULLREQUEST_PULLREQUESTID) {
# PR Validation context
$url = "$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)$env:SYSTEM_TEAMPROJECTID/_apis/git/repositories/$($env:BUILD_REPOSITORY_ID)/pullRequests/$($env:SYSTEM_PULLREQUEST_PULLREQUESTID)?api-version=7.0"
$headers = @{
Authorization = "Bearer $($env:SYSTEM_ACCESSTOKEN)"
}
$pullRequestInfo = Invoke-RestMethod -Uri $url -Method 'GET' -ContentType 'application/json' -Headers $headers
# Write-Host "Pull Request Info: $($pullRequestInfo | ConvertTo-Json -Depth 100)"
$title = $pullRequestInfo.title
Write-Host "PR Title: $title"
# Regular expression for conventional commits
$regex = "^(feat|fix|docs|style|refactor|perf|test|chore|build|ci|revert|BREAKING CHANGE)(\(.+\))?!?: .+"
if ($title -notmatch $regex) {
Write-Error "PR title does not follow Conventional Commit guidelines. Please ensure the title starts with one of the allowed types (e.g., feat, fix) followed by an optional scope and a colon."
exit 1
} else {
Write-Host "PR title follows Conventional Commits format"
}
}
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
displayName: "Validate PR Title against Conventional Commits"
- job: PostMergeActions
displayName: "Post-Merge Actions"
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
steps:
- checkout: self
persistCredentials: true #Important - Persist creds to run further git command
clean: true #Important - Certain kinds of changes to the local repository aren't automatically cleaned up by the build pipeline
- task: PowerShell@2
inputs:
targetType: "inline"
script: |
git config --global user.email "[email protected]"
git config --global user.name "ADO pipeline"
# Fetch the latest changes
git fetch --all
# Ensure the branch exists and switch to it
git checkout main
# Read and increment the version number
$versionFilePath = "version.txt"
$version = Get-Content $versionFilePath
$versionParts = $version -split '\.'
$major = [int]$versionParts[0]
$minor = [int]$versionParts[1]
$patch = [int]$versionParts[2]
$commitMessage = git log -1 --pretty=%B
Write-Host "Latest commit message: $commitMessage"
if ($commitMessage -match "(?i)^Merged PR \d+: BREAKING CHANGE") {
$major++
$minor = 0
$patch = 0
} elseif ($commitMessage -match "(?i)^Merged PR \d+: feat") {
$minor++
$patch = 0
} else {
$patch++
}
# Update the version number
$newVersion = "$major.$minor.$patch"
Set-Content -Path $versionFilePath -Value $newVersion
Write-Host "Bumping version to $newVersion"
# Commit and tag the new version
git add $versionFilePath
git commit -m "chore(release): bump version to $newVersion [skip ci]"
# git tag -a "v$newVersion" -m "Release $newVersion"
# Push changes and tags
git push --follow-tags
displayName: "Validate Commit Message and Bump Version"