Automated release management - DevConFu 2014

705 views

Published on

Published in: Software
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
705
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
33
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Automated release management - DevConFu 2014

  1. 1. 03.06.2014 / 1
  2. 2. AUTOMATED RELEASE MANAGEMENT WITH TEAMCITY & OCTOPUSDEPLOY
  3. 3. CONTINOUS DELIVERY 03.06.2014 / 3
  4. 4. Continuous Integration 03.06.2014 / 4
  5. 5. Continuous Deployment 03.06.2014 / 5
  6. 6. Continuous Delivery 03.06.2014 / 6
  7. 7. It’s all about frequent releases 03.06.2014 / 7 John Allspaw: “Ops metametrics” http://slidesha.re/dsSZIr It’s all about failing fast
  8. 8. It’s all about expanding your horizon
  9. 9. Developer responsibility horizon •Dude, it compiles! •It works on my machine •All tests pass •QA approved it •It’s working in production “We don’t know, man, we just don’t know.” The confident Nick of months prior shook now, leading Fred to his cubicle. “We coded the application. We debugged until it compiled without errors. When we run it- core dump!” He threw up his hands, then dropped into his swivel chair. “We’ve been pestering IBM support, but they haven’t been very helpful.” “Well, why would they be?” Fred frowned, pausing at the cube threshold. “I mean, who knows what might be wrong with the code?” “Nothing’s wrong with it. It compiles!” “So? It could still have errors.” Nick swiveled around to face him. “Dude. It compiles.”
  10. 10. «Nothing at facebook is anyone elses problem» - Kent Beck (Is TDD dead –part 3)
  11. 11. The deployment pipeline 03.06.2014 / 11
  12. 12. Test coverage 03.06.2014 / 12 http://www.industrieit.com/blog/2012/02/a-practical-guide-to-extending-continuous-integration-to-continuous-delivery/ http://jamescrisp.org/2011/05/30/automated-testing-and-the-test-pyramid/
  13. 13. Blue-green deployment 03.06.2014 / 13 Jez Humble: “Continous Delivery” http://www.slideshare.net/jezhumble/continuous-delivery-5359386
  14. 14. Blue-green deployment 03.06.2014 / 14 Jez Humble: “Continous Delivery” http://www.slideshare.net/jezhumble/continuous-delivery-5359386
  15. 15. Blue-green deployment 03.06.2014 / 15 Jez Humble: “Continous Delivery” http://www.slideshare.net/jezhumble/continuous-delivery-5359386
  16. 16. Blue-green deployment 03.06.2014 / 16 Jez Humble: “Continous Delivery” http://www.slideshare.net/jezhumble/continuous-delivery-5359386
  17. 17. Canary releasing 03.06.2014 / 17 Jez Humble: “Four principles or Low-Risk Software releases” http://www.informit.com/articles/article.aspx?p=1833567
  18. 18. The arguments 03.06.2014 / 18
  19. 19. The arguments 03.06.2014 / 19 • Before: ~30 minutes • After: 4 minutes • 4 times per day • Time spent: 8 hours • Days until investment time paid: 8 ÷ 0.43 ÷ 4 = 4.65 ≈ 𝑗𝑢𝑠𝑡 𝑎𝑓𝑡𝑒𝑟 𝑙𝑢𝑛𝑐ℎ
  20. 20. 03.06.2014 / 20
  21. 21. DEPLOYING A WEBSITE 03.06.2014 / 21
  22. 22. Basic asp.net mvc4 website <hgroup class="title"> <h1>Welcome to ASP.NET Web API!</h1> <br /> <h2> @WebApiApplication.Environment - @WebApiApplication.Version </h2> </hgroup> 03.06.2014 / 22
  23. 23. Web.Development.config <?xml version="1.0"?> <configuration xmlns:xdt="http://schemas.microsoft.com/XML- Document-Transform"> <appSettings> <add key="Environment" value="Development“ xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/> </appSettings> </configuration> 03.06.2014 / 23
  24. 24. Creating the Octopus NuGet package • Why NuGet? – Metadata – Lots of available tools – Feed-based – Developers know how to use them – Already used for other purposes (check out chocolatey.org) • Does NOT use the default NuGet conventions – Octopus deploys the exact structure of the package 03.06.2014 / 24
  25. 25. mvc4webapi.nuspec <?xml version="1.0"?> <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <metadata> <id>Itera.NDC2013.TCOD.Web</id> <title>ASP.NET MVC 4 Web Api demo site</title> <version>1.0.0</version> <authors>Kristoffer Rolf Deinoff</authors> <owners>Kristoffer Rolf Deinoff</owners> <licenseUrl>http://itera.no</licenseUrl> <projectUrl>http://itera.no</projectUrl> <requireLicenseAcceptance>false</requireLicenseAcceptance> <description>A sample project</description> <releaseNotes>First release</releaseNotes> </metadata> </package> 03.06.2014 / 25
  26. 26. Using OctoPack 03.06.2014 / 26
  27. 27. Using TeamCity 03.06.2014 / 27
  28. 28. Using NuGet.exe nuget.exe pack $nuspecFileName -OutputDirectory $contentDir -Version $version 03.06.2014 / 28
  29. 29. Configuring TeamCity 03.06.2014 / 29
  30. 30. Configuring TeamCity – Commit build 03.06.2014 / 30
  31. 31. Configuring TeamCity – VCS root 03.06.2014 / 31
  32. 32. Configuring TeamCity – Patch AssemblyInfo 03.06.2014 / 32
  33. 33. Configuring TeamCity - Compile 03.06.2014 / 33
  34. 34. Configuring TeamCity – Commit tests 03.06.2014 / 34
  35. 35. Configuring TeamCity – Trigger on check-in 03.06.2014 / 35
  36. 36. Configuring TeamCity – Build artifacts 03.06.2014 / 36
  37. 37. Configuring TeamCity – NuGet Server 03.06.2014 / 37
  38. 38. Configuring TeamCity – NuGet Server 03.06.2014 / 38
  39. 39. Configuring OctopusDeploy - Environments 03.06.2014 / 39
  40. 40. Configuring OctopusDeploy – NuGet server 03.06.2014 / 40
  41. 41. Configuring OctopusDeploy – Steps 03.06.2014 / 41
  42. 42. Configuring OctopusDeploy – Publish website 03.06.2014 / 42
  43. 43. Configuring OctopusDeploy – Publish website 03.06.2014 / 43
  44. 44. Configuring OctopusDeploy – Smoke test 03.06.2014 / 44 $url = ("http://" + $hostname + ":" + $port + "/") Invoke-WebRequest $url -UseBasicParsing
  45. 45. Configuring OctopusDeploy – UAT Verification 03.06.2014 / 45
  46. 46. Configuring OctopusDeploy – Variables 03.06.2014 / 46
  47. 47. Configuring OctopusDeploy – Security 03.06.2014 / 47
  48. 48. Configuring OctopusDeploy – Security 03.06.2014 / 48
  49. 49. Configuring TeamCity – Integration build 03.06.2014 / 49
  50. 50. Configuring TeamCity – Dependencies 03.06.2014 / 50
  51. 51. Configuring TeamCity – Create release 03.06.2014 / 51
  52. 52. Configuring TeamCity – Integration tests 03.06.2014 / 52 $url = ("http://tcod-build:8080/") $TeamCitySession = New-Object Microsoft.PowerShell.Commands.WebRequestSession Invoke-WebRequest -Uri $url -WebSession $TeamCitySession -UseBasicParsing
  53. 53. DEPLOYING A SERVICE 03.06.2014 / 53
  54. 54. Asp.net mvc webapi as a service 03.06.2014 / 54 <appSettings> <add key="Environment" value="Local" /> <add key="Hostname" value="localhost" /> <add key="Port" value="8989" /> </appSettings>
  55. 55. And then… 03.06.2014 / 55
  56. 56. Differences - Steps 03.06.2014 / 56
  57. 57. Differences - Publish service 03.06.2014 / 57
  58. 58. Differences - Variables 03.06.2014 / 58
  59. 59. Differences - Automated «Acceptance test» 03.06.2014 / 59 $url = ("http://tcod-build:8090/api/version") $TeamCitySession = New-Object Microsoft.PowerShell.Commands.WebRequestSession $response = Invoke-WebRequest -Uri $url -WebSession $TeamCitySession -UseBasicParsing if ($response.Content.Contains("Development")){ Write-Host "Correct environment(Development)." } else{ Write-Host Environment 'Development' not found. Exit 1 } $buildNumber = $env:build_number if ($response.Content.Contains($buildNumber)){ Write-Host "Correct build number($buildNumber)." } else{ Write-Host Build number '$buildNumber' not found. Exit 1 }
  60. 60. WRITING POWERSHELLS SCRIPTS 03.06.2014 / 60
  61. 61. Deploy.config 03.06.2014 / 61 <?xml version="1.0"?> <configuration> <name>MyProject</name> <nuGet> <url>"http://www.myget.org/F/MyProject/"</url> <apiKey>xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx</apiKey> <username>myUser</username> <password>myPassword</password> </nuGet> </configuration>
  62. 62. CreateOctopusPackage.ps1 03.06.2014 / 62 param ([string]$contentDir, [string]$version) try{ $configFile = New-Object XML $configFile.Load('Deploy.config') $config = $configFile.configuration $nuspecFileName = $config.name+'.nuspec' $targetNuspecFileName = Join-Path $contentDir $nuspecFileName .nuget.exe pack $targetNuspecFileName -OutputDirectory $contentDir -Version $version } catch { Write-Error $error[0] Exit 1 }
  63. 63. PublishNuGet.ps1 03.06.2014 / 63 param ([string]$contentDir, [string]$version) try{ $configFile = New-Object XML $configFile.Load('Deploy.config') $config = $configFile.configuration $nugetFileName = $config.name+'.'+$version+'.nupkg' nuget sources Add -Name $config.name -Source $config.nuGet.url -Username $config.nuGet.username -Password $config.nuGet.password nuget push $nugetFileName $config.nuGet.apiKey -Source $config.name nuget sources Remove -Name $config.name } catch { Write-Error $error[0] Exit 1 }
  64. 64. CreateMSDeployPackage.ps1 03.06.2014 / 64 param ([string]$sourceDir, [string]$targetPackage) $BuildDir = (Split-Path $MyInvocation.MyCommand.Path -Parent) $msdeploy = $BuildDir + "msdeploy.exe" $parameterFile = $BuildDir + "parameters.xml" $msdeploy_params = " -verb:sync" $msdeploy_params += " -source:contentPath=" + $sourceDir $msdeploy_params += " -dest:package=" + $targetPackage $msdeploy_params += " -declareParamFile:" + $parameterFile Write-Host "creating '$targetPackage' from '$sourceDir'." try { iex "$msdeploy $msdeploy_params" } catch { Write-Error $error[0] Exit 1 }
  65. 65. Deploy.ps1 03.06.2014 / 65 . .DeployUtil.ps1 $ServiceName = "Itera.NDC2013.TCOD.Service" $ServiceExecutable = $ServiceName + ".exe" Install-WebApi-Service $ServiceName $ServiceExecutable
  66. 66. DeployUtil.ps1 03.06.2014 / 66 function Install-WebApi-Service($name, $executable) { Write-Host "'$name'$executable'" $service = Get-Service $name -ErrorAction SilentlyContinue $fullPath = Resolve-Path $executable if (! $service) { Write-Host "Installing service" $frameworkDir = Get-FrameworkDirectory Set-Alias install_util (Join-Path $frameworkDir "installutil.exe") install_util $fullPath } else { Write-Host "The service will be stopped and reconfigured" Stop-Service $name -Force & "sc.exe" config $service.Name binPath= $fullPath start= auto } $config = $executable + ".config" $port = Get-Port $config Set-User-Rights $port "NT AUTHORITYNETWORK SERVICE" Write-Host "Starting service" Start-Service $name | Write-Host }
  67. 67. DeployUtil.ps1 03.06.2014 / 67 function Get-FrameworkDirectory { $([System.Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory()) } function Set-User-Rights($port, $user) { $uri = "http://+:$port/" $acls = (netsh http show urlacl url=$uri | Select-String -SimpleMatch $user) if ($acls.count -eq 0 ) { Write-Host "Setting rights for '$user' on $uri" netsh http add urlacl url=$uri user=$user | Write-Host } else { Write-Host "Rights already set for '$user' on $uri." } }
  68. 68. DeployUtil.ps1 03.06.2014 / 68 function Get-Port($config) { Write-Host "Reading config file '$config'" $found = $FALSE $appConfig = [xml](cat .$config) $appConfig.configuration.appSettings.add | foreach { if ($_.key -eq 'Port') { $port = $_.value $found = $TRUE } } if (-not $found) { $port = "8080“ } $($port) }
  69. 69. AUTOMATING YOUR PROCESS 03.06.2014 / 69
  70. 70. Automating your process • Create environments and projects • Add all the automated build steps you can • Add manual steps for the rest • Automate manual steps one by one • You can have more than one tentacle on a server – Not as a service 03.06.2014 / 70
  71. 71. CONNECTING THE ISSUE TRACKER 03.06.2014 / 71
  72. 72. Connecting the issue tracker • Connect TeacmCity throught Settings – Issue Tracker • Connect your issue tracker to TeamCity • Use the Issue tracker’s web api to get issues pending user acceptance – Add them to releasenotes while deploying 03.06.2014 / 72
  73. 73. Kristoffer Rolf Deinoff Lead Technologist @gatepoet kristoffer.deinoff@itera.no

×