Greetings my fellow Technology Advocates and Specialists.
In this Session, I will demonstrate how to Automate Pull Request (PR) and Associate Work-Items Using Azure DevOps.
I had the Privilege to talk on this topic in TWO Azure Communities:-
NAME OF THE AZURE COMMUNITY
TYPE OF SPEAKER SESSION
Microsoft Azure Bern User Group
In-Person
Microsoft Azure Pakistan Community
Virtual
IN-PERSON SESSION:-
I presented this Demo as a part of AZURE DEVOPS: TAKEAWAYS BEST PRACTISES AND LIVE DEMOS In-Person Speaker Session in MICROSOFT AZURE BERN USER GROUP Forum/Platform.
Event Meetup Announcement:-
Moment Captured with Founders of MICROSOFT AZURE BERN USER GROUP "STEFAN JOHNER", "STEFAN ROTH", "PAUL AFFENTRANGER" and Co-organizer "DAMIEN BOWDEN":-
VIRTUAL SESSION:-
Event Meetup Announcement:-
LIVE DEMO was Recorded as part of my Presentation in MICROSOFT AZURE PAKISTAN COMMUNITY Forum/Platform
Duration of My Demo = 48 Mins 23 Secs
AUTOMATION OBJECTIVE:-
Create Random Generated Work-Items in Azure DevOps Boards.
Create Pull Request (PR).
Associate Work-Item with Pull Request (PR).
Complete Pull Request (PR) with Squash Commit.
Delete the Working Branch (For Example: "Dev" or "Feature/AM".
REQUIREMENTS:-
Azure Subscription.
Azure DevOps Organisation and Project.
Azure DevOps Personal Access Token (PAT).
Service Principal with Required RBAC ( Contributor) applied on Subscription or Resource Group(s).
Azure Resource Manager Service Connection in Azure DevOps.
Microsoft DevLabs Terraform Extension Installed in Azure DevOps.
AUTOMATE PULL REQUEST & ASSOCIATE WORK-ITEMS USING AZ DEVOPS
AUTOMATE PULL REQUEST & ASSOCIATE WORK-ITEMS USING AZ DEVOPS
Greetings my fellow Technology Advocates and Specialists.
In this Session, I will demonstrate how to Automate Pull Request (PR) and Associate Work-Items Using Azure DevOps.
I had the Privilege to talk on this topic in TWO Azure Communities:-
NAME OF THE AZURE COMMUNITY
TYPE OF SPEAKER SESSION
Microsoft Azure Bern User Group
In-Person
Microsoft Azure Pakistan Community
Virtual
IN-PERSON SESSION:-
I presented this Demo as a part of AZURE DEVOPS: TAKEAWAYS BEST PRACTISES AND LIVE DEMOS In-Person Speaker Session in MICROSOFT AZURE BERN USER GROUP Forum/Platform.
Event Meetup Announcement:-
Moment Captured with Founders of MICROSOFT AZURE BERN USER GROUP "STEFAN JOHNER", "STEFAN ROTH", "PAUL AFFENTRANGER" and Co-organizer "DAMIEN BOWDEN":-
VIRTUAL SESSION:-
Event Meetup Announcement:-
LIVE DEMO was Recorded as part of my Presentation in MICROSOFT AZURE PAKISTAN COMMUNITY Forum/Platform
Instead of using TerraformInstaller@0 YAML Task, I have specified the Full Name. This is because I have two Terraform Extensions in my DevOps Organisation and with each of the Terraform Extension, exists the Terraform Install Task
The Names of the Extensions are listed below:-
1. Terraform by Microsoft DevLabs
2. Azure Pipelines Terraform Tasks by Charles Zipp
If Full Name is not provided, then below Error is Encountered:-
DETECT TERRAFORM CHANGES:-
# Detect Terraform Changes:-
- task: PowerShell@2
name: DetectTFChanges
displayName: DETECT TERRAFORM CHANGES
inputs:
workingDirectory: '$(workingDir)'
targetType: 'inline'
script: |
Write-Host "#######################################################"
Write-Host "Intial value of variable: $(anyTfChanges)"
Write-Host "#######################################################"
$plan = $(terraform show -json tfplan | ConvertFrom-Json)
$count = $plan.resource_changes.change.actions.length
$actions = ($plan.resource_changes | where { 'no-op' -notcontains $_.change.actions }).length -ne 0
Write-Host "##vso[task.setvariable variable=anyTfChanges;isOutput=true]$actions"
Write-Host "#######################################################"
Write-Host "Are there Changes in Infrastruture: $actions"
Write-Host "#######################################################"
Write-Host "TOTAL NO OF CHANGES: $count"
Write-Host "#######################################################"
EXPLANATION:-
The Original Creator of this Powershell Script is HOUSSEM DELLAI. I modified his Script to meet my requirements. TRUE or FALSE value is returned along with Total Count of Changes observed in Terraform Plan.
DEPLOY Stage will Execute only if the following conditions are met - 1) BUILD Stage gets completed successfully. 2) Source/Working Branch NOT EQUAL to Main Branch. 3) If there are CHANGES detected in Terraform Plan.
2.
DEPLOY Stage will Execute only after Approval. The Approval is integrated with Pipeline Environment defined and applied in Deploy Stage.
3.
Download the Published Artifacts.
4.
Terraform Installer installed in Azure DevOps Build Agent.
##################################################################################################
# STAGE: CREATE PR
# CREATE AND COMPLETE PULL REQUEST BY ASSOCIATING WORKITEMS AND DELETING SOURCE BRANCH
#################################################################################################
- stage: PULL_REQUEST_ASSOCIATE_WORKITEMS
condition: |
and(succeeded(),
ne(variables['Build.SourceBranch'], 'refs/heads/main')
)
dependsOn: DEPLOY
jobs:
- job: PULL_REQUEST_WORKITEMS
displayName: CREATE PR | ASSOCIATE WORKITEMS | COMPLETE
steps:
# Download Keyvault Secrets:-
- task: AzureKeyVault@2
inputs:
azureSubscription: '$(ServiceConnection)'
KeyVaultName: '$(KV-Name)'
SecretsFilter: '*'
RunAsPreJob: false
# Install Az DevOps CLI Extension in the Build Agent:-
- task: AzureCLI@1
displayName: INSTALL DEVOPS CLI EXTENSION
inputs:
azureSubscription: '$(ServiceConnection)'
scriptType: ps
scriptLocation: inlineScript
inlineScript: |
az extension add --name azure-devops
az extension show --name azure-devops --output table
# Validate Az DevOps CLI Extension in the Build Agent:-
- task: PowerShell@2
displayName: VALIDATE AZ DEVOPS CLI
inputs:
targetType: 'inline'
script: |
az devops -h
# Set Default DevOps Organization and Project:-
- task: PowerShell@2
displayName: DEVOPS LOGIN + SET DEFAULT DEVOPS ORG & PROJECT
inputs:
targetType: 'inline'
script: |
echo "$(PAT)" | az devops login
az devops configure --defaults organization=$(DevOpsOrganisation) project=$(DevOpsProjName)
# Create Workitem + Create PR + Associate Workitem with PR + Complete the PR + Delete Source Branch:-
- task: PowerShell@2
displayName: CREATE & COMPLETE PULL REQUEST + WORKITEMS + DELETE SOURCE BRANCH
inputs:
targetType: 'inline'
script: |
Write-Host "#######################################################"
Write-Host "NAME OF THE SOURCE BRANCH: $(Build.SourceBranchName)"
Write-Host "#######################################################"
$i="PR-"
$j=Get-Random -Maximum 1000
Write-Host "###################################################"
Write-Host "WORKITEM NUMBER GENERATED IN DEVOPS BOARD: $i$j"
Write-Host "###################################################"
$wid = az boards work-item create --title $i$j --type "Issue" --query "id"
Write-Host "#######################################################"
Write-Host "WORKITEM ID is: $wid"
Write-Host "#######################################################"
$prid = az repos pr create --repository $(DevOpsRepoName) --source-branch $(Build.SourceBranchName) --target-branch $(DevOpsDestinationBranch) --work-items $wid --transition-work-items true --query "pullRequestId"
Write-Host "#######################################################"
Write-Host "PULL REQUEST ID is: $prid"
Write-Host "#######################################################"
Write-Host "##### TO BE MERGED FROM $(Build.SourceBranchName) TO Main #####"
az repos pr update --id $prid --auto-complete true --squash true --status completed --delete-source-branch true
Write-Host "##### MERGE SUCCESSFULL #####"
PULL REQUEST STAGE PERFORMS BELOW:-
##
TASKS
1.
PULL REQUEST Stage will Execute only if the following conditions are met - 1) DEPLOY Stage gets completed successfully. 2) Source/Working Branch NOT EQUAL to Main Branch.
2.
Download Secrets from Keyvault (DevOps Personal Access Token [PAT]).
3.
Install Azure DevOps CLI Extension in Build Agent.
4.
Validate Azure DevOps CLI Extension in Build Agent.
variable "rg-name" {
type = string
description = "Name of the Resource Group"
}
variable "rg-location" {
type = string
description = "Resource Group Location"
}
variable "usr-mid-name" {
type = string
description = "Name of the User Assigned Managed Identity"
}
I found a small bug in script you have declared a variable $(PlanFilename) which you are using it in terraform plan step but not using the same in DetectTFChanges step, in DetectTFChanges the name of the plan is hardcoded :)
Hi Rakesh, thank you for your inputs. I might have missed out. Itโs line 110 in my Github. I see it now.
I did a quick sanity check and no other place, I could find anything hard-coded. But if you spot, please do let me know.
Again thank you very much for having a look at my automation with eagleโs eye
Highly appreciated!!! I thank you ๐
For further actions, you may consider blocking this person and/or reporting abuse
Top comments (2)
I found a small bug in script you have declared a variable $(PlanFilename) which you are using it in terraform plan step but not using the same in DetectTFChanges step, in DetectTFChanges the name of the plan is hardcoded :)
Hi Rakesh, thank you for your inputs. I might have missed out. Itโs line 110 in my Github. I see it now.
I did a quick sanity check and no other place, I could find anything hard-coded. But if you spot, please do let me know.
Again thank you very much for having a look at my automation with eagleโs eye
Highly appreciated!!! I thank you ๐