Deployment gets the code you and your team have written out into the world. Any system you've written that isn't deployed, and in front of a user, isn't generating value. It's also not giving you feedback about your product and how it helps your users. Hence getting deployment going is one of the first things most engineering teams (even if that's just you on day 1!) do when they start to build a product.
Like most items constructed at the start of a company or product's life, we often create the fastest, simplest ~solution~ hack as our deployment system: "I just need something that works, and I'll worry about making it better later."
This is a mistake.
The system that gets your code from your engineers to the customer is the most crucial piece of engineering tooling you'll build: ever.
The capabilities, quality, and performance of your deployment system directly correlate to the speed to market of your product, both in generating value and addressing user feedback and issues. Not only this, your deployment frequency and outcomes represent one of the (rare) early measurements of engineering velocity and quality. If your product or business partners are complaining about things moving too slow, then this is one of the first places you should look. Finally, getting code in front of users and seeing your product in action makes your engineers happy.
You may get a lot of pressure to develop features and not spend time on this kind of tooling, as a manager you need to make sure that you have given the team room to develop this tooling.
When you build that crucial first deployment system you need to build upon the right principles: what can be summarized as CI/CD or Continuous Integration/Continuous Delivery:
- Everybody should be able to deploy.
- Deployment should be automatic and continuous.
You can then scale your deployment system instead of refactoring it every time your organization scales. This comes with some risk of premature optimization but I believe that risk is outweighed by the rewards: faster deployment, enhanced developer happiness, and faster speed to market.
Let's look at each principle.
Everyone on your team should be able to deploy. A good deployment system should be continuous and not gated. Deployment systems triggered by intermediaries, "approvers," or small groups, like QA teams, are inherently hamstrung. Firstly, this model removes a developer's ownership of the deployment of their code and its outcomes. Worse, it sometimes transfers ownership of the code that is being deployed, disconnecting an engineer from the reality of the systems for which they write code. Secondly, these models are slow by design. They exist to put roadblocks in the way of your code getting deployed.
Code sitting in repositories or in branches is also not adding value. Any deployment process should optimize for putting the system into use as fast as possible. My preference has always been to deploy any code merged to
master automatically to production.
There has also always been a lot of debate over how to manage development and code branching processes to get that code merged. Again, my personal preference has always been to make use of GitHub Flow which states:
masterbranch can always be deployed.
- Everything is branched off
masterand named for a feature or issue.
- Do your work on that branch locally and regularly push your work upstream to the server.
- Merge by opening a pull request, having it reviewed, and then merging it to
- Automatically deploy
With the GitHub Flow, we optimize for small, short-lived branches to reduce the risk of merge conflicts and disruption and to increase the velocity of code being pushed and deployed. Your commit-to-deploy time is another good, early measure of your team's development velocity.
If you are worried about inter-dependencies or features being developed over longer time frames, for example in stages, you can make use of feature flags to hide features that aren't ready for prime time or not yet complete. Feature flags also encourage early user and integration testing. They additionally provide your engineers with a sense that a feature is evolving and work is progressing, rather than being stuck in a long-lived branch.
If you do have to put in an approval process to satisfy compliance or regulatory requirements then the GitHub Flow allows you to lock off the
masterbranch from direct pushes and require approvals on pull requests.
Once you have a deployment system that provides everyone on your team the ability to deploy automatically and continuously, the return on investment will be tangible and measurable. If your deployment system meets these two objectives then you're building on a good foundation that will allow you to scale as your team and company grows.