Skip to content

Instantly share code, notes, and snippets.

@noelbundick
Created April 24, 2015 20:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save noelbundick/be42384874ab9a0068e3 to your computer and use it in GitHub Desktop.
Save noelbundick/be42384874ab9a0068e3 to your computer and use it in GitHub Desktop.
Sample build
properties {
$config = if ($config) { $config } else { "Debug" }
$base_dir = Resolve-Path .
$sln_file = "$base_dir\ProjectName.sln"
$artifacts_dir = "$base_dir\build"
$package_dir = "$base_dir\packages"
$ef_migrate_output = "$artifacts_dir\Tools\EF\"
$msbuild = "msbuild"
$msdeploy = GetMSWebDeployInstallPath
}
#Build & run tests by default
task default -depends Build, RunTests
#Creates a blank folder where build artifacts will be placed
task Clean {
Write-Output "Cleaning build artifacts directory - $artifacts_dir"
if (Test-Path $artifacts_dir)
{
rd $artifacts_dir -rec -force | out-null
}
mkdir $artifacts_dir | out-null
}
#Build the solution using .Net 4.5
task Build -depends Clean {
Framework '4.5.1'
Write-Output "Building Solution"
#Build msbuild command for solution
$params = @()
$params += $sln_file
$params += "/t:Clean"
$params += "/t:Build"
$params += "/m"
$params += "/v:m"
$params += "/p:Configuration=$config"
$params += "/p:OutDir=""$artifacts_dir"""
$params += "/p:GenerateProjectSpecificOutputFolder=true"
$params += "/p:DeployOnBuild=True"
$params += "/p:PublishProfile=Package-$config"
$params += "/p:DocumentationFile=""bin\XmlComments.xml"""
Write-Output $msbuild $params
Exec { & $msbuild $params }
BuildAngularApp
}
#Run xUnit tests for all projects named *Tests
task RunTests -depends Build {
Write-Output "Running tests"
$runner = "$package_dir\xunit.runners.1.9.2\tools\xunit.console.clr4.exe"
Get-ChildItem -Recurse -ErrorAction SilentlyContinue -Include *Tests.csproj | % {
$project = $_.BaseName
& $runner "$artifacts_dir\$project\$project.dll"
}
}
#Copy files needed to run Entity Framework code-first migrations
Task PrepareEntityFrameworkMigrate {
Write-Output "Copying migrate.exe and supporting files for EF migrations"
#TODO: Get these versions from packages.config instead of hard coding them here
$ef_package_dir = "$package_dir\EntityFramework.6.1.3"
if (Test-Path $ef_migrate_output) {
rd $ef_migrate_output -rec -force | out-null
}
mkdir $ef_migrate_output | out-null
Copy-Item "$ef_package_dir\lib\net45\*" $ef_migrate_output -Recurse -Force
Copy-Item "$ef_package_dir\tools\*" $ef_migrate_output -Recurse
if ($config -eq "Debug") {
$seed_scripts_dir = "$artifacts_dir\Data\SeedScripts"
if (Test-Path $seed_scripts_dir) {
rd $seed_scripts_dir -rec -force | out-null
}
mkdir $seed_scripts_dir | out-null
Copy-Item "$base_dir\ProjectName.Api\data\SeedScripts\*" $seed_scripts_dir -Recurse
}
}
#Run database migrations
Task MigrateDatabase -depends PrepareEntityFrameworkMigrate {
$api = "ProjectName.Api"
if (!(Test-Path "$artifacts_dir\$api\$api.dll")) {
throw "ERROR: $api.dll is not present in $artifacts_dir. Please make sure you have run Build"
}
$migrate = "$ef_migrate_output\migrate.exe"
if (!(Test-Path $migrate)) {
throw "ERROR: $migrate is not present in $ef_migrate_output. Please make sure you have run PrepareEntityFrameworkMigrate"
}
[xml]$packageParameters = Get-Content "$artifacts_dir\$api\_PublishedWebsites\$($api)_Package\$($api).SetParameters.xml"
$connectionString = ($packageParameters.parameters.setParameter | ? {$_.name -match 'ProjectName-Web.config Connection String'}).value
$connectionProviderName = "System.Data.SqlClient"
Write-Output "Running database migrations for $api"
Exec { & $migrate "$api.dll" /connectionString="$connectionString" /connectionProviderName="$connectionProviderName" /StartUpDirectory:"$artifacts_dir\$api" /startupConfigurationFile="$artifacts_dir\$api\$api.dll.config" }
}
#Deploy using WebDeploy
Task DeployAPI {
DeploySite "ProjectName.Api" $web_deploy_endpoint
}
Task DeployAngular {
DeploySite "ProjectName.Angular" $web_deploy_endpoint
}
function BuildAngularApp() {
$msbuildParams = @()
$msbuildParams += "$base_dir\ProjectName.Angular\ProjectName.Angular.csproj"
$msbuildParams += "/t:Clean"
$msbuildParams += "/t:Build"
$msbuildParams += "/p:Configuration=$config"
Write-Output $msbuild $msbuildParams
Exec { & $msbuild $msbuildParams }
$buildDirectory = "$base_dir\ProjectName.Angular\build"
$targetDirectory = "$artifacts_dir\ProjectName.Angular\_PublishedWebsites\ProjectName.Angular_Package"
New-Item $targetDirectory -Type Directory
$msdeployParams = @()
$msdeployParams += "-source:manifest=`"$buildDirectory\sourcemanifest.xml`""
$msdeployParams += "-dest:package=$targetDirectory\ProjectName.Angular.zip"
$msdeployParams += "-disableLink:AppPoolExtension"
$msdeployParams += "-disableLink:ContentExtension"
$msdeployParams += "-disableLink:CertificateExtension"
$msdeployParams += "-declareParam:name=IISWebApplicationName,kind=ProviderPath,scope=IisApp,defaultValue=ProjectName-online-services"
$msdeployParams += "-declareParam:name=IISWebApplicationName,kind=ProviderPath,scope=setAcl"
$msdeployParams += "-verb:sync"
Write-Output $msdeploy $msdeployParams
& $msdeploy $msdeployParams 2>&1
Copy-Item "$buildDirectory\ProjectName.Angular.SetParameters.xml" $targetDirectory
}
function DeploySite($project, $deploy_to) {
Assert ($project -ne $null) '$project should not be null'
Assert ($deploy_to -ne $null) '$deploy_to should not be null'
Write-Output "Deploying $project to: $deploy_to"
$webdeploy_artifacts_dir = "$artifacts_dir\$project\_PublishedWebsites\$($project)_Package"
#Building msdeploy parameters as an array because PowerShell sucks at passing arguments that contain quotes/spaces/etc
$params = @()
$params += "-source:package='$webdeploy_artifacts_dir\$project.zip'"
$params += "-dest:auto,wmsvc=""$deploy_to"",authtype=""NTLM"",includeAcls=""False"",username="
$params += "-verb:sync"
$params += "-disableLink:AppPoolExtension"
$params += "-disableLink:ContentExtension"
$params += "-disableLink:CertificateExtension"
#Add setParamFile only if the file is present
if (Test-Path "$webdeploy_artifacts_dir\$project.SetParameters.xml") {
$params += "-setParamFile:""$webdeploy_artifacts_dir\$project.SetParameters.xml"""
}
#$params += "-whatif" #Uncomment for testing msdeploy
$params += "-allowUntrusted"
write-Output $msdeploy $params
& $msdeploy $params 2>&1
}
function GetMSWebDeployInstallPath() {
$path = (get-childitem "HKLM:\SOFTWARE\Microsoft\IIS Extensions\MSDeploy" | Select -last 1).GetValue("InstallPath")
$path = "${path}msdeploy.exe"
if (!(Test-Path $path)) {
throw "MSDEPLOY.EXE is not installed. See <a href=""http://go.microsoft.com/?linkid=9278654"" target=""_blank"">http://go.microsoft.com/?linkid=9278654</a>"
}
return $path
}
Note: You will need to restore NuGet packages before invoking psake. Quick fix is to store psake in the repo & use default.ps1 to restore packages
psake
psake -parameters "@{'config'='Release'}"
psake MigrateDatabase -parameters "@{'config'='Testing'}"
psake DeployAPI -parameters "@{'web_deploy_endpoint'='https://server.example.com:8172/msdeploy.axd?site=api'}"
psake DeployAngular -parameters "@{'web_deploy_endpoint'='https://server.example.com:8172/msdeploy.axd?site=angular'}"
@echo off
::Lists all packages in name order, finds the ones named "psake", and keeps the name of the last one (highest version)
FOR /F "tokens=*" %%F IN ('dir packages /b /on ^| find "psake"') DO (
SET version=%%F
)
::Call psake with the latest version available. Pass arguments given to this file
packages\%version%\tools\psake.cmd %*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment