Our Quest for Continuous Delivery

Part 1: Enter GitLab

Overview

The Promevo Engineering team is leveling up! Follow along as we chronicle our journey to achieving Continuous Delivery!

In this article, we set the scene and describe some recent improvements we've made to our delivery model.

Background

We host our SaaS product, gPanel, on the Google Cloud Platform (GCP). More specifically, we run on Google App Engine. As a Google Partner, we are all in on GCP. Whenever we have a choice to make in terms of tooling or hosting, our default is to use GCP.

Our source code has been hosted on Google Cloud Source Repositories, and it has served us well as a sturdy git repository.

The gPanel development team here at Promevo operates in one week iterations. We plan our work at the beginning of the week, we execute during the week, and we release at the end of the week. This is common practice across the tech industry.

The Goal

Common? We don't want to be merely common! We want to be uncommonly awesome! Why should our customers have to wait for features to be batched up and delivered as a bundle, when we could put the feature in their hands as soon as it's ready? The seminal book, Accelerate, by Forsgren, Humble, and Kim, makes the case that tech organizations that embrace Continuous Delivery (CD) separate themselves from those that don't. The book supports (with data) the claim that teams that leverage CD outperform those that don't. This correlates strongly with a business advantage in the marketplace. I won't go deeper here, but suffice it to say that CD is what we are striving for here at Promevo.

How do we get there?

One of the tactics that facilitates CD is trunk based development. "Yes", we said, "we want that too!" Using the aptly named website, https://trunkbaseddevelopment.com/ as a guide, we designed a model that works for us.

Developer experience is another important factor to us. We want onboarding to be as frictionless as possible. We want developers to be able to build new features and roll them out frequently and smoothly.

Using these principles to guide us, we drafted up a design of our ideal workflow and release pipeline. We put some boxes and arrows on a Jamboard, iterated a bit, then stepped back and nodded in agreement. "Yes", we agreed, "this is the way."

One of the glaring deficiencies in the GCP CI/CD ecosystem is a lack of tooling to support a Pull Request flow. Thus far in Promevo's journey, we've managed to deliver without this. However, we've decided that it is too important to our vision to do without. Our team is projected to grow, and in the interest of quality, communication, and developer experience we are choosing to use the GitLab platform as a basis for our vision. Pull Requests (called Merge Requests in GitLab) are a first class feature. Using this workflow is important to us, and it will be used as a gate before merging to our Main branch. The Developer submits a Merge Request, and it will require an approval. The Approver can comment, suggest changes, insist on unit tests, etc. The Developer and Approver can iterate until it is suitable to merge.

But, our Merge Request stage has some secret sauce! And this may be the most exciting part of our flow!

  1. The Developer implements the change on their local workstation (Green box in the above diagram)

  2. Once satisfied with their change, the Developer then pushes to a short-lived branch in GitLab

  3. This will trigger a pipeline that will build, test, and deploy to a dynamically provisioned environment in GCP (Pink box)

  4. The developer can visit a URL and see their changes deployed to an isolated and "private" environment

The developer may spot something unexpected, and can push more changes until they are satisfied with the functionality. At this point, we can signal that we are ready for the Approver to review the code. The Approver can also visit the URL and see working software alongside the Merge Request. This is game changing for everyone! As an Approver, you'll get so much more context than just a code diff. You can actually see what that UI change looks like, or take a back end feature for a spin before approving and merging it in.

Our CI process also runs immediately when a Merge Request is created. If any of our unit tests fail, the developer is alerted that there is still work to do before asking for review. This all supports the "shift left" mentality, which puts more onus for quality on the developer. We want to flag any quality concerns as soon as possible, as opposed to the old time model of finding bugs weeks after code was written.

Having a Merge Request workflow will facilitate team growth, as it gives us a chance to gate changes and communicate expectations to new team members. For example, a reviewer may comment "Sorry, I can't approve this Merge Request, it doesn't appear that you've written any unit tests".

Get value to the customer, ASAP!

Ok, we've covered the first part of our delivery model. The developer has checked all the boxes, and gotten their Merge Request approved and merged. Now what?

Stay tuned for the next installment of "Our Quest for Continuous Delivery!"