Modern Applications - How we do work
What this is:
- Process based
- How we ensure "quality"
- How we automate ourselves out of a job
- So we can move onto bigger\better things
What this isn't:
- How to write code
- Seriously though
- SOLID\DDD principles
- Basic architectural patterns
- Write tests
- That's the basics
- Seriously though
- Frameworks, libraries, etc
Why should I listen to you?
- Been automating myself out of a job since I got here
- Started with nant + CC.net
- Moved to PSake + TeamCity
- Have automated over 30 projects
- Have automated most of the products we support
- e.g. SharePoint, CRM
- I love this stuff
Why should I care?
- Deployments should be boring and predictable
- When they're not, make them so
- Signs you're doing it wrong:
- Deploying and leaving the office at 4am*
- Copy\pasting files
- Manually editing stuff post-"deployment"
- A giant document of steps to follow
- Nervous before every deployment
- Same people deploying each time
*Unless it genuinely takes that long
General Process
- Source control\Gitflow
- Build script + local runner
- TeamCity for CI
- Octopus Deploy for deployments\CD
Source Control\Gitflow
Visual Studio Online
- Git + command line tools (seriously learn them)
- Create master/develop branches
- Lock them for PRs only
- Set develop as default branch (saves time on PRs)
Git + command line tools
- Learn them. Seriously.
- You'll actually understand what you're doing
- When something goes wrong you can rectify it
- Most GUIs fall short when you're in a strange land
- Takes maybe 2-3 days to cover most use cases
- Poshgit for powershell is great
Poshgit

Gitflow - out of scope
- Huge topic, lots of knowledge in MA around this
- Day to day process as a developer
- Create feature branches off develop
- Finish work
- Run go.bat and ensure it works locally
- Push to VSO
- Create PR back into develop
Pull Requests

Here's one we prepared earlier: Example
Pull Requests
- Review of your work by someone else
- Ego-less
- Time to reflect and spot improvements\shortcuts
- Shortcuts = technical debt
- Hit by a train = no biggy, someone else knows whats up
- Comments to indicate decisions\history
Build Script + go.bat
General process of a build script
- Clean
- Nuget restore
- Compile
- Deploy database changes
- Run unit\integration tests
- (Build Server only) Create and publish deployment packages
- Any other project specific things
What NOT to put in a build script
- Anything you can't run again and again
- A lot of set up once and forget things
- Script those separately, e.g. IIS
- Deployment steps should not be in a build script
So how do I make one?
- PSake
- PowerShell commands
- That's it
- Lots of example scripts here
Basic build script example
properties {
#----------
#Properties
#PSake properties, these cannot be changed once they're defined
#----------
#----------
#Deployment Variables
#----------
#----------
#Environmental Variables for Development
#----------
$projectName = "ProjName"
$buildNumber = "DEV"
$config = "Release"
#----------
#Directories
#----------
$baseDir = Resolve-Path .
$sourceDir = "$baseDir\Source"
$toolsDir = "$baseDir\Tools"
$scriptsDir = "$baseDir\Scripts"
$artefactsDir = "$baseDir\Artefacts"
#----------
#Variable dependent properties
#Properties that depend on other variables to be defined first
#----------
$solutionFilePath = "$sourceDir\$projectName.sln"
$mainProjectFile = "$sourceDir\$projectName\$projectName.csproj"
#----------
#Project Specific Variables
#----------
$visualStudioVersion = "14.0"
}
#----------
#Includes
#Script files to include for function definitions
#----------
$path = Resolve-Path .
Include Scripts\Logger.ps1 -ErrorAction Stop
Include Scripts\VisualStudioExtensions.ps1 -ErrorAction Stop
Include Scripts\NUnitExtensions.ps1 -ErrorAction Stop
#-------------
#Build Targets
#Targets to build
#-------------
#-------------------------
#Targets
#-------------------------
task default -depends initial
task initial -depends preamble, clean, nugetRestore, compile, runUnitTests, postamble
task buildServer -depends initial
#-----------
#Build Steps
#Steps to execute
#-----------
task preamble {
Log "Executing build number: $buildNumber Mode: $config" Green
}
task postamble {
$date = Get-Date
Log "Build number $buildNumber complete at $date" Green
}
task clean {
Log "Cleaning solution $solutionFilePath" Green
Clean-VisualStudioSolution $solutionFilePath $config $isBuildServerTarget $visualStudioVersion
}
task nugetRestore {
Log "Restoring nuget packages for the solution" Green
Push-Location $sourceDir
$nugetExe = ".nuget\nuget.exe"
&$nugetExe "restore"
Pop-Location
Log "Nuget packages successfully restored" Green
}
task compile {
Log "Building solution $sourceDir\$projectName.sln in $config mode" Green
Build-VisualStudioSolution $solutionFilePath $config $isBuildServerTarget $visualStudioVersion
}
task runUnitTests {
Log "Recreating artefacts directory" Green
Remove-Item $artefactsDir -Recurse -Confirm:$false -ErrorAction SilentlyContinue
New-Item -ItemType Directory $artefactsDir
Log "Artefacts directory recreated" Green
Log "Running Unit Tests" Green
Copy-FilesFromDirectories "$sourceDir\Test\*Test*\bin\$config" $artefactsDir
$tests = Get-ChildItem $artefactsDir\*.Test*.dll -Exclude $excludedProjectRegex
Foreach ($test in $tests) {
$testPath = $test.FullName
$testName = $test.Name
Log "Running test suite: $testName" Yellow
Run-Nunit $toolsDir $testPath $resultsDir
}
}
#-----------
#Generalised functions
#Any other generic functions can be stored here
#-----------
Generic go.bat runner
@echo off
powershell.exe -NoProfile -ExecutionPolicy unrestricted -Command "import-module .\Tools\PSake\psake.psm1; invoke-psake build.ps1 %1 -properties @{config='Release'; buildNumber='dev'} -framework 4.0x64;if ($psake.build_success -eq $false) { exit 1 } else { exit 0;}"
TeamCity
TeamCity role
- Automated running of the build script
- Red\green indicators of success
- Proves it works on more than just my machine
- Creates and uploads packages to Octopus' Nuget server
Considerations and tradeoffs
- Build script running =\= build steps in TC
- Logging\feedback for PS scripts is painful
- Dumpster diving when things go wrong
Benefits
- Same process on build\local
- Confidence that my changes "work"
- Can run the build hundreds of times locally to see changes
- Ensures one final "good to go" run before checking in
- Eliminates "works on my machine" conversations
What about nightlies?
- Used for long running processes
- Code coverage + deployment of MKDocs documentation
- Full system integration tests that take hours
- Attaching live data and running integration tests
- etc
Octopus Deploy
Octopus Role
- Automate deployments
- Change config values per env
- Remove all manual steps
- Click "go" and wait
- It deploys everything for us
- Provides feedback
- Can deploy to hundreds of machines painlessly
Demo time
Future things I'm excited about
Modern Applications - How we do work
By kylemuir
Modern Applications - How we do work
A brief rundown of how Modern Apps in Intergen does work
- 505