SlideShare a Scribd company logo
Advanced CI
I’m Dirk Zittersteyn,
Software engineer @ since mid 2013
Did some stuff
@ before that
The wonderful world of
Continuous Integration.
A.k.a.:
Getting to green
Version Control
Is your team larger than 1 person?
Use version control.
Is your team 1 person?
Use version control.
Big (open source) players
Version control can look
overly complicated
Codebase
More awesome
WorkingonfeatureX
BuiltfeatureY
FinishedfeatureX
Mainline branch
Mainline branch
The mainline stays deliverable
Mainline branch
Branch “New feature”
$ git branch
$ hg branch
$ svn copy
Mainline branch
Branch “New feature”
Mainline branch
Branch “New feature”
Mainline branch
Branch “New feature”
Integrate your changes
Concurrent work!
Concurrent work
Mainline branch
Branch “New feature”
Branch “Other feature”
Toavoid“IntegrationHell”
So, are we done?
Concurrency is hard
Meet Charlie.
My code
isn’t
broken!
My code
isn’t
broken!
You better check yo build
Before you wreck yo build
Ice Cube
!
Mainline should be green
Agreement ≠ Reality
Missing testcases
“It’s so simple, it won’t break”
Agreement ≠ Reality
‘Bad’ commits
$ git commit -m ’removed debug statement’
Agreement ≠ Reality
Quick fixes w/o running tests
$ git commit -m ’server no longer explodes’
But wait, there’s more!
+ =
!+ = !
Mainline + Branch = New Mainline
!+ != ?
Yes!
!+ !=
Yes(ish)!
!+ !=
Assuming everything is okay.
e.g.
all environments are the same,
nobody is removing tests,
nobody is setting this up to happen
!+ !=
+ = ?
Mainline:
add(a, b):
result = a + b
return result
test_add():
assert add(1,1) == 2
+ = ?
Developer A:
add(a, b):
+ g.adds += 1
result = a + b
return result
test_add():
+ g.adds = 0
assert add(1,1) == 2
+ assert g.adds == 1
Developer B:
add(a, b):
result = a + b
+ g.adds += 1
return result
test_add():
+ g.adds = 0
assert add(1,1) == 2
+ assert g.adds == 1
Merge A’s changes with mainline
add(a, b):
+ g.adds += 1
result = a + b
return result
test_add():
+ g.adds = 0
assert add(1,1) == 2
+ assert g.adds == 1
Merge B’s changes with mainline
add(a, b):
g.adds += 1
result = a + b
+ g.adds += 1
return result
test_add():
g.adds = 0
assert add(1,1) == 2
assert g.adds == 1
add(a, b):
g.adds += 1
result = a + b
g.adds += 1
return result
test_add():
g.adds = 0
assert add(1,1) == 2
! assert g.adds == 1
!+ =
!
Developer A
Developer B
Does this happen?
if ((err = SSLFreeBuffer(&hashCtx)) != 0)
goto fail;
if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &clientRandom)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
goto fail;
! goto fail;
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
goto fail;
At least, that’s what the NSA wants you to think
Just because you're paranoid
doesn't mean that they're not after you
Joseph Heller
Developers shouldn’t change the mainline
Every merge is a change!
Oh merciful
Gatekeeper, please
merge my code!
✓
!
!
Calm down, Try again
!
Calm down, Try again
!
What do we use?
Our judge, jury and execut(ion)er
Jenkins-CI.org
• Test execution:
py.test
• Code merging
Gatekeeper plugin
• Developer notification
Fogbugz plugin
.com/ /paylogic-jenkins-plugins
Running on
Bare metal
Running on
+
Bare metal
Release 1418
Unstable
Unstable
Release 1418
Case 1
Case 2
Unstable
Release 1418
Case 1
Case 2
Unstable
Release 1418
Case 1
Case 2
Unstable
Release 1418
Case 1
Case 2
Unstable
Release 1418
Case 1
Case 2
Unstable
Release 1418
✓
Case 1
Case 2
Unstable
Release 1418
✓
Case 1
Case 2
Unstable
Release 1418
✓
Case 1
Case 2
Unstable
Release 1418
✓
Case 1
Case 2
Unstable
Release 1418
✓
!
Case 1
Case 2
!
Unstable
Release 1418
✓
Case 1
Case 2
!
Unstable
Release 1418
✓
Case 1
Case 2
!
Unstable
Release 1418
✓
Case 1
Case 2
!
Unstable
Release 1418
✓
Case 1
Case 2
!
Unstable
Release 1418
✓
✓Case 1
Case 2
!
Unstable
Release 1418
✓
✓
✓
Case 1
Case 2
!
Unstable
Release 1418
✓
✓
✓
Staging
✓
Case 1
Case 2
!
Unstable
Release 1418
✓
✓
✓
Staging
✓
Release 1420
Case 1
Case 2
So, are we done?
Advanced Continuous Integration - PyGrunn 2014 - Dirk Zittersteyn
Advanced Continuous Integration - PyGrunn 2014 - Dirk Zittersteyn

