Allow commit on protected branch by pipline

Copper Contributor

I am using on premise Azure DevOps. When a pipeline builds the actual release build, I want the pipeline to update the CHANGELOG.md with the version and the release date directly with a new commit. But this is rejected if the branch is a protected branch. 

 

How can my pipeline running on any build agent make a commit on branch that is a protected branch?

2 Replies
Following and hoping you or someone else figured this out

@bitbonk 

 

This is a cross-post to my answer on a similar question on Stack Overflow, just in case.

 

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

6YEVooBM.png

 

 

 

 

 

 

 

 

 

 

 

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 pipeli..."

 

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 address removed for privacy reasons"
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"
```