Part 3: The Development Environment

If you've been following our Underneath the UI series, by now you should have a good idea of how our front-end and API stacks look. In this part 3, we'll talk about eve's development environment—how we wire everything up, our daily engineering process, the continuous integration and delivery solutions we employ in-house, and so on.

Local Environment

The simpler a tool or workflow is to adopt and use, the easier it is for a busy development team to get value from it. This isn’t just a nice-to-have property, it’s essential. —Lei Zhang, Head of Bloomberg’s Developer Experience group

We've all been there: our first day at a new job, so fresh and excited for all the upcoming challenges. But before all else, we need to set up our local development environment. Let's start with installing… erm, PHP? It can't be that hard, right? Only, what version is the company using again? Should we use Homebrew, Docker, a pre-built binary package, or go for the hardcore mode and build everything from source? What extensions should be included by default? What would be a sensible ini value for upload_max_filesize? Then, what about the database? The web server, or a combination of them for that matter? The environment variables? One hundred hours and a thousand config files later, the excitement is all gone and we start questioning our career choice.

Perhaps the best thing about Laravel, our backend framework of choice, is that it's not just one single technical solution but an exhaustive developer experience. Apart from the built-in functionalities, Laravel provides a vast of first-party packages to aid in almost all of your business and technical needs. Want to integrate your application with payment processors such as Stripe? Pull in Cashier. Need to enable full-text search for your content? Install Scout. And to solve the local environment issue, Laravel provides Homestead, a shared dev environment solution powered by Vagrant.

Out of the box, Homestead comes with a complete set of Ubuntu, Git, multiple PHP versions, Composer, PostgreSQL/MySQL, Redis, nginx etc. With Homestead, a fully-functional workstation is literally a single vagrant up command away:

$ vagrant up
Bringing machine 'homestead' up with 'virtualbox' provider...
==> homestead: Checking if box 'laravel/homestead' version '10.1.1' is up to date...
==> homestead: Clearing any previously set forwarded ports...
==> homestead: Clearing any previously set network interfaces...
==> homestead: Preparing network interfaces based on configuration...
==> homestead: Forwarding ports...
...
==> homestead: Machine booted and ready!
==> homestead: Checking for guest additions in VM...
==> homestead: Setting hostname...
==> homestead: Configuring and enabling network interfaces...
==> homestead: Mounting shared folders...
...

$ vagrant ssh
Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-48-generic x86_64)

 _                               _                 _
| |                             | |               | |
| |__   ___  _ __ ___   ___  ___| |_ ___  __ _  __| |
| '_ \\ / _ \\| '_ ` _ \\ / _ \\/ __| __/ _ \\/ _` |/ _` |
| | | | (_) | | | | | |  __/\\__ \\ ||  __/ (_| | (_| |
|_| |_|\\___/|_| |_| |_|\\___||___/\\__\\___|\\__,_|\\__,_|

* Homestead v12.0.0
* Settler v11.0.0 (Ubuntu 20.04)

Last login: Tue Apr  6 09:51:36 2021 from 10.0.2.2
➜  api art tinker
Psy Shell v0.10.7 (PHP 7.4.11 — cli) by Justin Hileman
>>> app()->version()
=> "8.33.1"

Swift and steady. No more configuration hell. Also, since everyone has the same setup now, gone is the infamous "It works on my machine ¯\(ツ)/¯™" syndrome. One can't ask for a developer experience smoother than that, really.

Version Control and Branching Model

Like almost everyone else nowadays, we use Git (hosted by GitHub) as our version control software. Our repository is a monorepo—a repository that contains the code for several projects. As with effectively everything else in this industry, there are arguments for and against monorepos (or their counterpart, polyrepos), but we've found this approach to suit us the best—as does it software giants like Google, Facebook, Microsoft, Uber, Twitter, Airbnb, and others.

For branching model, instead of the popular Git flow which can be unnecessarily complex and in fact has been discouraged by its own author, we embrace the much simpler GitLab flow catering to our setup:

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/c6f056e0-ee33-4e83-a50b-2eb5ed643d0c/flow_(2).svg

With this model, we maintain two long-lived branches: master, which is deployed onto staging, and production, which is deployed onto, well, production. All feature branches are created from and merged into master, which in turn is periodically merged into production. Hotfixes, due to their high-priority nature, are branched directly from production; however, they are synchronized back to master after deployment, ensuring the integrity between the two main branches.

This model has been proven to work extremely well with our continuous deployment pipeline, which we'll talk about in the next section.

Continuous Deployment

At eve, we maintain a continuous integration and deployment (CI/CD) pipeline that is at the same time powerful and straightforward, as shown in the diagram below: