231 строка
13 KiB
PowerShell
231 строка
13 KiB
PowerShell
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingWriteHost", "", Justification = "Coloured output required in this script")]
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
This script can be used to create the Azure Landing Zones (ALZ) standard GitHub labels to a GitHub repository.
|
|
|
|
.DESCRIPTION
|
|
This script can be used to create the Azure Landing Zones (ALZ) standard GitHub labels to a GitHub repository.
|
|
|
|
By default, the script will remove all pre-existing labels and apply the ALZ labels. However, this can be changed by using the -RemoveExistingLabels parameter and setting it to $false. The tool will also output the labels that exist in the repository before and after the script has run to a CSV file in the current directory, or a directory specified by the -OutputDirectory parameter.
|
|
|
|
The ALZ labels to be created are documented here: TBC
|
|
|
|
.NOTES
|
|
Please ensure you have specified the GitHub repositry correctly. The script will prompt you to confirm the repository name before proceeding.
|
|
|
|
.COMPONENT
|
|
You must have the GitHub CLI installed and be authenticated to a GitHub account with access to the repository you are applying the labels to before running this script.
|
|
|
|
.LINK
|
|
TBC
|
|
|
|
.Parameter RepositoryName
|
|
The name of the GitHub repository to apply the labels to.
|
|
|
|
.Parameter RemoveExistingLabels
|
|
If set to $true, the default value, the script will remove all pre-existing labels from the repository specified in -RepositoryName before applying the ALZ labels. If set to $false, the script will not remove any pre-existing labels.
|
|
|
|
.Parameter UpdateAndAddLabelsOnly
|
|
If set to $true, the default value, the script will only update and add labels to the repository specified in -RepositoryName. If set to $false, the script will remove all pre-existing labels from the repository specified in -RepositoryName before applying the ALZ labels.
|
|
|
|
.Parameter OutputDirectory
|
|
The directory to output the pre-existing and post-existing labels to in a CSV file. The default value is the current directory.
|
|
|
|
.Parameter CreateCsvLabelExports
|
|
If set to $true, the default value, the script will output the pre-existing and post-existing labels to a CSV file in the current directory, or a directory specified by the -OutputDirectory parameter. If set to $false, the script will not output the pre-existing and post-existing labels to a CSV file.
|
|
|
|
.Parameter GitHubCliLimit
|
|
The maximum number of labels to return from the GitHub CLI. The default value is 999.
|
|
|
|
.Parameter LabelsToApplyCsvUri
|
|
The URI to the CSV file containing the labels to apply to the GitHub repository. The default value is https://raw.githubusercontent.com/Azure/Enterprise-Scale/main/utils/github/alz-repo-standard-labels.csv.
|
|
|
|
.Parameter NoUserPrompts
|
|
If set to $true, the default value, the script will not prompt the user to confirm they want to remove all pre-existing labels from the repository specified in -RepositoryName before applying the ALZ labels. If set to $false, the script will prompt the user to confirm they want to remove all pre-existing labels from the repository specified in -RepositoryName before applying the ALZ labels.
|
|
|
|
This is useful for running the script in automation workflows
|
|
|
|
.EXAMPLE
|
|
Create the ALZ labels in the repository Org/MyGitHubRepo and remove all pre-existing labels.
|
|
|
|
Set-AlzGitHubLabels.ps1 -RepositoryName "Org/MyGitHubRepo"
|
|
|
|
.EXAMPLE
|
|
Create the ALZ labels in the repository Org/MyGitHubRepo and do not remove any pre-existing labels, just overwrite any labels that have the same name.
|
|
|
|
Set-AlzGitHubLabels.ps1 -RepositoryName "Org/MyGitHubRepo" -RemoveExistingLabels $false
|
|
|
|
.EXAMPLE
|
|
Create the ALZ labels in the repository Org/MyGitHubRepo and output the pre-existing and post-existing labels to the directory C:\GitHubLabels.
|
|
|
|
Set-AlzGitHubLabels.ps1 -RepositoryName "Org/MyGitHubRepo" -OutputDirectory "C:\GitHubLabels"
|
|
|
|
.EXAMPLE
|
|
Create the ALZ labels in the repository Org/MyGitHubRepo and output the pre-existing and post-existing labels to the directory C:\GitHubLabels and do not remove any pre-existing labels, just overwrite any labels that have the same name.
|
|
|
|
Set-AlzGitHubLabels.ps1 -RepositoryName "Org/MyGitHubRepo" -OutputDirectory "C:\GitHubLabels" -RemoveExistingLabels $false
|
|
|
|
.EXAMPLE
|
|
Create the ALZ labels in the repository Org/MyGitHubRepo and do not create the pre-existing and post-existing labels CSV files and do not remove any pre-existing labels, just overwrite any labels that have the same name.
|
|
|
|
Set-AlzGitHubLabels.ps1 -RepositoryName "Org/MyGitHubRepo" -RemoveExistingLabels $false -CreateCsvLabelExports $false
|
|
|
|
.EXAMPLE
|
|
Create the ALZ labels in the repository Org/MyGitHubRepo and do not create the pre-existing and post-existing labels CSV files and do not remove any pre-existing labels, just overwrite any labels that have the same name. Finally, use a custom CSV file hosted on the internet to create the labels from.
|
|
|
|
Set-AlzGitHubLabels.ps1 -RepositoryName "Org/MyGitHubRepo" -OutputDirectory "C:\GitHubLabels" -RemoveExistingLabels $false -CreateCsvLabelExports $false -LabelsToApplyCsvUri "https://example.com/csv/alz-github-labels.csv"
|
|
|
|
#>
|
|
|
|
#Requires -PSEdition Core
|
|
|
|
[CmdletBinding()]
|
|
param (
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$RepositoryName,
|
|
|
|
[Parameter(Mandatory = $false)]
|
|
[bool]$RemoveExistingLabels = $true,
|
|
|
|
[Parameter(Mandatory = $false)]
|
|
[bool]$UpdateAndAddLabelsOnly = $true,
|
|
|
|
[Parameter(Mandatory = $false)]
|
|
[bool]$CreateCsvLabelExports = $true,
|
|
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$OutputDirectory = (Get-Location),
|
|
|
|
[Parameter(Mandatory = $false)]
|
|
[int]$GitHubCliLimit = 999,
|
|
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$LabelsToApplyCsvUri = "https://raw.githubusercontent.com/Azure/Enterprise-Scale/main/utils/github/alz-repo-standard-labels.csv",
|
|
|
|
[Parameter(Mandatory = $false)]
|
|
[bool]$NoUserPrompts = $false
|
|
)
|
|
|
|
# Check if the GitHub CLI is installed
|
|
$GitHubCliInstalled = Get-Command gh -ErrorAction SilentlyContinue
|
|
if ($null -eq $GitHubCliInstalled) {
|
|
throw "The GitHub CLI is not installed. Please install the GitHub CLI and try again."
|
|
}
|
|
Write-Host "The GitHub CLI is installed..." -ForegroundColor Green
|
|
|
|
# Check if GitHub CLI is authenticated
|
|
$GitHubCliAuthenticated = gh auth status
|
|
if ($null -eq $GitHubCliAuthenticated) {
|
|
throw "Not authenticated to GitHub. Please authenticate to GitHub using the GitHub CLI, `gh auth login`, and try again."
|
|
}
|
|
Write-Host "Authenticated to GitHub..." -ForegroundColor Green
|
|
|
|
# Check if GitHub repository name is valid
|
|
$GitHubRepositoryNameValid = $RepositoryName -match "^[a-zA-Z0-9-]+/[a-zA-Z0-9-]+$"
|
|
if ($false -eq $GitHubRepositoryNameValid) {
|
|
throw "The GitHub repository name $RepositoryName is not valid. Please check the repository name and try again. The format must be <OrgName>/<RepoName>"
|
|
}
|
|
|
|
# List GitHub repository provided and check it exists
|
|
$GitHubRepository = gh repo view $RepositoryName
|
|
if ($null -eq $GitHubRepository) {
|
|
throw "The GitHub repository $RepositoryName does not exist. Please check the repository name and try again."
|
|
}
|
|
Write-Host "The GitHub repository $RepositoryName exists..." -ForegroundColor Green
|
|
|
|
# PRE - Get the current GitHub repository labels and export to a CSV file in the current directory or where -OutputDirectory specifies if set to a valid directory path and the directory exists or can be created if it does not exist already
|
|
if ($RemoveExistingLabels -or $UpdateAndAddLabelsOnly) {
|
|
Write-Host "Getting the current GitHub repository (pre) labels for $RepositoryName..." -ForegroundColor Yellow
|
|
$GitHubRepositoryLabels = gh label list -R $RepositoryName -L $GitHubCliLimit --json name,description,color
|
|
|
|
if ($null -ne $GitHubRepositoryLabels -and $CreateCsvLabelExports -eq $true) {
|
|
$csvFileNamePathPre = "$OutputDirectory\$($RepositoryName.Replace('/', '_'))-Labels-Pre-$(Get-Date -Format FileDateTime).csv"
|
|
Write-Host "Exporting the current GitHub repository (pre) labels for $RepositoryName to $csvFileNamePathPre" -ForegroundColor Yellow
|
|
$GitHubRepositoryLabels | ConvertFrom-Json | Export-Csv -Path $csvFileNamePathPre -NoTypeInformation
|
|
}
|
|
}
|
|
|
|
# Remove all pre-existing labels if -RemoveExistingLabels is set to $true and user confirms they want to remove all pre-existing labels
|
|
if ($null -ne $GitHubRepositoryLabels) {
|
|
$GitHubRepositoryLabelsJson = $GitHubRepositoryLabels | ConvertFrom-Json
|
|
if ($RemoveExistingLabels -eq $true -and $NoUserPrompts -eq $false -and $UpdateAndAddLabelsOnly -eq $false) {
|
|
$RemoveExistingLabelsConfirmation = Read-Host "Are you sure you want to remove all $($GitHubRepositoryLabelsJson.Count) pre-existing labels from $($RepositoryName)? (Y/N)"
|
|
if ($RemoveExistingLabelsConfirmation -eq "Y") {
|
|
Write-Host "Removing all pre-existing labels from $RepositoryName..." -ForegroundColor Yellow
|
|
$GitHubRepositoryLabels | ConvertFrom-Json | ForEach-Object {
|
|
Write-Host "Removing label $($_.name) from $RepositoryName..." -ForegroundColor DarkRed
|
|
gh label delete -R $RepositoryName $_.name --yes
|
|
}
|
|
}
|
|
}
|
|
if ($RemoveExistingLabels -eq $true -and $NoUserPrompts -eq $true -and $UpdateAndAddLabelsOnly -eq $false) {
|
|
Write-Host "Removing all pre-existing labels from $RepositoryName..." -ForegroundColor Yellow
|
|
$GitHubRepositoryLabels | ConvertFrom-Json | ForEach-Object {
|
|
Write-Host "Removing label $($_.name) from $RepositoryName..." -ForegroundColor DarkRed
|
|
gh label delete -R $RepositoryName $_.name --yes
|
|
}
|
|
}
|
|
}
|
|
if ($null -eq $GitHubRepositoryLabels) {
|
|
Write-Host "No pre-existing labels to remove or not selected to be removed from $RepositoryName..." -ForegroundColor Magenta
|
|
}
|
|
|
|
# Check LabelsToApplyCsvUri is valid and contains a CSV content
|
|
Write-Host "Checking $LabelsToApplyCsvUri is valid..." -ForegroundColor Yellow
|
|
$LabelsToApplyCsvUriValid = $LabelsToApplyCsvUri -match "^https?://"
|
|
if ($false -eq $LabelsToApplyCsvUriValid) {
|
|
throw "The LabelsToApplyCsvUri $LabelsToApplyCsvUri is not valid. Please check the URI and try again. The format must be a valid URI."
|
|
}
|
|
Write-Host "The LabelsToApplyCsvUri $LabelsToApplyCsvUri is valid..." -ForegroundColor Green
|
|
|
|
# Create ALZ lables from the ALZ labels CSV file stored on the web using the convertfrom-csv cmdlet
|
|
$alzLabelsCsv = Invoke-WebRequest -Uri $LabelsToApplyCsvUri | ConvertFrom-Csv
|
|
|
|
# Check if the ALZ labels CSV file contains the following columns: Name, Description, HEX
|
|
$alzLabelsCsvColumns = $alzLabelsCsv | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name
|
|
$alzLabelsCsvColumnsValid = $alzLabelsCsvColumns -contains "Name" -and $alzLabelsCsvColumns -contains "Description" -and $alzLabelsCsvColumns -contains "HEX"
|
|
if ($false -eq $alzLabelsCsvColumnsValid) {
|
|
throw "The labels CSV file does not contain the required columns: Name, Description, HEX. Please check the CSV file and try again. It contains the following columns: $alzLabelsCsvColumns"
|
|
}
|
|
Write-Host "The labels CSV file contains the required columns: Name, Description, HEX" -ForegroundColor Green
|
|
|
|
# Create the ALZ labels in the GitHub repository
|
|
Write-Host "Creating/Updating the $($alzLabelsCsv.Count) ALZ labels in $RepositoryName..." -ForegroundColor Yellow
|
|
$alzLabelsCsv | ForEach-Object {
|
|
if ($GitHubRepositoryLabelsJson.name -contains $_.name) {
|
|
Write-Host "The label $($_.name) already exists in $RepositoryName. Updating the label to ensure description and color are consitent..." -ForegroundColor Magenta
|
|
gh label create -R $RepositoryName "$($_.name)" -c $_.HEX -d $($_.Description) --force
|
|
}
|
|
else {
|
|
Write-Host "The label $($_.name) does not exist in $RepositoryName. Creating label $($_.name) in $RepositoryName..." -ForegroundColor Cyan
|
|
gh label create -R $RepositoryName "$($_.Name)" -c $_.HEX -d $($_.Description) --force
|
|
}
|
|
}
|
|
|
|
# POST - Get the current GitHub repository labels and export to a CSV file in the current directory or where -OutputDirectory specifies if set to a valid directory path and the directory exists or can be created if it does not exist already
|
|
if ($CreateCsvLabelExports -eq $true) {
|
|
Write-Host "Getting the current GitHub repository (post) labels for $RepositoryName..." -ForegroundColor Yellow
|
|
$GitHubRepositoryLabels = gh label list -R $RepositoryName -L $GitHubCliLimit --json name,description,color
|
|
|
|
if ($null -ne $GitHubRepositoryLabels) {
|
|
$csvFileNamePathPre = "$OutputDirectory\$($RepositoryName.Replace('/', '_'))-Labels-Post-$(Get-Date -Format FileDateTime).csv"
|
|
Write-Host "Exporting the current GitHub repository (post) labels for $RepositoryName to $csvFileNamePathPre" -ForegroundColor Yellow
|
|
$GitHubRepositoryLabels | ConvertFrom-Json | Export-Csv -Path $csvFileNamePathPre -NoTypeInformation
|
|
}
|
|
}
|
|
|
|
# If -RemoveExistingLabels is set to $true and user confirms they want to remove all pre-existing labels check that only the alz labels exist in the repository
|
|
if ($RemoveExistingLabels -eq $true -and ($RemoveExistingLabelsConfirmation -eq "Y" -or $NoUserPrompts -eq $true) -and $UpdateAndAddLabelsOnly -eq $false) {
|
|
Write-Host "Checking that only the ALZ labels exist in $RepositoryName..." -ForegroundColor Yellow
|
|
$GitHubRepositoryLabels = gh label list -R $RepositoryName -L $GitHubCliLimit --json name,description,color
|
|
$GitHubRepositoryLabels | ConvertFrom-Json | ForEach-Object {
|
|
if ($alzLabelsCsv.Name -notcontains $_.name) {
|
|
throw "The label $($_.name) exists in $RepositoryName but is not in the CSV file."
|
|
}
|
|
}
|
|
Write-Host "Only the CSV labels exist in $RepositoryName..." -ForegroundColor Green
|
|
}
|
|
|
|
Write-Host "The CSV labels have been created/updated in $RepositoryName..." -ForegroundColor Green
|