Azure Verified Modules
Glossary GitHub GitHub Issues Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

SNFR23 - GitHub Repo Labels

ID: SNFR23 - Category: Contribution/Support - GitHub Repo Labels

GitHub repositories where modules are held MUST use the below labels and SHOULD not use any additional labels:

These labels are available in a CSV file from here

NameDescriptionHEX
AZD 🧑‍💻These modules are requested/used by the AZD team.
E0BFFA
Needs: Attention 👋Reply has been added to issue, maintainer to review
E99695
Needs: Immediate Attention ‼️Immediate attention of module owner / AVM team is needed
FF0000
Needs: Author Feedback 👂Awaiting feedback from the issue/PR author
F18A07
Needs: External Changes ⚒️When an issue/PR requires changes that are outside of the control of the module. e.g. to an RP.
DE389D
Needs: More Evidence ⚖We are looking for more evidence to make a decision on this
F64872
Needs: Triage 🔍Maintainers need to triage still
FBCA04
Needs: Module Owner 📣In the AVM repository: this module needs an owner to develop or maintain it. In the BRM repository: the module owner needs to review a PR.
FF0019
Needs: Module Contributor 📣This module needs secondary owner(s) or contributor(s) to develop or maintain it
C95474
Needs: Core Team 🧞‍♂️This item needs the AVM Core Team to review it
DB4503
Status: Awaiting Release To Be Cut ✂️This is fixed in the main branch but not in the latest release, will be fixed with next release cut
800080
Status: Do Not Merge ⛔Do not merge PRs with this label attached as they are not ready or aligned to future direction etc.
8B4513
Status: External Contribution 🌍This is being worked on by someone outside of the AVM module owners/contributors or AVM core team
D8FA2C
Status: Fixed ✅Auto label applied when issue fixed by merged PR
90EE90
Status: Help Wanted 🆘Extra attention is needed
FF4500
Status: In Triage 🔍Picked up for triaging by an AVM core team member
D4AF37
Status: In PR 👉This is when an issue is due to be fixed in an open PR
EDEDED
Status: Invalid ❌This doesn't seem right
E4E669
Status: Long Term ⏳We will do it, but will take a longer amount of time due to complexity/priorities
B60205
Status: No Recent Activity 💤When an issue/PR has not been modified for X amount of days
808080
Status: Won't Fix 💔This will not be worked on
FFFFFF
Status: Owners Identified 🤘This module has its owners identified
FBEF2A
Status: Module Available 🟢The module is published
C8E6C9
Status: Module Orphaned 👀The module has no owner and is therefore orphaned at this time
F4A460
Status: Response Overdue 🚩When an issue/PR has not been responded to for X amount of days
850000
Status: Looking For Assistance 🦆This item is looking for anyone to help develop the code and submit a PR for resolution
03FCC2
Type: Bug 🐛Something isn't working
D73A4A
Type: CI 🚀This issue is related to the AVM CI
74CFB0
Type: Documentation 📄Improvements or additions to documentation
0075CA
Type: Duplicate 🤲This issue or pull request already exists
CFD3D7
Type: Feature Request ➕New feature or request
A2EEEF
Type: Hygiene 🧹things related to testing, issue triage etc.
17016A
Type: New Module Proposal 💡A new module for AVM is being proposed
ADD8E6
Type: Question/Feedback 🙋‍♀️Further information is requested or just some feedback
CB6BA2
Type: Security Bug 🔒This is a security bug
FFFF00
Type: AVM 🅰️ ✌️ ⓜ️This is an AVM related issue
F0FFFF
Language: Terraform 🌐This is related to the Terraform IaC language
7740B6
Language: Bicep 💪This is related to the Bicep IaC language
1D73B3
Class: Resource Module 📦This is a resource module
D3D3D3
Class: Pattern Module 📦This is a pattern module
A9A9A9
Class: Utility Module 📦This is a utility module
CAD1DE

To help apply these to a module GitHub repository you can use the below PowerShell script:

For most scenario this is the command you’ll need to call the below PowerShell script with, replacing the value for RepositoryName:

Set-AvmGitHubLabels.ps1 -RepositoryName "Org/MyGitHubRepo" -CreateCsvLabelExports $false -NoUserPrompts $true
# Linux / MacOs
# For Windows replace $PWD with your the local path or your repository
#
docker run -it -v $PWD:/repo -w /repo mcr.microsoft.com/powershell pwsh -Command '
    #Invoke-WebRequest -Uri "https://azure.github.io/Azure-Verified-Modules/scripts/Set-AvmGitHubLabels.ps1" -OutFile "Set-AvmGitHubLabels.ps1"
    $gh_version = "2.44.1"
    Invoke-WebRequest -Uri "https://github.com/cli/cli/releases/download/v2.44.1/gh_2.44.1_linux_amd64.tar.gz" -OutFile "gh_$($gh_version)_linux_amd64.tar.gz"
    apt-get update && apt-get install -y git
    tar -xzf "gh_$($gh_version)_linux_amd64.tar.gz"
    ls -lsa
    mv "gh_$($gh_version)_linux_amd64/bin/gh" /usr/local/bin/
    rm "gh_$($gh_version)_linux_amd64.tar.gz" && rm -rf "gh_$($gh_version)_linux_amd64"
    gh --version
    ls -lsa
    gh auth login
    $OrgProject = "Azure/terraform-azurerm-avm-res-kusto-cluster"
    gh auth status
    ./Set-AvmGitHubLabels.ps1 -RepositoryName $OrgProject -CreateCsvLabelExports $false -NoUserPrompts $true
  '

