0

In AzureDevOps, we have three branches:

  • feature
  • develop
  • main

We create a Pull Request (PR) from feature to develop. Once the PR is complete, we create a PR from develop to main. Is there a way to create a PR from develop to main automatically when the feature to develop PR is complete?

UPDATE V1:

I added a task in YAML as follows:

    - task: PowerShell@2
      displayName: 'PowerShell Script'
      inputs:
        targetType: filePath
        filePath: ./Scripts/CreatePRBuildTask.ps1
        arguments: '-token $(System.AccessToken)'


-- CreatePRBuildTask.ps1

$user = "PrivateToken"
$branchTarget = "refs/heads/main"
$branchSource = "refs/heads/develop"
$branchTragetPath = $branchTarget -replace "refs/heads/", ""
$teamProject = "team"
$repoName = "$(Build.Repository.Name)"
$organization = "org"

$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))
 
$uriBranchStatus = "https://dev.azure.com/$organization/$teamProject/_apis/git/repositories/$repoName/stats/branches?name=$branchTragetPath&api-version=5.1"
$uriCheckActivePR = "https://dev.azure.com/$organization/$teamProject/_apis/git/repositories/$repoName/pullrequests?searchCriteria.targetRefName=$branchTarget&searchCriteria.sourceRefName=$branchSource&api-version=5.1"
$uriCreatePR = "https://dev.azure.com/$organization/$teamProject/_apis/git/repositories/$repoName/pullrequests?api-version=5.1"

$resultStatus = Invoke-RestMethod -Uri $uriBranchStatus -Method Get -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}

if ($resultStatus.behindCount -eq 0)
{
    Write-Host "Current branch contains last changes from master"
    Return
}

$resultActivePR = Invoke-RestMethod -Uri $uriCheckActivePR -Method Get -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}

if ($resultActivePR.count -gt 0) 
{
    Write-Host "PR exists already"
    Return
}

$bodyCreatePR = "{sourceRefName:'$branchSource',targetRefName:'$branchTarget',title:'Sync changes from $branchSource'}"

$result = Invoke-RestMethod -Uri $uriCreatePR -Method Post -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -Body $bodyCreatePR

Write-Host "Created PR" $result.pullRequestId

Looks like it is erroring out. What am I doing wrong?

enter image description here

UPDATE V2:

I see the script running successfully:

enter image description here

However, I see the log 'PR exists already' log even though there are no active PRs with 'develop' as source branch and 'main' as target branch.

On trying to run this part of script:

$bodyCreatePR = "{sourceRefName:'$branchSource',targetRefName:'$branchTarget',title:'Sync changes from $branchSource'}"

$result = Invoke-RestMethod -Uri $uriCreatePR -Method Post -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -Body $bodyCreatePR

Write-Host "Created PR" $result.pullRequestId

I see:

enter image description here

no pull request being created. What am I missing?

Here is my YAML file:

- task: PowerShell@2
  displayName: 'PowerShell Script'
  env:
    SYSTEM_ACCESSTOKEN: $(System.AccessToken)
  inputs:
    targetType: filePath
    filePath: ./Scripts/CreatePRBuildTask.ps1
    arguments: '-token ${{ parameters.token }}'

enter image description here

user989988
  • 3,006
  • 7
  • 44
  • 91
  • I modern world it's time to switch to trunk-based development. You don't need `develop` branch. Just merge to `main`. https://trunkbaseddevelopment.com/ – Vlad DX Mar 07 '23 at 21:26

1 Answers1

1

Out of box, no, we can not. However you can use REST Api. Here is the example of PowerShell inline script: CreatePRBuildTask.ps1

Add this step to your develop CI and change:

$branchTarget = "$(Build.SourceBranch)"
$branchSource = "refs/heads/master"
$branchTragetPath = $branchTarget -replace "refs/heads/", ""

To:

$branchTarget = "refs/heads/master"
$branchSource = "refs/heads/develop"
$branchTragetPath = $branchTarget -replace "refs/heads/", ""

Additionally, add for project build service permission "Contribute on pull requests" on your repo.

For system access token use the recommendation: System.AccessToken

- task: PowerShell@2
  displayName: 'PowerShell Script'
  env:
    SYSTEM_ACCESSTOKEN: $(System.AccessToken)
  inputs:
    targetType: filePath
    filePath: ./Scripts/CreatePRBuildTask.ps1
    arguments: '-token $(System.AccessToken)'