More Related Content

Similar to Advanced Continuous Integration - PyGrunn 2014 - Dirk Zittersteyn

Git Merge, Resets and Branches
Git Merge, Resets and BranchesGit Merge, Resets and Branches
Git Merge, Resets and Branches
Victor Pudelski
 
Working with Git
Working with GitWorking with Git
Working with Git
Sanghoon Hong
 
Code Management
Code ManagementCode Management
Code Management
Y. Thong Kuah
 
Git Distributed Version Control System
Git   Distributed Version Control SystemGit   Distributed Version Control System
Git Distributed Version Control SystemVictor Wong
 
Continuous Delivery: The Dirty Details
Continuous Delivery: The Dirty DetailsContinuous Delivery: The Dirty Details
Continuous Delivery: The Dirty Details
Mike Brittain
 
Grails Plugins
Grails PluginsGrails Plugins
Grails Plugins
NexThoughts Technologies
 
Data Binding in qooxdoo
Data Binding in qooxdooData Binding in qooxdoo
Data Binding in qooxdoo
Martin Wittemann
 
Build Automation? It's a piece of Cake.
Build Automation? It's a piece of Cake.Build Automation? It's a piece of Cake.
Build Automation? It's a piece of Cake.
Guilherme Ferreira
 
Mutation testing with PIT
Mutation testing with PITMutation testing with PIT
Mutation testing with PIT
Rafał Leszko
 
Be a Happier Developer with Git / Productive Team #gettinggitright
Be a Happier Developer with Git / Productive Team #gettinggitright Be a Happier Developer with Git / Productive Team #gettinggitright
Be a Happier Developer with Git / Productive Team #gettinggitright
Shunsuke (Sean) Osawa
 
Introduction To Git Workshop
Introduction To Git WorkshopIntroduction To Git Workshop
Introduction To Git Workshop
themystic_ca
 
Becoming a Git Master
Becoming a Git MasterBecoming a Git Master
Becoming a Git Master
Nicola Paolucci
 
Working with Git
Working with GitWorking with Git
Working with Git
Pete Nicholls
 
Hurdles the sprint with impediments on the way to automation
Hurdles   the sprint with impediments on the way to automationHurdles   the sprint with impediments on the way to automation
Hurdles the sprint with impediments on the way to automation
vinodpthmn
 
Hurdles, the sprint with impediments on the way to automation
Hurdles, the sprint with impediments on the way to automationHurdles, the sprint with impediments on the way to automation
Hurdles, the sprint with impediments on the way to automation
vinodpthmn
 
Achievement Unlocked: Drive development, increase velocity, and write blissfu...
Achievement Unlocked: Drive development, increase velocity, and write blissfu...Achievement Unlocked: Drive development, increase velocity, and write blissfu...
Achievement Unlocked: Drive development, increase velocity, and write blissfu...
All Things Open
 