By default this script will only update and append labels on the repository specified. However, this can be changed by setting the parameter -UpdateAndAddLabelsOnly to $false, which will remove all the labels from the repository first and then apply the AVM labels from the CSV only.

Make sure you elevate your privilege to admin level or the labels will not be applied to your repository. Go to repos.opensource.microsoft.com/orgs/Azure/repos/ to request admin access before running the script.

Full Script:

These Set-AvmGitHubLabels.ps1 can be downloaded from here.

[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingWriteHost", "", Justification = "Coloured output required in this script")]

<#
.SYNOPSIS
  This script can be used to create the Azure Verified Modules (AVM) standard GitHub labels to a GitHub repository.

.DESCRIPTION
  This script can be used to create the Azure Verified Modules (AVM) standard GitHub labels to a GitHub repository.

  By default, the script will remove all pre-existing labels and apply the AVM 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 AVM 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 AVM 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 AVM 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/jtracey93/label-source/main/avm-github-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 AVM 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 AVM labels.

  This is useful for running the script in automation workflows

.EXAMPLE
  Create the AVM labels in the repository Org/MyGitHubRepo and remove all pre-existing labels.

  Set-AvmGitHubLabels.ps1 -RepositoryName "Org/MyGitHubRepo"

.EXAMPLE
  Create the AVM labels in the repository Org/MyGitHubRepo and do not remove any pre-existing labels, just overwrite any labels that have the same name.

  Set-AvmGitHubLabels.ps1 -RepositoryName "Org/MyGitHubRepo" -RemoveExistingLabels $false

.EXAMPLE
  Create the AVM labels in the repository Org/MyGitHubRepo and output the pre-existing and post-existing labels to the directory C:\GitHubLabels.

  Set-AvmGitHubLabels.ps1 -RepositoryName "Org/MyGitHubRepo" -OutputDirectory "C:\GitHubLabels"

.EXAMPLE
  Create the AVM 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-AvmGitHubLabels.ps1 -RepositoryName "Org/MyGitHubRepo" -OutputDirectory "C:\GitHubLabels" -RemoveExistingLabels $false

.EXAMPLE
  Create the AVM 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-AvmGitHubLabels.ps1 -RepositoryName "Org/MyGitHubRepo" -RemoveExistingLabels $false -CreateCsvLabelExports $false

.EXAMPLE
  Create the AVM 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-AvmGitHubLabels.ps1 -RepositoryName "Org/MyGitHubRepo" -OutputDirectory "C:\GitHubLabels" -RemoveExistingLabels $false -CreateCsvLabelExports $false -LabelsToApplyCsvUri "https://example.com/csv/avm-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://azure.github.io/Azure-Verified-Modules/governance/avm-standard-github-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 ($LASTEXITCODE -ne 0) {
  Write-Host $GitHubCliAuthenticated -ForegroundColor Red
  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 ($LASTEXITCODE -ne 0) {
  Write-Host $GitHubRepository -ForegroundColor Red
  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 AVM lables from the AVM labels CSV file stored on the web using the convertfrom-csv cmdlet
$avmLabelsCsv = Invoke-WebRequest -Uri $LabelsToApplyCsvUri | ConvertFrom-Csv

# Check if the AVM labels CSV file contains the following columns: Name, Description, HEX
$avmLabelsCsvColumns = $avmLabelsCsv | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name
$avmLabelsCsvColumnsValid = $avmLabelsCsvColumns -contains "Name" -and $avmLabelsCsvColumns -contains "Description" -and $avmLabelsCsvColumns -contains "HEX"
if ($false -eq $avmLabelsCsvColumnsValid) {
  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: $avmLabelsCsvColumns"
}
Write-Host "The labels CSV file contains the required columns: Name, Description, HEX" -ForegroundColor Green

# Create the AVM labels in the GitHub repository
Write-Host "Creating/Updating the $($avmLabelsCsv.Count) AVM labels in $RepositoryName..." -ForegroundColor Yellow
$avmLabelsCsv | 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 avm 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 AVM labels exist in $RepositoryName..." -ForegroundColor Yellow
  $GitHubRepositoryLabels = gh label list -R $RepositoryName -L $GitHubCliLimit --json name,description,color
  $GitHubRepositoryLabels | ConvertFrom-Json | ForEach-Object {
    if ($avmLabelsCsv.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