Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added GitVersion meta-runner #32

Merged
merged 3 commits into from
Jul 21, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 165 additions & 0 deletions gitversion/MR_GitVersion.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
<?xml version="1.0" encoding="UTF-8"?>
<meta-runner name="GitVersion">
<description>Execute GitVersion</description>
<settings>
<parameters>
<param name="mr.GitVersion.gitCheckoutDir" value="" spec="text description='The directory containing .git relative to the working directory. Leave blank for the working directory itself.' display='normal' label='Git Repository Directory:'" />
<param name="mr.GitVersion.output" value="buildserver" spec="checkbox checkedValue='buildserver' description='Update the TeamCity build number or output JSON?' display='normal' label='Update TeamCity build version:' uncheckedValue='json'" />
<param name="mr.GitVersion.outputFile" value="" spec="text description='Optional path to a file relative to the working directory to output the json into if you selected JSON above.' display='normal' label='Json output file:'" />
<param name="mr.GitVersion.url" value="" spec="text description='Optional URL to remote git repository if you have not already checked one out.' display='normal' label='Remote Git Repository:'" />
<param name="mr.GitVersion.branch" value="" spec="text description='Remote branch to use.' display='normal' label='Remote Git Branch:'" />
<param name="mr.GitVersion.username" value="" spec="text description='Remote git repo username (if private).' display='normal' label='Remote Git Username:'" />
<param name="mr.GitVersion.password" value="" spec="text description='Remote git repo password (if private).' display='normal' label='Remote Git Password:'" />
<param name="mr.GitVersion.logFile" value="" spec="text description='Optional path to a file relative to the working directory to log output messages to.' display='normal' label='Log File:'" />
<param name="mr.GitVersion.exec" value="" spec="text description='Optional executable relative to the working directory to run using GitVersion - environment vars will be available to the process.' display='normal' label='Executable:'" />
<param name="mr.GitVersion.execArgs" value="" spec="text description='If an Executable is specified then arguments to pass to the executable.' display='normal' label='Executable Arguments:'" />
<param name="mr.GitVersion.proj" value="" spec="text description='Optional MSBuild file relative to the working directory to run using GitVersion - environment vars will be available to the process.' display='normal' label='MSBuild File:'" />
<param name="mr.GitVersion.projArgs" value="" spec="text description='If an MSBuild file is specified then arguments to pass to MSBuild.' display='normal' label='MSBuild Arguments:'" />
<param name="mr.GitVersion.updateAssemblyInfo" value="false" spec="checkbox checkedValue='true' description='Update any AssemblyInfo files while running the Executable or MSBuild file?' display='normal' label='Update AssemblyInfo Files:' uncheckedValue='false'" />
</parameters>
<build-runners>
<runner name="GitVersion" type="jetbrains_powershell">
<parameters>
<param name="jetbrains_powershell_execution" value="PS1" />
<param name="jetbrains_powershell_noprofile" value="true" />
<param name="jetbrains_powershell_errorToError" value="error" />
<param name="jetbrains_powershell_script_mode" value="CODE" />
<param name="jetbrains_powershell_bitness" value="x86" />
<param name="teamcity.step.mode" value="default" />
<param name="jetbrains_powershell_script_code"><![CDATA[
[CmdletBinding()]
Param (
[string] $workingDir = (Join-Path "%teamcity.build.workingDir%" "%mr.GitVersion.gitCheckoutDir%"),
[string] $output = "%mr.GitVersion.output%",
[string] $outputFile = "%mr.GitVersion.outputFile%",
[string] $url = "%mr.GitVersion.url%",
[string] $branch = "%mr.GitVersion.branch%",
[string] $username = "%mr.GitVersion.username%",
[string] $password = "%mr.GitVersion.password%",
[string] $logFile = "%mr.GitVersion.logFile%",
[string] $exec = "%mr.GitVersion.exec%",
[string] $execArgs = "%mr.GitVersion.execArgs%",
[string] $proj = "%mr.GitVersion.proj%",
[string] $projArgs = "%mr.GitVersion.projArgs%",
[string] $updateAssemblyInfo = "%mr.GitVersion.updateAssemblyInfo%"
)

$ErrorActionPreference = "Stop"

function Join-ToWorkingDirectoryIfSpecified($path) {
$workingDir = "%teamcity.build.workingDir%"
if ($workingDir -match "teamcity.build.workingDir") {
return $path
}
if (Test-IsSpecified $path) {
return Join-Path $workingDir $path
}
return $path
}

function Test-IsSpecified ($value) {
if ($value -ne $null -and $value -ne "" -and -not ($value -match "mr.GitVersion.")) {
return $true
}
return $false
}

function Append-IfSpecified($appendTo, $command, $value) {
if (Test-IsSpecified $value) {
return "$appendTo /$command ""$value"""
}
return $appendTo
}

function Build-Arguments() {
$args = "";
if (Test-IsSpecified $workingDir) {
$args = """$workingDir"""
}
if (Test-IsSpecified $url) {
$args = Append-IfSpecified $args "url" $url
$args = Append-IfSpecified $args "b" $branch
$args = Append-IfSpecified $args "u" $username
$args = Append-IfSpecified $args "p" $password
}
$args = Append-IfSpecified $args "output" $output
$args = Append-IfSpecified $args "l" $logFile
if (Test-IsSpecified $exec) {
$args = Append-IfSpecified $args "exec" $exec
$args = Append-IfSpecified $args "execargs" $execargs
}
if (Test-IsSpecified $proj) {
$args = Append-IfSpecified $args "proj" $proj
$args = Append-IfSpecified $args "projargs" $projargs
}
if ($updateAssemblyInfo -eq "true") {
$args = "$args /UpdateAssemblyInfo"
}
if ($output -eq "json" -and (Test-IsSpecified $outputFile)) {
$args = "$args > ""$outputFile"""
}
return $args
}

try {

$chocolateyDir = $null
if ($env:ChocolateyInstall -ne $null) {
$chocolateyDir = $env:ChocolateyInstall
} elseif (Test-Path (Join-Path $env:SYSTEMDRIVE Chocolatey)) {
$chocolateyDir = Join-Path $env:SYSTEMDRIVE Chocolatey
} elseif (Test-Path (Join-Path ([Environment]::GetFolderPath("CommonApplicationData")) Chocolatey)) {
$chocolateyDir = Join-Path ([Environment]::GetFolderPath("CommonApplicationData")) Chocolatey
}

if ($chocolateyDir -eq $null) {
Write-Host "##teamcity[progressMessage 'Chocolatey not installed; installing Chocolatey']"
iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))
$chocolateyDir = Join-Path ([Environment]::GetFolderPath("CommonApplicationData")) Chocolatey
if (-not (Test-Path $chocolateyDir)) {
throw "Error installing Chocolatey"
}
} else {
Write-Host "Chocolatey already installed"
}

$chocolateyBinDir = Join-Path $chocolateyDir "bin"
$gitversion = Join-Path $chocolateyBinDir "gitversion.bat"
if (-not (Test-Path $gitversion)) {
$gitversion = Join-Path $chocolateyBinDir "gitversion.exe"
}
if (-not (Test-Path $gitversion)) {
Write-Host "##teamcity[progressMessage 'GitVersion not installed; installing GitVersion']"
$choco = Join-Path (Join-Path $chocolateyDir "chocolateyInstall") "chocolatey.cmd"
iex "$choco install gitversion"
if ($LASTEXITCODE -ne 0) {
throw "Error installing GitVersion"
}
} else {
Write-Host "GitVersion already installed"
}

$outputFile = Join-ToWorkingDirectoryIfSpecified $outputFile
$logFile = Join-ToWorkingDirectoryIfSpecified $logFile
$exec = Join-ToWorkingDirectoryIfSpecified $exec
$proj = Join-ToWorkingDirectoryIfSpecified $proj

$arguments = Build-Arguments
Write-Host "##teamcity[progressMessage 'Running: $gitversion $arguments']"
iex "$gitversion $arguments"
if ($LASTEXITCODE -ne 0) {
throw "Error running GitVersion"
}
}
catch {
Write-Host "##teamcity[buildStatus text='$_' status='FAILURE']"
Write-Host "##teamcity[message text='$_' status='ERROR']"
exit 1
}
]]></param>
</parameters>
</runner>
</build-runners>
<requirements />
</settings>
</meta-runner>
39 changes: 39 additions & 0 deletions gitversion/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
GitVersion meta-runner for TeamCity
===================================