VersionEEring
VersionEEringVersionEEring
VersionEEring
Ruthie BenDor
 
Introduction to Agile
Introduction to AgileIntroduction to Agile
Introduction to Agile
Charlotte Chang
 
Refactoring
RefactoringRefactoring
Refactoring
Amir Barylko
 

Similar to Advanced Continuous Integration - PyGrunn 2014 - Dirk Zittersteyn (20)

Git Merge, Resets and Branches
Git Merge, Resets and BranchesGit Merge, Resets and Branches
Git Merge, Resets and Branches
 
Working with Git
Working with GitWorking with Git
Working with Git
 
Code Management
Code ManagementCode Management
Code Management
 
Git Distributed Version Control System
Git   Distributed Version Control SystemGit   Distributed Version Control System
Git Distributed Version Control System
 
Continuous Delivery: The Dirty Details
Continuous Delivery: The Dirty DetailsContinuous Delivery: The Dirty Details
Continuous Delivery: The Dirty Details
 
Grails Plugins
Grails PluginsGrails Plugins
Grails Plugins
 
Data Binding in qooxdoo
Data Binding in qooxdooData Binding in qooxdoo
Data Binding in qooxdoo
 
Build Automation? It's a piece of Cake.
Build Automation? It's a piece of Cake.Build Automation? It's a piece of Cake.
Build Automation? It's a piece of Cake.
 
Mutation testing with PIT
Mutation testing with PITMutation testing with PIT
Mutation testing with PIT
 
Be a Happier Developer with Git / Productive Team #gettinggitright
Be a Happier Developer with Git / Productive Team #gettinggitright Be a Happier Developer with Git / Productive Team #gettinggitright
Be a Happier Developer with Git / Productive Team #gettinggitright
 
Introduction To Git Workshop
Introduction To Git WorkshopIntroduction To Git Workshop
Introduction To Git Workshop
 
Becoming a Git Master
Becoming a Git MasterBecoming a Git Master
Becoming a Git Master
 
Gittalk
GittalkGittalk
Gittalk
 
Working with Git
Working with GitWorking with Git
Working with Git
 
Hurdles the sprint with impediments on the way to automation
Hurdles   the sprint with impediments on the way to automationHurdles   the sprint with impediments on the way to automation
Hurdles the sprint with impediments on the way to automation
 
Hurdles, the sprint with impediments on the way to automation
Hurdles, the sprint with impediments on the way to automationHurdles, the sprint with impediments on the way to automation
Hurdles, the sprint with impediments on the way to automation
 
Achievement Unlocked: Drive development, increase velocity, and write blissfu...
Achievement Unlocked: Drive development, increase velocity, and write blissfu...Achievement Unlocked: Drive development, increase velocity, and write blissfu...
Achievement Unlocked: Drive development, increase velocity, and write blissfu...
 
VersionEEring
VersionEEringVersionEEring
VersionEEring
 
Introduction to Agile
Introduction to AgileIntroduction to Agile
Introduction to Agile
 
Refactoring
RefactoringRefactoring
Refactoring
 

Recently uploaded

Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
Deuglo Infosystem Pvt Ltd
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
E-commerce Application Development Company.pdf
E-commerce Application Development Company.pdfE-commerce Application Development Company.pdf
E-commerce Application Development Company.pdf
Hornet Dynamics
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
Google
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
Google
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
Max Andersen
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
timtebeek1
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
Aftab Hussain
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
Shane Coughlan
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
Ayan Halder
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
Alina Yurenko
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
Rakesh Kumar R
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
TheSMSPoint
 
AI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website CreatorAI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website Creator
Google
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
Octavian Nadolu
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 

Recently uploaded (20)

Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
E-commerce Application Development Company.pdf
E-commerce Application Development Company.pdfE-commerce Application Development Company.pdf
E-commerce Application Development Company.pdf
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
 
