Last active
November 18, 2016 22:56
-
-
Save DamianReeves/16f4690b594850520dd605a28a051aa3 to your computer and use it in GitHub Desktop.
PS YAML 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
#Requires -Version 4.0 | |
$ErrorActionPreference = 'Stop' | |
# Ignoring progress stream is vital to keep the performance | |
# of Invoke-WebRequest decent in Teamcity | |
$ProgressPreference = 'SilentlyContinue' | |
function global:RestoreBuildLevelPackages { | |
# Download paket.exe. | |
# Use --prefer-nuget to get it from nuget.org first as it is quicker (compressed .nupkg) | |
$paketVersion = "" # Set this to the value of a specific version of paket.exe to download if need be. | |
& "$PSScriptRoot\..\.paket\paket.bootstrapper.exe" $paketVersion --prefer-nuget | |
Push-Location $PsScriptRoot -verbose | |
try { | |
& "..\.paket\paket.exe" install | |
if($LASTEXITCODE -ne 0) { | |
throw "paket install exited with code $LASTEXITCODE" | |
} | |
} finally { | |
Pop-Location | |
} | |
} | |
<# | |
.SYNOPSIS | |
Build <amazing-product>. | |
.DESCRIPTION | |
This is really a wrapper around build.ps1 (build.ps1 is our actual build script. E.g.(the script that tells you how to build this crazy thing) | |
2 main steps: | |
1 - Restore nuget packages that are needed to get our build engine/tools. | |
2 - Execute the build. (Invoke-Build build.ps1) | |
In theory, Teamcity will also use this build command. Probably like this: 'build -Task Build' | |
.EXAMPLE | |
build -Task Compile, UnitTests | |
Run the build script and only execute the 'Compile' and 'UnitTests' tasks. | |
.EXAMPLE | |
build | |
The simplest example! Just execute the build with default values for the -Task parameter. | |
#> | |
function global:Build { | |
[CmdletBinding()] | |
param( | |
# The Tasks to execute. '.' means the default task as defined in build.ps1 | |
[string[]] $Task = @('.'), | |
# The Configuration to build. Either Release or Debug | |
[ValidateSet('Release', 'Debug')] | |
[string] $Configuration = 'Release', | |
# The name of the branch we are building (Set by Teamcity). | |
# Will be set by Teamcity. Defaults to 'dev' for local developer builds. | |
[string] $BranchName = 'dev', | |
# Indicates whether or not BranchName represents the default branch for the source control system currently in use. | |
# Will be set by Teamcity. Defaults to $false for local developer builds. | |
[bool] $IsDefaultBranch = $false, | |
# (Optional) URL to the nuget feed to publish nuget packages to. | |
# Will be set by Teamcity. | |
[string] $NugetFeedUrl, | |
# (Optional) Api Key to the nuget feed to be able to publish nuget packages. | |
# Will be set by Teamcity. | |
[string] $NugetFeedApiKey, | |
# (Optional) Signing service url used to sign dll/exe. | |
[string] $SigningServiceUrl | |
) | |
RestoreBuildLevelPackages | |
Push-Location $PsScriptRoot -verbose | |
try | |
{ | |
# Import the Mohawk.Build module. | |
Import-Module '.\packages\Mohawk.Build\tools\Mohawk.Build.psm1' -Force -DisableNameChecking | |
# If building installers you need the Mohawk.Build.Installers module too | |
#Import-Module ".\packages\Mohawk.Build.Installer\tools\Mohawk.Build.Installer.psm1" -Force -DisableNameChecking | |
# Call the actual build script | |
& '.\packages\Invoke-Build\tools\Invoke-Build.ps1' ` | |
-File .\build.ps1 ` | |
-Task $Task ` | |
-BranchName $BranchName ` | |
-IsDefaultBranch $IsDefaultBranch ` | |
-NugetFeedUrl $NugetFeedUrl ` | |
-NugetFeedApiKey $NugetFeedApiKey ` | |
-SigningServiceUrl $SigningServiceUrl ` | |
} | |
finally | |
{ | |
Pop-Location | |
} | |
} | |
<# | |
.SYNOPSIS | |
Build <amazing-product>. | |
.DESCRIPTION | |
This is really a wrapper around build.ps1 (build.ps1 is our actual build script. E.g.(the script that tells you how to build this crazy thing) | |
2 main steps: | |
1 - Restore nuget packages that are needed to get our build engine/tools. | |
2 - Execute the build. (Invoke-Build build.ps1) | |
In theory, Teamcity will also use this build command. Probably like this: 'build -Task Build' | |
.EXAMPLE | |
build -Task Compile, UnitTests | |
Run the build script and only execute the 'Compile' and 'UnitTests' tasks. | |
.EXAMPLE | |
dotnetbuild | |
The simplest example! Just execute the dotnetbuild with default values for the -Task parameter. | |
#> | |
function global:DotNetBuild { | |
[CmdletBinding()] | |
param( | |
# The Tasks to execute. '.' means the default task as defined in build.ps1 | |
[string[]] $Task = @('.'), | |
# The Configuration to build. Either Release or Debug | |
[ValidateSet('Release', 'Debug')] | |
[string] $Configuration = 'Release', | |
# The name of the branch we are building (Set by Teamcity). | |
# Will be set by Teamcity. Defaults to 'dev' for local developer builds. | |
[string] $BranchName = "", | |
# Indicates whether or not BranchName represents the default branch for the source control system currently in use. | |
# Will be set by Teamcity. Defaults to $false for local developer builds. | |
[bool] $IsDefaultBranch = $false, | |
# (Optional) URL to the nuget feed to publish nuget packages to. | |
# Will be set by Teamcity. | |
[string] $NugetFeedUrl, | |
# (Optional) Api Key to the nuget feed to be able to publish nuget packages. | |
# Will be set by Teamcity. | |
[string] $NugetFeedApiKey, | |
# (Optional) Signing service url used to sign dll/exe. | |
[string] $SigningServiceUrl | |
) | |
RestoreBuildLevelPackages | |
Push-Location $PsScriptRoot -verbose | |
try | |
{ | |
# Import the Mohawk.Build module. | |
Import-Module '.\packages\Mohawk.Build\tools\Mohawk.Build.psm1' -Force -DisableNameChecking | |
# If building installers you need the Mohawk.Build.Installers module too | |
#Import-Module ".\packages\Mohawk.Build.Installer\tools\Mohawk.Build.Installer.psm1" -Force -DisableNameChecking | |
# Call the actual build script | |
& '.\packages\Invoke-Build\tools\Invoke-Build.ps1' ` | |
-File .\dotnetbuild.ps1 ` | |
-Task $Task ` | |
-BranchName $BranchName ` | |
-IsDefaultBranch $IsDefaultBranch ` | |
-NugetFeedUrl $NugetFeedUrl ` | |
-NugetFeedApiKey $NugetFeedApiKey ` | |
-SigningServiceUrl $SigningServiceUrl ` | |
} | |
finally | |
{ | |
Pop-Location | |
} | |
} | |
$repoName = ([System.IO.DirectoryInfo](Resolve-Path(Join-Path $PSScriptRoot "..")).Path).Name | |
Write-Host "This is the $repoName repo. And here are the available commands:" -Fore Magenta | |
Write-Host "`t dotnetbuild" -Fore Green | |
Write-Host "`t build" -Fore Green | |
Write-Host "`t installer" -Fore Green | |
Write-Host "For more info, use help <command-name>" -Fore Magenta |
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
assemblyVersion: 0.1.1.0 | |
semanticVersion: "0.1.1-preview.1+15" | |
packageVersion: 0.1.1-preview0001 | |
testProjectRegex: "[Tt]ests?$" | |
branch: | |
nugetPublishFeeds: ["http://myfeed/ci/feed"] | |
develop: | |
nugetPublishFeeds: ["http://myfeed/dev/feed/", "http://myfeed/ci/feed"] | |
master: | |
nugetPublishFeeds: ["http://myfeed/dev/feed/", "http://myfeed/ci/feed", "http://myfeed/live/feed"] | |
projects: | |
- Project: | |
Name: Mohawk.Core | |
PackageVersion: 0.1.1-rc0001 | |
- Project: | |
Name: Mohawk.Service | |
IsService: true | |
- Project: | |
Name: Mohawk.Tool | |
IsTool: true | |
- Project: | |
Name: Mohawk.Core.Tests | |
TestSuites: ["xUnit", "NUnit", "MSTest"] | |
DisablePackaging: true | |
- Project: | |
Name: Mohawk.Common.Tests | |
TestSuites: ["xUnit"] | |
DisablePackaging: true | |
IsTestProject: true |
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
[CmdletBinding()] | |
param( | |
[string] $Configuration = 'Release', | |
[string] $BranchName, | |
[bool] $IsDefaultBranch = $false, | |
[string] $NugetFeedUrl, | |
[string] $NugetFeedApiKey, | |
[string] $SigningServiceUrl | |
) | |
$RootDir = "$PsScriptRoot\.." | Resolve-Path | |
$OutputDir = "$RootDir\.output\$Configuration" | |
$LogsDir = "$OutputDir\logs" | |
$NugetPackageOutputDir = "$OutputDir\nugetpackages" | |
$TestResultsOutputDir = "$OutputDir\testResults" | |
$BuildStateOutputDir = "$OutputDir\buildState" # A directory used for dynamic build configuration | |
$SourceProjects = ls (Join-Path $RootDir '.\src\**\project.json') -Recurse | |
$TestProjects = ls (Join-Path $RootDir '.\test\**\project.json') -Recurse | |
$AllProjects = ls (Join-Path $RootDir '.\**\project.json') -Recurse | |
# We probably don't want to publish every single nuget package ever built to our external feed. | |
# Let's only publish packages built from the default branch (master) by default. | |
# packages built from non master branches would still be available using the built-in Teamcity feed at | |
# http://<teamcity-server>/guestAuth/app/nuget/v1/FeedService.svc/ | |
# or http://<teamcity-server>/httpAuth/app/nuget/v1/FeedService.svc/ | |
$PublishNugetPackages = $env:TEAMCITY_VERSION -and $IsDefaultBranch | |
$NugetExe = "$PSScriptRoot\packages\Nuget.CommandLine\tools\Nuget.exe" | Resolve-Path | |
# Installer building routines are stored in a separate file | |
# . $PSScriptRoot\installer.tasks.ps1 | |
task CleanOutputs { | |
Remove-Item $OutputDir -Recurse -Force -ErrorAction SilentlyContinue | Out-Null | |
#Remove-Item $LogsDir -Recurse -Force | Out-Null | |
#Remove-Item $NugetPackageOutputDir -Recurse -Force | Out-Null | |
} | |
task CreateFolders { | |
New-Item $OutputDir -ItemType Directory -Force | Out-Null | |
New-Item $LogsDir -ItemType Directory -Force | Out-Null | |
New-Item $NugetPackageOutputDir -ItemType Directory -Force | Out-Null | |
New-Item $TestResultsOutputDir -ItemType Directory -Force | Out-Null | |
New-Item $BuildStateOutputDir -ItemType Directory -Force | Out-Null | |
} | |
# Synopsis: Retrieve three part version information and release notes from $RootDir\RELEASENOTES.md | |
# $script:Version = Major.Minor.Build.$VersionSuffix (for installer.tasks) | |
# $script:AssemblyVersion = $script:Version | |
# $script:AssemblyFileVersion = $script:Version | |
# $script:ReleaseNotes = read from RELEASENOTES.md | |
function GenerateVersionInformationFromReleaseNotesMd([int] $VersionSuffix) { | |
$ReleaseNotesPath = "$RootDir\RELEASENOTES.md" | Resolve-Path | |
$Notes = Read-ReleaseNotes -ReleaseNotesPath $ReleaseNotesPath -ThreePartVersion | |
$script:Version = [System.Version] "$($Notes.Version).$VersionSuffix" | |
$script:ReleaseNotes = [string] $Notes.Content | |
# Establish assembly version number | |
$script:AssemblyVersion = $script:Version | |
$script:AssemblyFileVersion = $script:Version | |
#TeamCity-PublishArtifact "$ReleaseNotesPath" | |
$false | |
} | |
# Synopsis: Retrieve two part semantic version information and release notes from $RootDir\RELEASENOTES.md | |
# $script:Version = Major.Minor.$VersionSuffix | |
# $script:AssemblyVersion = Major.0.0.0 | |
# $script:AssemblyFileVersion = Major.Minor.$VersionSuffix.0 | |
# $script:ReleaseNotes = read from RELEASENOTES.md | |
function GenerateSemVerInformationFromReleaseNotesMd([int] $VersionSuffix) { | |
$ReleaseNotesPath = "$RootDir\RELEASENOTES.md" | Resolve-Path | |
$Notes = Read-ReleaseNotes -ReleaseNotesPath $ReleaseNotesPath | |
$script:Version = [System.Version] "$($Notes.Version).$VersionSuffix" | |
$script:ReleaseNotes = [string] $Notes.Content | |
# Establish assembly version number | |
$script:AssemblyVersion = [version] "$($script:Version.Major).0.0.0" | |
$script:AssemblyFileVersion = [version] "$script:Version.0" | |
#TeamCity-PublishArtifact "$ReleaseNotesPath" | |
$false | |
} | |
# Synopsis: Retrieve three part version information from .build\version.txt | |
# $script:Version = Major.Minor.Build.$VersionSuffix | |
# $script:AssemblyVersion = Major.Minor.Build.$VersionSuffix | |
# $script:AssemblyFileVersion = Major.Minor.Build.$VersionSuffix | |
# $script:ReleaseNotes = '' | |
function GetVersionInformationFromVersionTxt([int] $VersionSuffix) { | |
$script:Version = [System.Version] "$(Get-Content version.txt).$VersionSuffix" | |
$script:AssemblyVersion = $script:Version | |
$script:AssemblyFileVersion = $script:Version | |
$script:ReleaseNotes = '' | |
$false | |
} | |
# Synopsis: Retrieve three part version information using GitVersion | |
# $script:Version = NuGetVersion2 | |
# $script:AssemblyVersion = AssemblySemVer | |
# $script:AssemblyFileVersion = AssemblySemVer | |
# $script:ReleaseNotes = '' | |
function GetVersionInformationFromGitVersion([int] $VersionSuffix) { | |
$GitVersionDir = Join-Path $RootDir ".build\packages\GitVersion.CommandLine\tools\GitVersion.exe" | |
$Versions = (& $GitVersionDir) | ConvertFrom-Json | |
$script:Version = ($Versions).NuGetVersionV2 | |
$script:AssemblyVersion = $Versions.AssemblySemVer | |
$script:AssemblyFileVersion = $Versions.AssemblySemVer | |
$script:ReleaseNotes = '' | |
if([System.String]::IsNullOrWhiteSpace($BranchName)) { | |
$script:BranchName = $Versions.BranchName | |
} | |
$true | |
} | |
<# | |
.SYNOPSIS | |
You can add this to you build script to ensure that psbuild is available before calling | |
Invoke-MSBuild. If psbuild is not available locally it will be downloaded automatically. | |
#> | |
function EnsurePsbuildInstalled{ | |
[cmdletbinding()] | |
param( | |
[string]$psbuildInstallUri = 'https://raw.githubusercontent.com/ligershark/psbuild/master/src/GetPSBuild.ps1' | |
) | |
process{ | |
if(-not (Get-Command "Invoke-MsBuild" -errorAction SilentlyContinue)){ | |
'Installing psbuild from [{0}]' -f $psbuildInstallUri | Write-Verbose | |
(new-object Net.WebClient).DownloadString($psbuildInstallUri) | iex | |
} | |
else{ | |
'psbuild already loaded, skipping download' | Write-Verbose | |
} | |
# make sure it's loaded and throw if not | |
if(-not (Get-Command "Invoke-MsBuild" -errorAction SilentlyContinue)){ | |
throw ('Unable to install/load psbuild from [{0}]' -f $psbuildInstallUri) | |
} | |
} | |
} | |
# Ensures the following are set | |
# $script:Version | |
# $script:AssemblyVersion | |
# $script:AssemblyFileVersion | |
# $script:ReleaseNotes | |
# $script:NugetPackageVersion = $script:Version or $script:Version-branch | |
task GenerateVersionInformation { | |
"Retrieving version information" | |
# For dev builds, version suffix is always 0 | |
$versionSuffix = 0 | |
if($env:BUILD_NUMBER) { | |
$versionSuffix = $env:BUILD_NUMBER | |
} | |
$versionIsFinal = GetVersionInformationFromGitVersion($versionSuffix) | |
# GetVersionInformationFromVersionTxt($versionSuffix) | |
# GenerateVersionInformationFromReleaseNotesMd($versionSuffix) | |
# GenerateSemVerInformationFromReleaseNotesMd($versionSuffix) | |
#TeamCity-SetBuildNumber $script:Version | |
if($versionIsFinal) { | |
$script:NugetPackageVersion = $script:Version | |
} else { | |
$script:NugetPackageVersion = New-NugetPackageVersion -Version $script:Version -BranchName $BranchName -IsDefaultBranch $IsDefaultBranch | |
} | |
"Version = $script:Version" | |
"AssemblyVersion = $script:AssemblyVersion" | |
"AssemblyFileVersion = $script:AssemblyFileVersion" | |
"NugetPackageVersion = $script:NugetPackageVersion" | |
"ReleaseNotes = $script:ReleaseNotes" | |
} | |
task GatherBuildConfigurationInfo GenerateVersionInformation, { | |
if([System.String]::IsNullOrWhiteSpace($NugetFeedUrl)) { | |
switch -Wildcard ($BranchName) { | |
"rc" { | |
$Script:NugetFeedUrl = "https://mohawkgp.pkgs.visualstudio.com/_packaging/rc/nuget/v3/index.json" | |
} | |
"rc-*" { | |
$Script:NugetFeedUrl = "https://mohawkgp.pkgs.visualstudio.com/_packaging/rc/nuget/v3/index.json" | |
} | |
"rc/*" { | |
$Script:NugetFeedUrl = "https://mohawkgp.pkgs.visualstudio.com/_packaging/rc/nuget/v3/index.json" | |
} | |
"develop" { | |
$Script:NugetFeedUrl = "https://mohawkgp.pkgs.visualstudio.com/_packaging/develop/nuget/v3/index.json" | |
} | |
"master" { | |
$Script:NugetFeedUrl = "https://mohawkgp.pkgs.visualstudio.com/_packaging/live/nuget/v3/index.json" | |
} | |
default { | |
$Script:NugetFeedUrl = "https://mohawkgp.pkgs.visualstudio.com/_packaging/CI/nuget/v3/index.json" | |
} | |
} | |
} | |
} | |
task WriteBuildConfiguration GatherBuildConfigurationInfo, { | |
$buildState = @{ | |
"BranchName" = $script:BranchName; | |
"Version" = $script:Version; | |
"AssemblyVersion" = $script:AssemblyVersion; | |
"AssemblyFileVersion" = $script:AssemblyFileVersion; | |
"NugetPackageVersion" = $script:NugetPackageVersion; | |
"NugetFeedUrl" = $script:NugetFeedUrl; | |
"ReleaseNotes" = $script:ReleaseNotes; | |
} | |
foreach ($key in $buildState.Keys) { | |
$variableName = "BuildState_$key" | |
$theValue = $buildState[$key] | |
Write-Host "##vso[task.setvariable variable=$variableName;]$theValue" | |
} | |
ConvertTo-Json $buildState | Out-File (Join-Path $BuildStateOutputDir "buildState.json") | |
} | |
# Synopsis: Update the project.json versions | |
task UpdateProjectDotJsonVersionInfo { | |
foreach ($Project in $SourceProjects) { | |
Set-PackageVersion -path $Project -Version $script:NugetPackageVersion | |
} | |
} | |
# Synopsis: Restore the nuget packages of the Visual Studio solution | |
task RestorePackages { | |
exec {& dotnet restore $RootDir } | |
<# | |
"Restoring using global.json:" | |
$globalJsonPath = Join-Path "$RootDir" "global.json" | Resolve-Path -ErrorAction SilentlyContinue | |
if(Test-Path $globalJsonPath) { | |
"Restoring packages using global.json:" | |
exec {& dotnet restore "$RootDir" } | |
} | |
#> | |
<# | |
"Restoring individual packages for good measure:" | |
foreach ($Project in $AllProjects) { | |
"Restoring $Project" | |
exec { | |
& dotnet restore $Project | |
} | |
} | |
#> | |
} | |
# Synopsis: Update the nuget packages of the Visual Studio solution | |
task UpdateNugetPackages RestorePackages, { | |
exec { | |
& $NugetExe update "$Solution" -Verbosity detailed | |
} | |
} | |
# Synopsis: Update the version info in all AssemblyInfo.cs | |
task UpdateVersionInfo GenerateVersionInformation, { | |
"Updating assembly information" | |
# Ignore anything under the Testing/ folder | |
@(Get-ChildItem "$RootDir" AssemblyInfo.cs -Recurse) | where { $_.FullName -notlike "$RootDir\Testing\*" } | ForEach { | |
Update-AssemblyVersion $_.FullName ` | |
-Version $script:AssemblyVersion ` | |
-FileVersion $script:AssemblyFileVersion ` | |
-InformationalVersion $script:NuGetPackageVersion | |
} | |
} | |
# Synopsis: A task that makes sure our initialization tasks have been run before we can do anything useful | |
task Init CleanOutputs, CreateFolders, RestorePackages, GenerateVersionInformation, WriteBuildConfiguration | |
# Synopsis: Compile the Visual Studio solution | |
task Compile Init, UpdateVersionInfo, { | |
try { | |
foreach ($Project in $AllProjects) { | |
exec { | |
& dotnet build $Project --configuration "$Configuration" | |
} | |
} | |
} finally { | |
#TeamCity-PublishArtifact "$LogsDir\_msbuild.log.* => logs/msbuild.$Configuration.logs.zip" | |
} | |
} | |
# Synopsis: Execute our unit tests | |
task UnitTests { | |
foreach ($Project in $TestProjects) { | |
$ProjectName = $Project.Directory.Name | |
$OutputFilename = Join-Path $TestResultsOutputDir "$ProjectName.testResults.xml" | |
exec {& dotnet test "$Project" -c "$Configuration" -xml $OutputFilename } | |
} | |
} | |
# Synopsis: Build the nuget packages. | |
task BuildNugetPackages Init, UpdateProjectDotJsonVersionInfo, { | |
New-Item $NugetPackageOutputDir -ItemType Directory -Force | Out-Null | |
#$escaped=$ReleaseNotes.Replace('"','\"') | |
#$properties = "releaseNotes=$escaped" | |
foreach ($Project in $SourceProjects) { | |
"Packing $project..." | |
exec { | |
& dotnet pack $Project --no-build --output "$NugetPackageOutputDir" --configuration "$Configuration" | |
} | |
"Packing for $project completed!" | |
} | |
} | |
# Synopsis: Publish the nuget packages (Teamcity only) | |
task PublishNugetPackages -If($PublishNugetPackages) { | |
assert ($NugetFeedUrl) '$NugetFeedUrl is missing. Cannot publish nuget packages' | |
assert ($NugetFeedApiKey) '$NugetFeedApiKey is missing. Cannot publish nuget packages' | |
Get-ChildItem $NugetPackageOutputDir -Filter "*.nupkg" | ForEach { | |
& $NugetExe push $_.FullName -Source $NugetFeedUrl -ApiKey $NugetFeedApiKey | |
} | |
} | |
# Synopsis: Build the project. | |
task Build Init, Compile, UnitTests, BuildNugetPackages, PublishNugetPackages | |
# Synopsis: Build the project. | |
task BuildNoTests Init, Compile, BuildNugetPackages, PublishNugetPackages | |
# Synopsis: By default, Call the 'Build' task | |
task . Build |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Added
: