Created
November 26, 2024 23:57
-
-
Save GFoley83/19491dacf591806036a796c4280bc2c6 to your computer and use it in GitHub Desktop.
Delete all branches X number of commits behind master
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Define variables | |
$organization = "" | |
$project = "" | |
$repositoryName = "" | |
$masterBranch = "master" | |
$devBranch = "develop" | |
$maxCommitsBehind = 500 | |
$apiKey = $env:AZURE_DEVOPS_API_KEY | |
# Validate API Key | |
if (-not $apiKey) { | |
Write-Error "Azure DevOps API Key is not set in the environment variable 'AZURE_DEVOPS_API_KEY'." | |
exit 1 | |
} | |
# Azure DevOps API base URL | |
$repositoryApiUrl = "https://dev.azure.com/$organization/$project/_apis/git/repositories?api-version=6.0" | |
# Set API headers | |
$headers = @{ | |
"Authorization" = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$apiKey")) | |
"Content-Type" = "application/json" | |
} | |
# Fetch repositories and validate existence | |
Write-Host "Validating repository existence..." -ForegroundColor Yellow | |
$repositoriesResponse = Invoke-RestMethod -Uri $repositoryApiUrl -Headers $headers -Method Get | |
# Match the repository by name | |
$repository = $repositoriesResponse.value | Where-Object { $_.name -ieq $repositoryName } | |
if (-not $repository) { | |
Write-Error "Repository with name '$repositoryName' does not exist in the project '$project'." | |
exit 1 | |
} | |
Write-Host "Repository '$repositoryName' found." -ForegroundColor Green | |
# Extract repository ID (GUID) for subsequent API calls | |
$repositoryId = $repository.id | |
Write-Host "Using Repository ID: $repositoryId" -ForegroundColor Cyan | |
# Azure DevOps repository-specific API base URL | |
$baseApiUrl = "https://dev.azure.com/$organization/$project/_apis/git/repositories/$repositoryId" | |
# Fetch all branches | |
Write-Host "Fetching all branches in repository '$repositoryName'..." -ForegroundColor Yellow | |
$branchesUrl = "$baseApiUrl/refs?filter=heads/&api-version=6.0" | |
$branchesResponse = Invoke-RestMethod -Uri $branchesUrl -Headers $headers -Method Get | |
$branches = $branchesResponse.value | |
if (-not $branches) { | |
Write-Error "No branches found in the repository '$repositoryName'." | |
exit 1 | |
} | |
# Process each branch | |
foreach ($branch in $branches) { | |
$branchName = $branch.name -replace "^refs/heads/", "" # Remove refs/heads/ prefix | |
if ($branchName -eq $masterBranch -or $branchName -eq $devBranch) { | |
Write-Host "Skipping $branchName branch..." -ForegroundColor Yellow | |
continue | |
} | |
# Compare commits between the branch and master using diffs/commits API | |
$compareUrl = "$baseApiUrl/diffs/commits?baseVersionType=branch&baseVersion=$masterBranch&targetVersionType=branch&targetVersion=$branchName&api-version=6.0" | |
try { | |
$compareResponse = Invoke-RestMethod -Uri $compareUrl -Headers $headers -Method Get | |
} catch { | |
Write-Warning "Unable to compare commits for branch: $branchName. Skipping..." | |
continue | |
} | |
if (-not $compareResponse.behindCount) { | |
Write-Warning "No commit comparison data for branch: $branchName. Skipping..." | |
continue | |
} | |
$commitsBehind = $compareResponse.behindCount | |
if ($commitsBehind -gt $maxCommitsBehind) { | |
# Prepare the delete request | |
$deleteBranchUrl = "$baseApiUrl/refs/?api-version=6.0" | |
# Get the current commit ID of the branch (oldObjectId) | |
$oldObjectId = $branch.objectId | |
# Prepare the request body as a JSON array | |
$body = ConvertTo-Json @( | |
@{ | |
name = "refs/heads/$branchName"; | |
oldObjectId = $oldObjectId; | |
newObjectId = "0000000000000000000000000000000000000000"; | |
} | |
) -Depth 10 | |
# Debug the request body | |
# Write-Host "Request Body JSON: $body" -ForegroundColor Yellow | |
try { | |
# Send the POST request to delete the branch | |
$deleteResponse = Invoke-RestMethod -Uri $deleteBranchUrl -Headers $headers -Method Post -Body $body -ContentType "application/json" -UseBasicParsing | |
Write-Host "Branch $branchName is $commitsBehind commits behind master. Deleted successfully." -ForegroundColor Red | |
} catch { | |
Write-Warning "Failed to delete branch: $branchName." | |
Write-Warning "Error details: $($_.Exception.Message)" | |
if ($_.Exception.Response -and $_.Exception.Response.Content) { | |
$reader = [System.IO.StreamReader]::new($_.Exception.Response.GetResponseStream()) | |
$responseContent = $reader.ReadToEnd() | |
Write-Warning "Response content: $responseContent" | |
} | |
} | |
} else { | |
Write-Host "Branch $branchName is only $commitsBehind commits behind master. Skipping..." -ForegroundColor Green | |
} | |
} | |
Write-Host "Branch cleanup complete." -ForegroundColor Green |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment