Forum Discussion

bitbonk's avatar
bitbonk
Copper Contributor
Aug 14, 2022

Allow commit on protected branch by pipline

I am using on premise Azure DevOps. When a pipeline builds the actual release build, I want the pipeline to update the https://keepachangelog.com/en/1.0.0/ 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

  • ryanlalchand's avatar
    ryanlalchand
    Copper Contributor

    bitbonk 

     

    This is a https://stackoverflow.com/a/78581148/20410952 to my answer on a similar question on Stack Overflow, just in case.

     

    First, you must allow your Build Service User the https://learn.microsoft.com/en-us/azure/devops/pipelines/scripts/git-commands?view=azure-devops&tabs=yaml#grant-version-control-permissions-to-the-build-service:

    - 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 https://learn.microsoft.com/en-us/azure/devops/pipelines/scripts/git-commands?view=azure-devops&tabs=yaml#allow-scripts-to-access-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. "https://learn.microsoft.com/en-us/azure/devops/pipelines/scripts/git-commands?view=azure-devops&tabs=yaml#make-sure-to-clean-up-the-local-repo"

     

    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"
    ```

     

Resources