In the second part of this series I talked about how we actually deliver our products every single day - the process and the tooling. In this final post I want to discuss why some of these practices are important to achieving the level of efficiency you need to deliver quality product, fast.
When we start a new project, there are a bunch of things that we setup to ensure the smoothest and fastest operation of that project and the best quality outcome of that project. Some of the following may be obvious than others, but these are what make our work style extremely efficient.
Git Repo — First and foremost a git repo (mostly GitHub) is created where the source and docs of the project are maintained. Along with that repo there will be two additional repos created for storing configuration details of each stage and production environments. I am not going to explain to you why you need to use something like git, but if you don’t you seriously need to look into that. Tools: GitHub, Gogs.
Dependency Management — This is a must for every type of project no matter what tech it is. This lets us make sure all dependencies are available and up-to-date at all times, with a single command. Tools: npm, composer, maven, ivy, homebrew, scoop.
Workflow Management — A workflow management tool is also a must in every project. This lets us manage the standard operations such as clean, build, test and so on, but also let us script out any other repeatable tasks/operations. And that is a crucial part of brining efficiency into work of this project. Tools: npm, gulp, ant, maven, angular-cli, phing.
Build Process — The build process is scripted out to work on all the different environments (local, testing, staging, production). Each environment’s build process would have different build settings and configurations as needed by the environment. Tools: Workflow Management.
Debug Process—Most projects will also have scripts to be able to run the code for testing which would enable the developer to test out changes and debug if necessary with change watching, magically applying changes as they are made. This is also made possible with a single command. Tools: angular-cli, live-server, beefy.
Code Styling (Lint) — This is another important tooling/config that saves the day. Code styling tools let you validate your code to adhere to a given set of styling rules. They can check many simple yet important things from missing semicolons, code indentation, variable naming, missing documentation to almost any sort of guideline you would want to enforce on how code should be written. Pull Requests cannot be merged without all code styling check’s passing. Tools: tslint, eslint, phplint.
Unit Tests and Coverage — Every line of code that is written must be unit tested to ensure it fulfills its purpose well. Unit tests are a powerful mechanism to ensure good code is written and continues to stay that way. Our projects also have coverage checks to ensure 100% of the code has unit tests. Pull Requests that don’t have this are automatically blocked from merging. Tools: karma, jasmine, mocha, junit, phpunit, mockito, JaCoCo, Cobertura.
End to End Tests—These are tests that validate the functional and integration testing aspects of the project outcome. These essentially ensure if the product functions as expected in each environment. These will be run every time a project is being deployed to stage or production and will fail the deployment if any of the tests fail. Tools: protractor, mocha, selenium.
Setup Docs—This is a set of instructions that will be available on the main page of the git repo that gives a step-by-step instruction on how to setup the project and get it running in minutes. This will also provide all the commands available in the project workflow (run tests, validations, build, deployments etc.). This simply removes any setup time for a new developer/tester on the project. Tools: markdown files.
Boilerplates — We also create boilerplate projects that help us start a project really fast. These boilerplates are created specific to tech-stack and are packed with all the above configured so anyone can simply create a copy of it and get started with a new project which has all these tools and commands working.
Test Environment — Our test environments are able to start any of the projects into a container and run them with just a couple of commands. For every new project created, a container file is added to be able to run the project in the test environment. Test environment can be used to run bunch of our apps together and see how they work. Tools: Docker, now.sh, AWS.
Continuous Delivery —For each project scripts are added to the CD server for running the workflow commands needed for validating and deploying the project to staging and production environments. Once these scripts are loaded, the CD server starts deploying as the branches have changes. As code gets pushed, we receive Slack notifications on the status. This whole process simply ensures that proper quality code gets deployed to our servers every-day. Tools: Jenkins, code-deploy.
While we have done all of this on more than a few projects, it is important to note that some of these projects are on completely different tech stacks than others (js, ts, java, php etc.). To make all these possible we had to put together a whole bunch of tools, most of which are freely available. Important things to note here are,
- Almost anything can be automated.
- There is always an already built tool you can use to do what you want.
In these three posts, while I was able to cover the bird’s-eye view of how we deliver product fast through a scalable approach, I could not touch on any of the technical details of how we managed to actually get them working. We hope to talk about more of this on Beyond the Semicolon soon.
Here a is a neat infographic showing how we work at Creately!