Skip to content

Instantly share code, notes, and snippets.

@mu88
Created April 12, 2019 14:27
Show Gist options
  • Save mu88/a8db77af7e7c66ad715bb6a6c0be4fc1 to your computer and use it in GitHub Desktop.
Save mu88/a8db77af7e7c66ad715bb6a6c0be4fc1 to your computer and use it in GitHub Desktop.
Pins and deletes old builds on TeamCity
Clear-Host
$ErrorActionPreference = 'Stop'
$BasicSecret = "MySecretBeingABase64StringContainingUsernameAndPasswordSeparatedByColon"
$TeamCityHost = "http://myTeamCityHost:1234"
$TeamCityBaseUrl = $TeamCityHost + "/httpAuth/app/rest/"
$JsonHeader = @{
"Authorization" = "Basic $BasicSecret"
"Accept" = 'application/json'
}
$PlainHeader = @{
"Authorization" = "Basic $BasicSecret"
}
function main()
{
[datetime]$EndDate = (Get-Date).AddDays(-90) # only builds older than 3 month will be analyzed
[datetime]$StartDate = "01.01.2010" # this is just an ubiqutous start date
$TimeZone = "0100"
Write-Host "Evaluation from $StartDate to $EndDate"
$DateOfFirstMonday = GetDateOfFirstMonday $StartDate
for($CurrentMonday = $DateOfFirstMonday; $CurrentMonday -lt $EndDate; $CurrentMonday = $CurrentMonday.AddDays(7))
{
$CurrentFriday = $CurrentMonday.AddDays(4)
$CurrentMondayTeamCity = GetTeamCityDate $CurrentMonday "000000" $TimeZone
$CurrentFridayTeamCity = GetTeamCityDate $CurrentFriday "235959" $TimeZone
$SuccessfulBuildsBetweenDates = GetSuccessfulBuildsBetweenDates $CurrentMondayTeamCity $CurrentFridayTeamCity
$NumberOfSuccessfulBuilds = $SuccessfulBuildsBetweenDates.Count
# Continue if there are no builds in the current week
if ($NumberOfSuccessfulBuilds -eq 0)
{
continue
}
# If there is only one successful build in this week, it will be pinned (but only if it not has been pinned before)
if ($NumberOfSuccessfulBuilds -eq 1)
{
$CurrentBuildId = $SuccessfulBuildsBetweenDates[$0].Id
$CurrentPinStatus = GetPinStatus $CurrentBuildId
if ($CurrentPinStatus -eq "False")
{
PinBuild $CurrentBuildId
}
# since there are no more builds, this week is done
continue
}
# Determine whether there is already a pinned build
$PinnedBuildId = -1
for($BuildNumber = 0; $BuildNumber -lt $NumberOfSuccessfulBuilds; $BuildNumber++)
{
$CurrentBuildId = $SuccessfulBuildsBetweenDates[$BuildNumber].Id
$CurrentPinStatus = GetPinStatus $CurrentBuildId
if ($CurrentPinStatus -eq "True")
{
$PinnedBuildId = $CurrentBuildId
break
}
}
# If there is already a pinned build, all the other builds of the week can be deleted.
# If not, the last build of the week will be pinned and all the others will be deleted
if ($PinnedBuildId -ne -1)
{
for($BuildNumber = 1; $BuildNumber -lt $NumberOfSuccessfulBuilds; $BuildNumber++)
{
$CurrentBuildId = $SuccessfulBuildsBetweenDates[$BuildNumber].Id
if ($CurrentBuildId -eq $PinnedBuildId)
{
continue
}
DeleteBuild $CurrentBuildId
}
}
else
{
# Only pin first build if it is not already pinned
$CurrentBuildId = $SuccessfulBuildsBetweenDates[0].Id
$CurrentPinStatus = GetPinStatus $CurrentBuildId
if ($CurrentPinStatus -ne "True")
{
PinBuild $CurrentBuildId
}
for($BuildNumber = 1; $BuildNumber -lt $NumberOfSuccessfulBuilds; $BuildNumber++)
{
$CurrentBuildId = $SuccessfulBuildsBetweenDates[$BuildNumber].Id
DeleteBuild $CurrentBuildId
}
}
$FailedBuildsBetweenDates = GetFailedBuildsBetweenDates $CurrentMondayTeamCity $CurrentFridayTeamCity
for($BuildNumber = 0; $BuildNumber -lt ($FailedBuildsBetweenDates.Count); $BuildNumber++)
{
DeleteBuild $FailedBuildsBetweenDates[$BuildNumber].Id
}
$CancelledBuildsBetweenDates = GetCancelledBuildsBetweenDates $CurrentMondayTeamCity $CurrentFridayTeamCity
for($BuildNumber = 0; $BuildNumber -lt ($CancelledBuildsBetweenDates.Count); $BuildNumber++)
{
DeleteBuild $CancelledBuildsBetweenDates[$BuildNumber].Id
}
}
}
function DeleteBuild($BuildId)
{
Invoke-RestMethod -Uri ($TeamCityBaseUrl + "builds/$BuildId") -Method Delete -Headers $PlainHeader
Write-Host "Build $BuildId successfully deleted"
}
function PinBuild($BuildId)
{
Invoke-RestMethod -Uri ($TeamCityBaseUrl + "builds/$BuildId/pin") -Method Put -Headers $PlainHeader -Body "True"
Write-Host "Build $BuildId successfully pinned"
}
function GetPinStatus($BuildId)
{
return (Invoke-RestMethod -Uri ($TeamCityBaseUrl + "builds/$BuildId/pin") -Method Get -Headers $PlainHeader)
}
function GetDateOfFirstMonday([datetime]$date)
{
return ($date.AddDays((-1 * ($date).DayOfWeek.Value__) + 1).Date)
}
function GetTeamCityDate([datetime]$date, $time, $zone)
{
return ($date.ToString("yyyyMMdd") + "T$time" + "%2B" + $zone)
}
function GetSuccessfulBuildsBetweenDates($start, $end)
{
return ((Invoke-RestMethod -Uri ($TeamCityBaseUrl + "builds/?locator=buildType:Vertec_InternalBuild,status:SUCCESS,startDate:(date:$start,condition:after),finishDate:(date:$end,condition:before)") -Method Get -Headers $JsonHeader)[0].build)
}
function GetCancelledBuildsBetweenDates($start, $end)
{
return ((Invoke-RestMethod -Uri ($TeamCityBaseUrl + "builds/?locator=buildType:Vertec_InternalBuild,canceled:true,startDate:(date:$start,condition:after),finishDate:(date:$end,condition:before)") -Method Get -Headers $JsonHeader)[0].build)
}
function GetFailedBuildsBetweenDates($start, $end)
{
return ((Invoke-RestMethod -Uri ($TeamCityBaseUrl + "builds/?locator=buildType:Vertec_InternalBuild,status:FAILURE,startDate:(date:$start,condition:after),finishDate:(date:$end,condition:before)") -Method Get -Headers $JsonHeader)[0].build)
}
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment