Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding intro to CI/CD aka Truss release best practices #59

Merged
merged 1 commit into from Jan 14, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
89 changes: 89 additions & 0 deletions developing/cicd/README.md
@@ -0,0 +1,89 @@
# [Tools and Practice](../README.md) / Intro to CI/CD

## Overview

The release process is one of the most important parts of development
for obvious reasons -- without a release, your code is never going to
actually be used by anyone. This page lays out Truss's method of using
continuous integration and continuous delivery (CI/CD) to deliver
software to customers.

## Developing Your Code

Here at Truss, we generally use Git for our code repository, and Github
more specifically. Our preferred method for making changes and integrating
them into the project is relatively simple:

1. Check out the repository for `my-project`.
2. Create a new branch `my-feature` in the repository.
3. Make your changes to the code and commit them, then push your code to
the central repository.
4. Create a pull request, get approvals, and then merge your `my-feature`
branch into `master`.

The virtue of this workflow over more complicated methods like the one
shown [here](https://nvie.com/posts/a-successful-git-branching-model/) is
that we are constantly merging to `master`, so the drift of any specific
branch from `master` is kept to a minimum. The idea of more frequent small
changes over less frequent large changes is a fundamental aspect of many
development practices (such as Agile). The core of this belief is that
things which break the the application can quickly be noticed, isolated,
and rolled back (or fixed), without requiring a lengthy period of
diagnosis, or requiring delicate operations to pull out problem code
without sacrificing code which is benign.

This process is known as *continuous integration* or CI (because code is
constantly being integrated into the mainline of the project). Its
relative simplicity belies the fact that it also requires a great deal
of additional work to ensure that this process can occur without
disrupting the project's development.

## Unit Testing

Key to ensuring that our CI workflow is safe is making sure we are doing
unit testing of our code *prior* to merging in to `master`. To do this,
we use automated tools like CircleCI to run a battery of tests against
every branch we create a PR from. We want to run a variety of tests that
cover a variety of things like:

* Code formatting and syntax
* Acceptance testing for configuration
* Functional code testing

Our goal is to be as sure as possible *before* anyone even looks at the
pull request that this code does what we want and won't break things.

## Deploying Our Code

Merging your code is just the first step to actually getting it in front
of a real person to use it. The other component for this how your code
gets from a Git repository into a live environment where someone can touch
it. This workflow is orchestrated via an automated tool like CircleCI, and
looks something like this:

1. New code is merged into `master`.
2. CircleCI detects that `master` has been updated and deploys the code to
our `development` environment.
3. CircleCI checks to make sure the deploy was successful. Is our
environment running the right version of the code?
4. CircleCI (or another tool fired by CircleCI) performs post-deployment
testing. Does it pass some functional tests to ensure user workflows
are functional (eg, can someone log in, pull up a user record, put
things in a shopping cart, etc)? Are logs filling up with error now
that the new version is deployed?
5. If the tests pass, CircleCI goes ahead and deploys to our `production`
environment, then runs the same sort of tests it ran in development.
In some cases, there may be an additional manual approval step, or
this may be a deployment to a `staging` environment as an additional
step prior to "real" production.

This means that we are constantly releasing new versions of our code to
users -- we may deploy a dozen times a day, all with a reasonable degree
of confidence that everything will be fine, thanks to our automated
tests. If something doesn't work, we can stop the process (or roll back,
if the problem is detected post-deploy), and users will be protected from
malfunctioning code. This *requires* that we write a battery of tests at
every stage of the release process, however.

This automated workflow that allows rapid release of merged code is called
*continuous delivery* or CD.