TL;DR
My aim with this post is to demonstrate and share a PowerShell script I developed for my team to minimize the time required to set up CI pipelines and other objects in an Azure DevOps project.
The script is available here : AzureDevopsProjectCreator/AzureDevopsProjectCreator.ps1 at main · jeev20/AzureDevopsProjectCreator · GitHub
Background
Back in 2020, UiPath launched an Azure DevOps integration, which is now available in its 5th iteration in the Azure DevOps marketplace UiPath Azure DevOps integration. We have been using this integration since the early days and would like to thank @ThomasStocker, @alexandru.iordan and their teams for the great work done on developing and maintaining this integration.
With time we observed that most of our developers treaded working with CI/CD merely because it took a lot of time setting things up for each project in Azure DevOps. That when this script came to life.
Prerequisites
In order to use the Azure CLI and the Azure DevOps extension, we need to install the following. The first link downloads the latest Azure CLI and the second downloads the dotnet runtime.
- https://aka.ms/installazurecliwindows
- Download .NET 5.0 Desktop Runtime (v5.0.17) - Windows x64 Installer
A visual overview of the script
graph LR
subgraph Initialize
direction TB
B[Set Arguments]
C[Set Environment Variables]
B --> C
C --> E[Configure Azure CLI \n Auto download modules]
end
subgraph CreateProject_Function
direction TB
G[Set Default Configuration \n Login to Azure DevOps]
H[Create Project]
I[Create Variable Group]
J[Create Repositories]
K[Create Build Pipelines]
L[Set Pipeline Variables]
M[Delete Orphan Repository]
G --> H --> I --> J --> K --> L --> M
end
subgraph Invoke
direction TB
T[CreateProject_Function]
end
Initialize --> CreateProject_Function
CreateProject_Function --> Invoke
Initialize
Certain basic arguments are needed to get us started.
$ProjectName
is the visual name of the project,
$Description
is a short string describing the project,
$PAT
is the Personal Access Token obtained from your Azure Devops (User Settings)
$Organization
is the URL of the Azure DevOps organization.
Note that $PAT
needs to have relevant rights to create projects and other resources within a project.
The az config set extension.use_dynamic_install=yes_without_prompt
tells the Azure CLI to install necessary extensions (in this case Azure DevOps is an extension in Azure CLI) if it is not found in the host machine.
param(
[Parameter(Mandatory=$true)]
[string]$ProjectName,
[Parameter(Mandatory=$true)]
[string]$Description,
[Parameter(Mandatory=$true)]
[string]$PAT,
[Parameter(Mandatory=$true)]
[string]$Organization
)
$env:AZURE_DEVOPS_EXT_PAT = $PAT
$ErrorActionPreference = 'SilentlyContinue'
# Configuration
az config set extension.use_dynamic_install=yes_without_prompt
Defining the function
function CreateProject{
# Set Default Configuration
az devops configure -d organization="https://dev.azure.com/organizationName"
az devops configure -d project=$ProjectName
# Login to Azure DevOps
Write-Output $env:AZURE_DEVOPS_EXT_PAT | az devops login
# Create Project
az devops project create --name $ProjectName --description $Description --process Basic --source-control git --output table
# Creating group library variables
az pipelines variable-group create --name BackupLocations --variables RPA-Robot-Dev="PATHTOFOLDER" RPA-Robot-Prod="PATHTOFOLDER"
# Creating repos within the project
az repos create --name "Dispatcher"
az repos create --name "Performer"
az repos create --name "Utils"
# Creating Build Pipelines within the project - path can be specified accordingly
az pipelines create --name "CI-Dispatcher" --description 'CI Pipeline for Dispatcher' --repository "Dispatcher" --branch main --repository-type tfsgit --yml-path "AzureDevOpsPipelines/CI_Dispatcher.yml" --skip-first-run
az pipelines create --name "CI-Performer" --description 'CI Pipeline for Performer' --repository "Performer" --branch main --repository-type tfsgit --yml-path "AzureDevOpsPipelines/CI_Performer.yml" --skip-first-run
# Creating Build Pipelines variables
az pipelines variable create --name ProjectBuildNumber --pipeline-name "CI-Dispatcher" --value "$[counter('', 1)]"
az pipelines variable create --name ProjectBuildNumber --pipeline-name "CI-Performer" --value "$[counter('', 1)]"
# Delete Orphan Repository
$reposlist = az repos list | ConvertFrom-Json
# Find the orphan repo
foreach ($repo in $reposlist)
{
if ($repo.name -eq $ProjectName)
{
Write-Host "Deleting unwanted orphan repository"
az repos delete --id $repo.id --yes # Delete the default repo and confirm
}
}
}
CreateProject
The part which makes this automation amazing is the way we can point a build definition (.yml file) when creating the pipeline.
--branch main --repository-type tfsgit --yml-path "AzureDevOpsPipelines/CI_Performer.yml" --skip-first-run
This means that the developer has full control over how the build task has to be executed by placing a CI_Performer.yml
/ CI_Dispatcher.yml
in a folder AzureDevOpsPipelines
when committing the UiPath project. For example, if the project being worked on is a library, the CI definition can mention that the output from the build task should be a UiPath library.
The --skip-first-run
ensures that the pipeline is not triggered right after we created it and will run for the first time when the developer commits code to the repo. This also avoids running a CI pipeline when the repo has zero commits nor does it have a CI build definition (yml file). In short, if this is not set, the CI will run and fail.
Invoking the script
You could chose many ways to run the above script, the two easy ways are
- Using the CLI
.\AzureDevopsProjectCreator.ps1 -ProjectName "TestProject" -Description "This is a test project" -PAT "YOURPATSTRING" -organization "https://dev.azure.com/ORGANIZATION"
- Using UiPath’s Invoke Powershell or Start Process activities.
Screenshots showing the results
How do we automate CD?
Unfortunately, unless a CI has previously run, we cannot create a CD pipeline in Azure DevOps CLI. This means that the repo needs to have a commit for the CI to trigger and for the artifact to be ready. Therefore, we still use the GUI in Azure DevOps to setup the CD pipelines to deploy automations to the UiPath Orchestrators.
References
Questions
For questions on your specific CI/CD case, kindly open a new topic and get individual support.