Created
November 14, 2016 00:46
-
-
Save phofman/12f2f5370d0e17fb2a12a5a0bbd515cd to your computer and use it in GitHub Desktop.
Script for TeamCity to update assembly-version on each build.
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
<# | |
.SYNOPSIS | |
Script for TeamCity to update assembly-version on each build. | |
.DESCRIPTION | |
PowerShell helper script to be consumed by TeamCity. It is capable of updating AssemblyInfo.cs | |
and AssemblyCommonInfo.cs in searching of 'AssemblyVersion' attribute. It can do a full or partial | |
replace, later print new version into a specified text file and in way recognized by TeamCity itself | |
so it's picked up and displayed there too. | |
.EXAMPLE | |
T:\> Update-BuildNumber -BuildRevision %build.counter% | |
Updates program's assembly and assembly-file version's last chunk with current unique build counter | |
given by TeamCity on build start. | |
.EXAMPLE | |
T:\> Update-BuildNumber -BuildRevision 11 -SkipAssemblyFileUpdate $True | |
Update program's assembly version's last chunk with '11' and leaves the assembly-file version as it was before. | |
.NOTES | |
Author: Paweł Hofman (CodeTitans 2016) | |
#> | |
Param( | |
[ValidateNotNullOrEmpty()] | |
[string]$ProjectName = ('App'), | |
[string]$ProjectPath = $null, | |
[int32]$BuildMajor = -1, | |
[int32]$BuildMinor = -1, | |
[int32]$BuildNumber = -1, | |
[int32]$BuildRevision = 0, | |
[bool]$ForceZeros = $False, | |
[bool]$SkipAssemblyVersionUpdate = $False, | |
[bool]$SkipAssemblyFileVersionUpdate = $False, | |
[bool]$SkipTeamCity = $False, | |
[string]$VersionOutputFile=('src\App\undefined.txt') | |
) | |
########################################## | |
# Setup global parameters | |
# Stop on each error inside the script | |
$ErrorActionPreference = "Stop" | |
# Set the path to projects, assumption is this script | |
# is located inside the 'scripts' folder while application sources | |
# are under 'src' | |
$SolutionDir = $path=$pwd.Path + '\..' | |
if ($ProjectPath -eq $null) | |
{ | |
$ProjectDir = $SolutionDir + '\src\' + $ProjectName | |
} | |
else | |
{ | |
$ProjectDir = $SolutionDir + '\' + $ProjectPath | |
} | |
# Check wether there is expected content | |
Function Private:Check-AssemblyInfoContent([string]$fileName) | |
{ | |
# Assume the file is under 'Properties' subfolder of the project | |
$fullFileName = $ProjectDir + '\Properties\' + $fileName; | |
#Write-Host "Looking for file: $fullFileName" | |
if (![System.IO.File]::Exists($fullFileName)) | |
{ | |
$fullFileName = $SolutionDir + '\' + $fileName | |
if (![System.IO.File]::Exists($fullFileName)) | |
{ | |
return $null | |
} | |
} | |
# Check if expected content is inside | |
$content = Get-Content $fullFileName | |
$count = ($content | Select-String -pattern "AssemblyVersion").Count | |
if ($count -eq 0) | |
{ | |
return $null | |
} | |
return $fullFileName | |
} | |
Function Get-DefaultBuildNumber() | |
{ | |
# by default Visual Studio gets the number of days since the beginning of the century: | |
return [string][int]((Get-Date -Date (Get-Date -Format d)) - (Get-Date -Date '2000-01-01')).TotalDays | |
} | |
############################################################################################################# | |
$AssemblyInfoFile = Check-AssemblyInfoContent 'GlobalAssemblyInfo.cs' | |
if ($AssemblyInfoFile -eq $null) | |
{ | |
$AssemblyInfoFile = Check-AssemblyInfoContent 'AssemblyInfo.cs' | |
} | |
if ($AssemblyInfoFile -eq $null) | |
{ | |
$AssemblyInfoFile = Check-AssemblyInfoContent 'AssemblyCommonInfo.cs' | |
} | |
if ($AssemblyInfoFile -eq $null) | |
{ | |
$AssemblyInfoFile = Check-AssemblyInfoContent 'AssemblyInfo.Common.cs' | |
} | |
# Test for input file: | |
if (![System.IO.File]::Exists($AssemblyInfoFile)) | |
{ | |
Write-Error "Unable to find assembly version file for project '$ProjectName'!" | |
Exit 1 | |
} | |
# Scan an assembly-info file to look for existing version value: | |
$content = Get-Content $AssemblyInfoFile | |
$version = $content | Select-String -pattern "AssemblyVersion" | Out-String | |
#$version | Foreach-Object { Write-Host $_ } | |
$version -imatch '\s*\[assembly:\s*AssemblyVersion\s*\(\s*"(?<major>[0-9]+)\.(?<minor>[0-9]+)\.(?<number>[0-9]+)\.(?<revision>[0-9]+)"\s*\)\s*\]' | Out-Null | |
if ($matches -eq $null) | |
{ | |
$version -imatch '\s*\[assembly:\s*AssemblyVersion\s*\(\s*"(?<major>[0-9]+)\.(?<minor>[0-9]+)\.\*"\s*\)\s*\]' | Out-Null | |
if ($matches -eq $null) | |
{ | |
Write-Error 'Unable to find correct assembly version!' | |
Exit 2 | |
} | |
else | |
{ | |
$FoundMajor = $matches["major"] | |
$FoundMinor = $matches["minor"] | |
$FoundNumber = Get-DefaultBuildNumber | |
$FoundRevision = 0 | |
} | |
} | |
else | |
{ | |
$FoundMajor = $matches["major"] | |
$FoundMinor = $matches["minor"] | |
$FoundNumber = $matches["number"] | |
$FoundRevision = $matches["revision"] | |
} | |
############################################################################################################# | |
# Reuse or replace existing value: | |
if ($BuildMajor -gt 0) | |
{ | |
$FoundMajor = $BuildMajor | |
} | |
if ($BuildMinor -gt 0) | |
{ | |
$FoundMinor = $BuildMinor | |
} | |
if ($BuildNumber -ge 0) | |
{ | |
if ($BuildNumber -eq 0) | |
{ | |
$FoundNumber = Get-DefaultBuildNumber | |
} | |
else | |
{ | |
$FoundNumber = $BuildNumber | |
} | |
} | |
if ($BuildRevision -le 0) | |
{ | |
$BuildRevision = $FoundRevision | |
} | |
# Calculate new build number: | |
if ($ForceZeros) | |
{ | |
$VersionText = "{0}.{1}.{2}.{3}" -f "0","0","0",$BuildRevision | |
} | |
else | |
{ | |
$VersionText = "{0}.{1}.{2}.{3}" -f $FoundMajor,$FoundMinor,$FoundNumber,$BuildRevision | |
} | |
############################################################################################################# | |
# Update the AssemblyInfo.cs file, if required: | |
if (!$SkipAssemblyVersionUpdate) | |
{ | |
$replacementVersion = 'AssemblyVersion("{0}")' -f $VersionText | |
$content = $content -Replace 'AssemblyVersion\s*\(\s*"\S+"\s*\)', $replacementVersion | |
} | |
if (!$SkipAssemblyFileVersionUpdate) | |
{ | |
$replacementFileVersion = 'AssemblyFileVersion("{0}")' -f $VersionText | |
$content = $content -Replace 'AssemblyFileVersion\s*\(\s*"\S+"\s*\)', $replacementFileVersion | |
} | |
if (!$SkipAssemblyVersionUpdate -Or !$SkipAssemblyFileVersionUpdate) | |
{ | |
$content | Out-File $AssemblyInfoFile | |
} | |
# Inform TeamCity about new build numer: | |
if (!$SkipTeamCity) | |
{ | |
"##teamcity[buildNumber '{0}']" -f $VersionText | |
} | |
############################################################################################################# | |
# Test for output file: | |
if (![System.IO.File]::Exists($VersionOutputFile)) | |
{ | |
$VersionOutputFile = $SolutionDir + '\' + $VersionOutputFile | |
} | |
# Save the same version number to specified content-output file (especially useful, when need to check version via HTTP): | |
if ([System.IO.File]::Exists($VersionOutputFile)) | |
{ | |
$versionOutputContent = Get-Content $VersionOutputFile | |
$replacementVersion = 'version=' + $VersionText | |
$versionOutputContent = $versionOutputContent -Replace 'version\s*=\s*\S+\s*', $replacementVersion | |
$versionOutputContent | Out-File $VersionOutputFile | |
# Write-Host $VersionOutputContent | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment