In the first part of this series I spoke about what this whole thing means for us. In summary the three key focuses are: World-class product quality, fast delivery of smaller things and automating everything. In this post I will be going through how it is done.
How we work is what enables us deliver product everyday.
Each of our projects are on their own git repo. Each project is bootstrapped with package management, linting, code styling, unit test coverage reporting and a full-on build process. Every repo has
- a dev branch which aligns with staging environment.
- a master branch which aligns with production environment.
Staging is an environment identical to production (except the data), where everything is tested. To ensure it is identical to production, the staging servers are automatically destroyed at night and recreated from the production server images — every single day! Yes our staging servers are suicidal.
The largest thing we can work on is an “epic”. How long does an epic take? we don’t care. Epics are for planning larger things. They are there so we can hash out the requirements, best-in-class user experience and bullet-proof solution design. Everything is reviewed by another person. Nothing is written on stone. We plan so we have a clear picture of the larger focus. Whatever we plan changes most of the time.
Then they breakdown into stories which actually get done. Stories are small, they complete a smaller part of the epic. Every Monday, on an iteration meeting, we decide what we want to get done - only for that week.
Someone who picks up a story will start coding on a new branch (out of the dev branch). The feature/fix is coded along with unit tests. Once complete, a pull-request(PR) is created back to the dev branch. The PR is auto validated to make sure, it does not fail lint, it does not fail unit tests and covers unit tests 100%. If all is well the PR will be reviewed by another team member and merged into the dev branch.
At the same time a test engineer starts coding the end-to-end (e2e) tests for the same story. This ensures the full automation of the functional testing for that feature/fix. This step is only done as needed (new features or feature changes). The e2e PR is merged into dev along with the feature/fix PR.
Code from dev branch gets pushed into staging servers every three hours. The push would run the whole set of unit tests, create the build, run all e2e tests on the build and then deploy to the staging server. At this point all automated testing would have completed successfully, if the build is good.
Test engineers will hold the code on staging for further testing if they deemed it necessary. Once all manual tests are complete, a PR would be created from the dev branch to the master branch. This PR can hold multiple changes and will be merged by a third member who has not been involved in any of the change/review.
The push to production is automated to start everyday, somewhere around 2pm IST. The CI server would pick up changes on the master branch of each repo and start pushing them. During this push, unit tests and e2e tests are run again to make sure everything is good.
And that’s how we deliver awesomeness every single day!
My explanation here barely does justice to the complexity of the overall process. But you get the idea. The most important part that I haven’t spoken about is the constant improvements we do to our style of working. The culture of efficiency is what makes all of this possible.
In the next part I will be covering why some of these things are done and how they are important for delivering quality product everyday.