Anyone with the ability to merge PRs on GitHub can deploy the application. Whenever a PR is merged the code is deployed. When deploying complex code, be sure that other team members are around to help if something goes wrong.
Generally, it's a good idea to keep the SRE team in the loop on high risk deploys. However, deployments are our collective responsibility, so it's important to monitor your deploys. You can see deployment status on Travis-ci.com and in the #deployment-pipeline channel on Slack. Be prepared to rollback or push a fix for any deployment!
Forem relies on GitHub and Travis to deploy continuously to Heroku. If a Pull Request is merged it will automatically be deployed to production once the build steps complete successfully. The process currently takes about 20 minutes to complete and will need a few additional minutes before the change goes live.
In stage 1, we use KnapsackPro to divide our Rspec tests evenly between 3 different jobs (virtual machines). This ensures that each job takes relatively the same amount of time to run. After running our Rspec tests, we then run a series of other checks. These additional checks are split up between the different jobs. Here is a list of those additional checks that are run.
If all of the jobs pass then we move on to Stage 2 of the Travis CI process.
If the build was kicked off from a pull request being created or updated this stage will do nothing. If the branch has been merged into master, then this stage will kick off a deploy. The deploy will run in its own job deploying our application to Heroku.
Prior to deploying the code, Heroku will run database migrations, Elasticsearch updates, and do some final checks (more information on that below) to make sure everything is working as expected. If these all succeed, then the deploy completes and our team is notified.
We use Heroku's Release Phase feature. Upon deploy, the app installs dependencies, bundles assets, and gets the app ready for launch. However, before it launches and releases the app Heroku runs a release script on a one-off dyno. If that release script/step succeeds the new app is released on all of the dynos. If that release script/step fails then the deploy is halted and we are notified.
The name of the script we use is
release-tasks.sh and its in our root directory. During this release step we do a few checks.