This meta-runner allows you to get up and running with [GitVersion](https://github.com/Particular/GitVersion) inside of TeamCity without needing to install anything further on your server. It will automatically install GitVersion from Chocolatey after ensuring Chocolatey exists on that server (it installs Chocolatey for you if it's not already there).

GitVersion is the easy way to use semantic versioning (semver.org) with Git. GitVersion uses your git repository branching conventions to determine the current [Semantic Version](http://semver.org/) of your application. It supports [GitFlow](https://github.com/Particular/GitVersion/wiki/GitFlow) and the much simpler [GitHubFlow](https://github.com/Particular/GitVersion/wiki/GitHubFlow) and might work with others (let us know).

![GitVersion in TeamCity](https://github.com/Particular/GitVersion/raw/master/Icons/README.png)

See the [GitVersion repository](https://github.com/Particular/GitVersion) for more information.

GitVersion Runner
-----------------

![Runner configuration in TeamCity](documentation/assets/gitversion_runner.png)

The following options can be specified:
* Git Repository Directory: The directory containing .git relative to the working directory. Leave blank for the working directory itself.
* Update TeamCity build version: Update the TeamCity build number or output JSON?
* Json output file: Optional path to a file relative to the working directory to output the json into if you selected JSON above.
* Remote Git Repository: Optional URL to remote git repository if you have not already checked one out.
* Remote Git Branch: Remote branch to use.
* Remote Git Username: Remote git repo username (if private).
* Remote Git Password: Remote git repo password (if private).
* Log File: Optional path to a file relative to the working directory to log output messages to.
* Executable: Optional executable relative to the working directory to run using GitVersion - environment vars will be available to the process.
* Executable Arguments: If an Executable is specified then arguments to pass to the executable.
* MSBuild File: Optional MSBuild file relative to the working directory to run using GitVersion - environment vars will be available to the process.
* MSBuild Arguments: If an MSBuild file is specified then arguments to pass to MSBuild.
* Update AssemblyInfo Files: Update any AssemblyInfo files while running the Executable or MSBuild file?

For more information about these arguments please consult the [GitVersion Commandline Documentation](https://github.com/Particular/GitVersion/wiki/Command-Line-Tool).

Known Issues
------------

1. You can't include spaces in the `execArgs` or `projArgs`
2. Once this gets a gitversion installed on the server from Chocolatey it will never try and update it - It could include a call to cinst to update it if necessary every run, but that will add at least 1-2s (if not more) to every build run due to Chocolatey's slowness. That's why it checks the filesystem for chocolatey rather than invoking a Chocolatey command to see if it already exists.
3. While it will fail the build if there is a problem, it won't fail the step (the PowerShell script always returns a 0 exit code unfortunately) so any steps after it that are marked as "Run if all previous steps successful" rather than "Run if build successful" will still run
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions gitversion/test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
json.txt
log.txt
129 changes: 129 additions & 0 deletions gitversion/test/GitVersion.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
[CmdletBinding()]
Param (
[string] $workingDir = (Join-Path "%teamcity.build.workingDir%" "%mr.GitVersion.gitCheckoutDir%"),
[string] $output = "%mr.GitVersion.output%",
[string] $outputFile = "%mr.GitVersion.outputFile%",
[string] $url = "%mr.GitVersion.url%",
[string] $branch = "%mr.GitVersion.branch%",
[string] $username = "%mr.GitVersion.username%",
[string] $password = "%mr.GitVersion.password%",
[string] $logFile = "%mr.GitVersion.logFile%",
[string] $exec = "%mr.GitVersion.exec%",
[string] $execArgs = "%mr.GitVersion.execArgs%",
[string] $proj = "%mr.GitVersion.proj%",
[string] $projArgs = "%mr.GitVersion.projArgs%",
[string] $updateAssemblyInfo = "%mr.GitVersion.updateAssemblyInfo%"
)

$ErrorActionPreference = "Stop"

function Join-ToWorkingDirectoryIfSpecified($path) {
$workingDir = "%teamcity.build.workingDir%"
if ($workingDir -match "teamcity.build.workingDir") {
return $path
}
if (Test-IsSpecified $path) {
return Join-Path $workingDir $path
}
return $path
}

function Test-IsSpecified ($value) {
if ($value -ne $null -and $value -ne "" -and -not ($value -match "mr.GitVersion.")) {
return $true
}
return $false
}

function Append-IfSpecified($appendTo, $command, $value) {
if (Test-IsSpecified $value) {
return "$appendTo /$command ""$value"""
}
return $appendTo
}

function Build-Arguments() {
$args = "";
if (Test-IsSpecified $workingDir) {
$args = """$workingDir"""
}
if (Test-IsSpecified $url) {
$args = Append-IfSpecified $args "url" $url
$args = Append-IfSpecified $args "b" $branch
$args = Append-IfSpecified $args "u" $username
$args = Append-IfSpecified $args "p" $password
}
$args = Append-IfSpecified $args "output" $output
$args = Append-IfSpecified $args "l" $logFile
if (Test-IsSpecified $exec) {
$args = Append-IfSpecified $args "exec" $exec
$args = Append-IfSpecified $args "execargs" $execargs
}
if (Test-IsSpecified $proj) {
$args = Append-IfSpecified $args "proj" $proj
$args = Append-IfSpecified $args "projargs" $projargs
}
if ($updateAssemblyInfo -eq "true") {
$args = "$args /UpdateAssemblyInfo"
}
if ($output -eq "json" -and (Test-IsSpecified $outputFile)) {
$args = "$args > ""$outputFile"""
}
return $args
}

try {

$chocolateyDir = $null
if ($env:ChocolateyInstall -ne $null) {
$chocolateyDir = $env:ChocolateyInstall
} elseif (Test-Path (Join-Path $env:SYSTEMDRIVE Chocolatey)) {
$chocolateyDir = Join-Path $env:SYSTEMDRIVE Chocolatey
} elseif (Test-Path (Join-Path ([Environment]::GetFolderPath("CommonApplicationData")) Chocolatey)) {
$chocolateyDir = Join-Path ([Environment]::GetFolderPath("CommonApplicationData")) Chocolatey
}

if ($chocolateyDir -eq $null) {
Write-Host "##teamcity[progressMessage 'Chocolatey not installed; installing Chocolatey']"
iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))
$chocolateyDir = Join-Path ([Environment]::GetFolderPath("CommonApplicationData")) Chocolatey
if (-not (Test-Path $chocolateyDir)) {
throw "Error installing Chocolatey"
}
} else {
Write-Host "Chocolatey already installed"
}

$chocolateyBinDir = Join-Path $chocolateyDir "bin"
$gitversion = Join-Path $chocolateyBinDir "gitversion.bat"
if (-not (Test-Path $gitversion)) {
$gitversion = Join-Path $chocolateyBinDir "gitversion.exe"
}
if (-not (Test-Path $gitversion)) {
Write-Host "##teamcity[progressMessage 'GitVersion not installed; installing GitVersion']"
$choco = Join-Path (Join-Path $chocolateyDir "chocolateyInstall") "chocolatey.cmd"
iex "$choco install gitversion"
if ($LASTEXITCODE -ne 0) {
throw "Error installing GitVersion"
}
} else {
Write-Host "GitVersion already installed"
}

$outputFile = Join-ToWorkingDirectoryIfSpecified $outputFile
$logFile = Join-ToWorkingDirectoryIfSpecified $logFile
$exec = Join-ToWorkingDirectoryIfSpecified $exec
$proj = Join-ToWorkingDirectoryIfSpecified $proj

$arguments = Build-Arguments
Write-Host "##teamcity[progressMessage 'Running: $gitversion $arguments']"
iex "$gitversion $arguments"
if ($LASTEXITCODE -ne 0) {
throw "Error running GitVersion"
}
}
catch {
Write-Host "##teamcity[buildStatus text='$_' status='FAILURE']"
Write-Host "##teamcity[message text='$_' status='ERROR']"
exit 1
}
3 changes: 3 additions & 0 deletions gitversion/test/executable_example.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@echo OFF
echo Example executable running with following arguments passed in:
echo %*
6 changes: 6 additions & 0 deletions gitversion/test/msbuild_example.proj
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Rebuild">
<Message Text="Running example MSBuild file with: Configuration=$(Configuration) Platform=$(Platform)"></Message>
</Target>
</Project>
4 changes: 4 additions & 0 deletions gitversion/test/test.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
$scriptpath = Split-Path $MyInvocation.MyCommand.Path
.\GitVersion.ps1 -workingDir "$scriptpath\..\" -output json -logFile "$scriptpath\log.txt" -outputFile "$scriptpath\json.txt"
.\GitVersion.ps1 -workingDir "$scriptpath\..\" -output buildserver -proj "$scriptpath\msbuild_example.proj" -projArgs "/t:Rebuild /p:Configuration=Release /p:Platform=AnyCPU"
.\GitVersion.ps1 -workingDir "$scriptpath\..\" -output buildserver -exec "$scriptpath\executable_example.bat" -execArgs "arg1 arg2"