|
| 1 | +# Define the list of Azure DevOps project names |
| 2 | +$organization = "org1" |
| 3 | +$pat = "<pat>" |
| 4 | +$projects = @( |
| 5 | + [PSCustomObject]@{ |
| 6 | + name = "project1" |
| 7 | + } |
| 8 | +) |
| 9 | +$VerbosePreference = 'Continue' |
| 10 | + |
| 11 | +# Log in to Azure DevOps using PAT |
| 12 | +$env:AZURE_DEVOPS_EXT_PAT = "$pat" |
| 13 | + |
| 14 | +# Function to get all projects in the organization |
| 15 | +function Get-AdoProjects { |
| 16 | + $uri = "https://dev.azure.com/$organization/_apis/projects?api-version=6.0" |
| 17 | + $response = Invoke-RestMethod -Uri $uri -Headers @{Authorization = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$pat")) } |
| 18 | + return $response.value |
| 19 | +} |
| 20 | + |
| 21 | +# Function to get repositories for a given project |
| 22 | +function Get-AdoRepositories($project) { |
| 23 | + $uri = "https://dev.azure.com/$organization/$project/_apis/git/repositories?api-version=6.0" |
| 24 | + $uri = $uri -replace " ", "%20" |
| 25 | + $response = Invoke-RestMethod -Uri $uri -Headers @{Authorization = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$pat")) } |
| 26 | + return $response.value |
| 27 | +} |
| 28 | + |
| 29 | +# Function to get all Azure Pipelines |
| 30 | +function Get-AdoPipelines($project) { |
| 31 | + $uri = "https://dev.azure.com/$organization/$project/_apis/pipelines?api-version=6.0" |
| 32 | + $uri = $uri -replace " ", "%20" |
| 33 | + $response = Invoke-RestMethod -Uri $uri -Headers @{Authorization = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$pat")) } |
| 34 | + return $response.value |
| 35 | +} |
| 36 | + |
| 37 | +# Function to get all build policies |
| 38 | +function Get-AdoBuildPolicies($project) { |
| 39 | + $uri = "https://dev.azure.com/$organization/$project/_apis/policy/configurations?api-version=6.0" |
| 40 | + $uri = $uri -replace " ", "%20" |
| 41 | + $response = Invoke-RestMethod -Uri $uri -Headers @{Authorization = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$pat")) } |
| 42 | + return $response.value |
| 43 | +} |
| 44 | + |
| 45 | +function CreateBuildValidationPolicy($project, $repo, $buildDefinition) { |
| 46 | + # check matching policies |
| 47 | + $matchingPolicies = $buildPolicies | Where-Object { $_.settings.buildDefinitionId -eq $buildDefinition.id } |
| 48 | + if ($matchingPolicies) { |
| 49 | + Write-Verbose "Policy already exists for $($repo.name) using pipeline $($buildDefinition.name). Updating." |
| 50 | + az repos policy build update ` |
| 51 | + --id $matchingPolicies.id ` |
| 52 | + --blocking $false ` |
| 53 | + --branch main ` |
| 54 | + --build-definition-id $buildDefinition.id ` |
| 55 | + --display-name $repo.name ` |
| 56 | + --enabled $true ` |
| 57 | + --manual-queue-only $false ` |
| 58 | + --queue-on-source-update-only $false ` |
| 59 | + --repository-id $repo.id ` |
| 60 | + --valid-duration 0 ` |
| 61 | + --project $project.name |
| 62 | + |
| 63 | + # Build Validation Policy |
| 64 | + # --blocking $false - Policy Requirement: Optional |
| 65 | + # --manual-queue-only $false - Trigger: Manual |
| 66 | + # --valid-duration 0 - Build expiration: Immediately when main is updated |
| 67 | + } else { |
| 68 | + Write-Verbose "Creating build validation policy for $($repo.name) using pipeline $($buildDefinition.name)." |
| 69 | + az repos policy build create ` |
| 70 | + --blocking $false ` |
| 71 | + --branch main ` |
| 72 | + --build-definition-id $buildDefinition.id ` |
| 73 | + --display-name $repo.name ` |
| 74 | + --enabled $true ` |
| 75 | + --manual-queue-only $false ` |
| 76 | + --queue-on-source-update-only $false ` |
| 77 | + --repository-id $repo.id ` |
| 78 | + --valid-duration 0 ` |
| 79 | + --project $project.name |
| 80 | + } |
| 81 | +} |
| 82 | + |
| 83 | +# Main script |
| 84 | +Write-Verbose "Getting projects ..." |
| 85 | +if ($projects.Count -eq 0) { |
| 86 | + Write-Verbose "Getting all projects ..." |
| 87 | + $projects = Get-AdoProjects |
| 88 | +} else { |
| 89 | + Write-Verbose "Using provided project(s): $($projects.name)" |
| 90 | +} |
| 91 | +Write-Verbose "Found $($projects.Count) project(s): $($projects.name)" |
| 92 | +foreach ($project in $projects) { |
| 93 | + Write-Verbose "Getting repos for $($project.name) ..." |
| 94 | + $repos = Get-AdoRepositories -project $project.name |
| 95 | + Write-Verbose "Found $($repos.Count) repos." |
| 96 | + $pipelines = Get-AdoPipelines -project $project.name |
| 97 | + Write-Verbose "Found $($pipelines.Count) pipelines." |
| 98 | + $buildPolicies = Get-AdoBuildPolicies -project $project.name |
| 99 | + Write-Verbose "Found $($buildPolicies.Count) build policies." |
| 100 | + # Check matching pipelines |
| 101 | + $checkedRepos = $repos | Where-Object { $_.name -in $pipelines.name } |
| 102 | + Write-Verbose "Found $($checkedRepos.Count) repos with matching pipelines." |
| 103 | + |
| 104 | + Read-Host "Press Enter to continue" |
| 105 | + |
| 106 | + foreach ($repo in $repos) { |
| 107 | + $buildDefinition = $pipelines | Where-Object { $_.name -eq "$($repo.name)" } |
| 108 | + # $response = Read-Host "Do you want to create build validation for repo $($repo.name) using pipeline $($buildDefinition.name)? (y/n)" |
| 109 | + # if ($response -eq 'y') { |
| 110 | + CreateBuildValidationPolicy -repo $repo -project $project -buildDefinition $buildDefinition |
| 111 | + # } else { |
| 112 | + # Write-Verbose "Skipping $($repo.name)" |
| 113 | + # } |
| 114 | + } |
| 115 | +} |
0 commit comments