AI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website CreatorAI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website Creator
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 

Advanced Continuous Integration - PyGrunn 2014 - Dirk Zittersteyn

Editor's Notes

  1. Thanks for the intro I’m Dirk Zittersteyn I’ll be talking about continuous integration
  2. But you’re not here to hear about me
  3. This is a screenshot of a build of mine on paylogic’s CI server The green light is so satisfying
  4. It’s like your code is saying: Well done! So how do you get there?
  5. First off, Version control.
  6. Still use version control.
  7. Which one? Git is cool, Mercurial is python, subversion is a wise old granddad
  8. Now we have some very powerful tools. But they seem to do things very complicated! They don’t magically make things awesome!
  9. You have some codebase, and you start implementing a sweet new feature
  10. Clearly your project is now better
  11. What if you break your build? Can’t deploy! Can’t do anything before fixing the bug! This workflow breaks down with multiple people.
  12. Also, you can’t deploy quickly.
  13. You’ve gone from something that’s pretty useless
  14. To something that’s way more advanced, but still useless
  15. Let’s solve this. This mainline can be your ‘base’ branch, In Git: Master In Mercurial: Default In SVN: Trunk (kinda) Or any other branch, by convention
  16. Deliverable means: it works.
  17. You create a branch, which is a copy of the mainline
  18. You work on your copy, and you commit Nothing happens in the mainline
  19. You can break your branch, but not the mainline!
  20. And when you’re convinced your feature is done, you merge!
  21. You can now do more than one thing at the same time!
  22. You decide to work on two features, at the same time!
  23. Integrate Often! Why? Glengarry GlenRoss
  24. The longer you wait to integrate, the harder it is.
  25. That would make for a really short talk We aren’t.
  26. Not just in algorithms, also in development!
  27. Charlie is a programmer. He thinks he’s quite clever.
  28. Now obviously, I would never commit broken code, But charlie does!
  29. Now your mainline is broken!
  30. And it breaks for everyone!
  31. Finger pointing results And finger pointing can be very wrong.
  32. My code might be buggy as well, but hidden by the other bug! This situation is so common…
  33. Someone made the effort to make this. How do we solve this?
  34. Don’t merge broken code! Never!
  35. You make an agreement with your devs: Don’t commit broken code.
  36. It’s so easy, it won’t break anything
  37. For example accidentally leaving debug statements in your code
  38. But even when you disregard this
  39. Even when you do everything right, we’re making an assumption
  40. Merging good code in a good mainline results in a good new mainline
  41. And we want to count the number of adds we do.
  42. Well, maybe?
  43. Ofcourse, there are plenty of people that say this is an intentional vulnerability, Used by the nsa to spy on us. Joseph heller said the following in the book catch-22
  44. This not only works for Surveilance agencies, but also for keeping your mainline safe.
  45. Ergo, developers shouldn’t do the merging
  46. We start with a mainline
  47. You branch
  48. And somebody makes a change in the mainline (doesn’t matter how)
  49. You test your build
  50. You test your build
  51. And the build is successful
  52. You request
  53. The Gatekeeper merges the code into the mainline, but doesn’t commit yet! First the build is tested
  54. If the build succeeds?
  55. The changes are commited to the mainline Much rejoicing
  56. The merge is discarded, And the developer is notified
  57. Developer f
  58. And ask for forgiveness
  59. With a very pretty please.
  60. For bare metal we use our ‘old’ hardware, using Wake-on-LAN to conserve power When the bare metal is fully used, and there’s still more, we spin up a couple of DigitalOcean droplets Tasks are distributed over multiple nodes with py.test xdist
  61. For bare metal we use our ‘old’ hardware, using Wake-on-LAN to conserve power When the bare metal is fully used, and there’s still more, we spin up a couple of DigitalOcean droplets Tasks are distributed over multiple nodes with py.test xdist
  62. And the cycle continues!
  63. That would make for a really short talk We aren’t.