with custom pat:

variables:
  CUSTOM_ACCESSTOKEN: $(token)

- task: PowerShell@2
  displayName: 'PowerShell Script'
  inputs:
    targetType: filePath
    filePath: ./Scripts/CreatePRBuildTask.ps1
    arguments: '-token $(CUSTOM_ACCESSTOKEN)'
Shamrai Aleksander
  • 13,096
  • 3
  • 24
  • 31
  • Thank you! Can you please clarify what this script CreatePRBuildTask.ps1 does? Does it create PR when a build is running or when a PR is complete? – user989988 Mar 07 '23 at 21:50
  • 1
    @user989988 check this [link](https://oshamrai.wordpress.com/2019/12/27/automated-creation-of-git-pull-requests-through-azure-devops-build-pipelines/) – Shamrai Aleksander Mar 07 '23 at 22:01
  • What should I provide as $user and $token values? – user989988 Mar 07 '23 at 22:31
  • @user989988 all needed values in the script, you do not need to add additional info. it uses the build service to auth: https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#systemaccesstoken – Shamrai Aleksander Mar 07 '23 at 22:36
  • Could you please check my 'UPDATE' section in question? – user989988 Mar 09 '23 at 00:31
  • 1
    @user989988 check my updates – Shamrai Aleksander Mar 09 '23 at 08:35
  • Thank you! Now I see a different unauthorized error - Invoke-RestMethod : The remote server returned an error: (401) Unauthorized. At D:\a\1\s\Scripts\CreatePRBuildTask.ps1:15 char:17 + ... ultStatus = Invoke-RestMethod -Uri $uriBranchStatus -Method Get -Cont ... – user989988 Mar 09 '23 at 11:09
  • 1
    @user989988 you are using the strange user .... it should be `$user=""` – Shamrai Aleksander Mar 09 '23 at 11:20
  • that worked ty! I see the script running successfully however I see 'PR exists already' log even though there are no active PRs with 'develop' as source branch and 'main' as target branch. Why is that? – user989988 Mar 09 '23 at 18:17
  • @user989988 update the last string to see the result: `Write-Host "Created PR" $result`. Did you assign permissions for build service `Contribute to pull requests`? – Shamrai Aleksander Mar 09 '23 at 20:17
  • I created PAT however I still see no value in $result. This is what I see- Created PR Azure DevOps Services | Sign In – user989988 Mar 10 '23 at 00:34
  • Please let me know if you have any idea on how to resolve? – user989988 Mar 14 '23 at 17:21
  • 1
    @user989988 `Azure DevOps Services | Sign In` this message says your pat is incorrect to something wrong with authorization. Can you add to the question the resulting yaml and how you store your pat? – Shamrai Aleksander Mar 14 '23 at 18:07
  • 1
    @user989988 can you check my last version? I`ve updated my answer. – Shamrai Aleksander Mar 14 '23 at 18:45
  • I see this error: Custom.AccessToken : The term 'Custom.AccessToken' is not recognized as the name of a cmdlet, function, script file, or operable program. -token $(Custom.AccessToken) ObjectNotFound: (Custom.AccessToken:String) [], ParentContainsErrorRecordException CommandNotFoundException – user989988 Mar 14 '23 at 19:30
  • 1
    @user989988 updated. Check how to use custom secrete variables: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch#secret-variables – Shamrai Aleksander Mar 14 '23 at 20:19
  • What is the type of this token - string or object? – user989988 Mar 14 '23 at 21:11
  • 1
    @user989988 it is just a string – Shamrai Aleksander Mar 14 '23 at 21:21
  • Hmm still I see the same Azure DevOps Services | Sign In error. When I tried to print token value, it's empty. so it's not getting passed to the yaml file. :( – user989988 Mar 14 '23 at 21:29
  • @user989988 I can not find in your ps1 script where you link the token. Your script should start with `param ($token)` line – Shamrai Aleksander Mar 14 '23 at 22:03
  • Could you please answer https://stackoverflow.com/questions/76077198/is-it-possible-to-cancel-a-azure-devops-pipeline-via-powershell-script – user989988 Apr 21 '23 at 23:11