Skip to content

Instantly share code, notes, and snippets.

@grenade
Last active August 29, 2015 13:56
Show Gist options
  • Save grenade/9207677 to your computer and use it in GitHub Desktop.
Save grenade/9207677 to your computer and use it in GitHub Desktop.
Sets the AssemblyVersion, AssemblyFileVersion and AssemblyInformationalVersion using build, revision and NuGet publish history.
<#
.Synopsis
Determines the AssemblyVersion, AssemblyFileVersion and AssemblyInformationalVersion using build, revision and NuGet publish history.
.Parameter baseDir
The root directory from which to recursively search for AssemblyInfo files
When called from TeamCity, use: "%teamcity.build.checkoutDir%" or omit.
Defaults to the parent directory of the script.
.Parameter nugetExe
The full path to NuGet.exe
When called from TeamCity, use: "%teamcity.tool.NuGet.CommandLine.DEFAULT.nupkg%\tools\NuGet.exe"
Defaults to assuming that NuGet.exe can be resolved with the environment PATH variable.
.Parameter packageId
The NuGet package Id
Required parameter
.Parameter buildNumber
The build number (will be included in AssemblyInformationalVersion)
When called from TeamCity, use: "%build.number%"
Required parameter
.Parameter vcsRevision
The version control revision number or commit hash (will be included in AssemblyInformationalVersion)
When called from TeamCity, use: "%build.vcs.number%"
Required parameter
.Parameter versionSuffix
The version suffix of NuGet prerelease packages
If set, will check NuGet source for pre-release versions and will be included in AssemblyInformationalVersion
.Parameter incrementPosition
The part of the assembly version to increment (against the last published NuGet package)
Can be set to: major, minor or patch
Defaults to "patch"
.Parameter nugetSource
The url to NuGet source
Defaults to "https://nuget.org/api/v2"
.Example
-baseDir "%teamcity.build.checkoutDir%" -nugetExe "C:\tools\NuGet\NuGet.exe" -packageId %PackageId% -buildNumber %build.counter% -vcsRevision %build.vcs.number% -versionSuffix "-%Configuration%" -revisionPrefix C -nugetSource "http://%NugetHost%/api/v2" -versionFile "%teamcity.build.checkoutDir%\VersionAssemblyInfo.cs"
.Link
http://semver.org
.Link
http://stackoverflow.com/a/65062/68115
#>
param(
[string] $baseDir = (Split-Path -Parent -Path $MyInvocation.MyCommand.Definition),
[string] $nugetExe = "NuGet.exe",
[Parameter(Mandatory = $true)]
[string] $packageId,
[Parameter(Mandatory = $true)]
[string] $buildNumber,
[Parameter(Mandatory = $true)]
[string] $vcsRevision,
[string] $versionSuffix = $null,
[string] $incrementPosition = "patch",
[string] $nugetSource = "https://nuget.org/api/v2",
[string] $revisionPrefix = "sha.",
[string] $versionFile = $null,
[int] $majorDefault = 0,
[int] $minorDefault = 0,
[int] $patchDefault = 0
)
Write-Host ("`$versionSuffix: {0}" -f $versionSuffix)
Write-Host ("`$nugetSource: {0}" -f $nugetSource)
function Update-AssemblyInfo {
param(
[string] $assemblyInfoFile,
[hashtable] $parameters
)
Write-Host ("`$assemblyInfoFile: {0}" -f $assemblyInfoFile)
foreach ($key in $($parameters.Keys)) {
if ($parameters[$key] -ne $null) {
$assemblyInfo = Get-Content $assemblyInfoFile
$pattern = ('\[assembly: {0}\("(.*)"\)\]' -f $key)
$oldValue = ($assemblyInfo | Select-String -Pattern $pattern | % { $_.Matches } ).Groups[1].Value
$match = ('[assembly: {0}("{1}")]' -f $key, $oldValue)
$replace = ('[assembly: {0}("{1}")]' -f $key, $parameters[$key])
(($assemblyInfo) | ForEach-Object { % { $_ -Replace [regex]::escape($match), $replace } }) | Set-Content $assemblyInfoFile
Write-Host ("{0} changed from: '{1}', to: '{2}'." -f $key, $oldValue, $parameters[$key])
}
}
}
$nugetArgs = "list", $packageId, "-s", $nugetSource
if ($versionSuffix) { $nugetArgs += "-pre" }
try {
(& $nugetExe $nugetArgs) | Where { $_.StartsWith(("{0} " -f $packageId)) } | % { $publishedVersion = $_.Split(" ")[1] }
}
catch {
Write-Error ("Failed to query NuGet source: {0}, for package: {1}." -f $nugetSource, $packageId)
}
if (!$publishedVersion) {
Write-Host ("Assuming no published version of package id: {0}, on NuGet source: {1}." -f $packageId, $nugetSource)
$publishedVersion = ("{0}.{1}.{2}" -f $majorDefault, $minorDefault, $patchDefault)
if ($versionSuffix) {
$publishedVersion += $versionSuffix
}
}
if ($versionSuffix) {
$major, $minor, $patch, $build = $publishedVersion.Split("-")[0].Split(".")
} else {
$major, $minor, $patch, $build = $publishedVersion.Split(".")
}
Write-Host ("Incrementing {0} position of semver: {1}." -f $incrementPosition, $publishedVersion)
switch ($incrementPosition) {
"major" { $semanticVersion = ("{0}.{1}.{2}" -f (([int] $major) + 1), $minor, $patch) }
"minor" { $semanticVersion = ("{0}.{1}.{2}" -f $major, (([int] $minor) + 1), $patch) }
default { $semanticVersion = ("{0}.{1}.{2}" -f $major, $minor, (([int] $patch) + 1)) }
}
Write-Host ("New semver: [{0}]." -f $semanticVersion)
$assemblyVersion = ("{0}.{1}" -f $semanticVersion, $buildNumber)
$assemblyInformationalVersion = $semanticVersion
if ($versionSuffix) {
$assemblyInformationalVersion += $versionSuffix
}
$assemblyInformationalVersion += ("+{0}.{1}{2}" -f $buildNumber, $revisionPrefix, $vcsRevision)
$assemblyInfoValues = @{ AssemblyVersion = $assemblyVersion; AssemblyFileVersion = $assemblyVersion; AssemblyInformationalVersion = $assemblyInformationalVersion }
if ($versionFile) {
Update-AssemblyInfo $versionFile $assemblyInfoValues
}
else {
$assemblyInfoFiles = (Get-ChildItem -Path $baseDir -Filter "*AssemblyInfo*.cs" -Recurse | Select-Object FullName)
foreach ($assemblyInfoFile in $assemblyInfoFiles) {
Update-AssemblyInfo $assemblyInfoFile.FullName $assemblyInfoValues
}
}
Write-Host ("##teamcity[buildNumber '{0}']" -f $assemblyInformationalVersion)
Write-Host ("##teamcity[setParameter name='SemVer' value='{0}']" -f $semanticVersion)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment