- checkout latest version of source code from mainline/master
- verify first that the build is passing – if it’s failing, fix it first
- develop feature
- build source locally (in developer’s working copy)
- compilation/producing a running version of the app
- run tests
- this step should be automated
- when build passes, integrate changes into mainline (eg, push to master)
- integration machine runs build
- if conflicts occur from different working copies (eg, merge conflict from different devs), build fails – fix build
- if build fails for any reason, fix build
- bugs are found early because of frequent builds
- especially useful for any team with more than one person – conflicts found as soon as they are introduced
- reduced risk: at all times you know what works, and what bugs are present
- this depends on how good your test suite is
- frequent deployment -> rapid feedback
- single source repository
- rule of thumb: everything required for a build should be there
- source, tests, config/property files, etc
- security caveat for some files
- exclude files generated by the build (eg, class files, executables)
- rule of thumb: everything required for a build should be there
- automate the build
- automate every step of the build – ideally requiring only one command (eg, Rake)
- self-testing builds
- TDD is a good way to produce tests, but not necessary – what’s important is that there are tests
- test failure should fail the build
- integrating the mainline every day
- ie, pushing to master every day
- requirement: build must pass before changes are integrated
- every push should trigger a build on the integration server
- CI servers automate this, as well as notifying everyone of the build results
- manually triggering the build is also an option – it depends on the team’s discipline
- keep the build fast
- XP guideline: max 10 minutes
- usual bottleneck: tests, particularly involving the DB
- deployment/build pipeline
- commit build: the fast one
- slower builds can run slower tests (in parallel on other machines) regularly
- test in a clone of the production environment
- the more differences between the test/staging and production environments, the more possibilities of environment-related bugs going unnoticed
- try VMs
- everyone can see what’s happening
- everyone should know if a build failed or passed
- tools like Jenkins provide logs, statistics, and other data about builds that illustrate the status/health of projects
- automate deployment
- consider automated rollback for production
- eg, Capistrano
- in this case, the pull request must pass the build before being merged, which helps keep production environments pristine
Hosted
- https://travis-ci.org/
- https://circleci.com/
- https://semaphoreci.com/
- https://drone.io/
- https://www.atlassian.com/software/bamboo
You set up the hosting yourself
- https://jenkins.io/index.html
- https://about.gitlab.com/gitlab-ci/
- built-in CI for GitLab repositories
You’re doing Continuous Delivery when
- Your software is deployable throughout its lifecycle
- Your team prioritizes keeping the software deployable over working on new features
- Anybody can get fast, automated feedback on the production readiness of their systems any time somebody makes a change to them
- You can perform push-button deployments of any version of the software to any environment on demand
Requirements
- Build automation and Continuous Integration
- Test automation
- Deployment automation
Continuous Deployment vs Continuous Delivery
- Continuous Deployment means that every change goes through the pipeline and automatically gets put into production, resulting in many production deployments every day
- Continuous Delivery just means that you are able to do frequent deployments but may choose not to do it, usually due to businesses preferring a slower rate of deployment
- Continuous Integration, by Martin Fowler
- Continuous Delivery, by Martin Fowler
- Continuous Delivery/Deployment articles (Martin Fowler’s website)
- Continuous delivery pipeline, by Andrew Phillips