Friday, September 11, 2015

Some tips on continuous integration, delivery and deployment

Here are some tips about continuous integration, continuous delivery and continuous deployment, after some experience in the area.

Nowadays, there is an increasing need to deploy as soon as possible the developed features, in order to reduce time to market and provide earlier more added value. 

To achieve this objective, we must follow some techniques to simplify and automate the full process, from development to production running code. 

A product is composed by a set of features. When developers finish the development of a new feature, they must reintegrate it to a main line of the product code. When these reintegrations happen frequently and without any previous planification (typical in agile environments), we are talking about continuous integration

Once a new feature is reintegrated in the product main line code, a quality control process starts and, if the product is stable and more added value is provided, we can say that we have a new release candidate. When the quality control process is fully automated, we have a continuous delivery context. 

Not all release candidates must be deployed to a production environment. For example, we may not want to deploy a release candidate because of performance problems, or maybe, we should wait for a significant number of completed features to publish a new release to the end users. We could also freeze deployments to production because we don't want to affect the availability of our software product (for example, e-commerce platforms at promotion days). When we are able to define some rules to automatically deploy release candidates (which pass a quality control threshold) to the production environment, we have a continuous deployment scenario. 

Here are some tips to achieve a continuous integration, delivery and deployment environment: 

  • The basis:
    • Try to choose modern and stable technologies, and define a good software architecture with them. Don't try to be always up-to-date (it's almost impossible in IT) and avoid using very old technologies (your software lifetime would decrease and you will have a lot of compatibility problems). Applications should have a minimum lifetime of 5-7 years aproximately, with minor changes. After this time, the software should be absolutely rebuilt with new technologies or migrated to the trending ones. 
    • Use a development environment with tools specially oriented to the chosen technologies, and clearly separate the code edition from the quality control (this way, you can reuse the quality control tools at integration servers). 
    • Use proactive actions in the editor in order to suit the quality control rules. 
  • Features development:
    • Use a source control management tool, in order to trace changes in code
    • Use a task management tool to control the features and bugfixes workflow (assignment, status, etc). 
    • Write unit tests to validate automatically your features development. Don't worry if you are not really interacting with other systems (use mocks, instead), the integration tests will check the correct communication with other systems. 
    • Don't develop in long-term, isolated branches (reintegrate your changes frequently to the code main line), and try to use a strategy of activating features by configuration (branch by abstraction). 
  • Features integration
    • When a feature development has finished, a reintegration request should be performed. If unit tests fail (before or after the reintegration), the reintegration should be automatically unauthorized and code changes rolled back.  
    • Once the features are integrated to the code main line, automatic integration tests should run to check the correctness of the developed features interaction with other services.
    • If unit and integration tests run without errors, we should also execute performance tests in an isolated environment, but with very similar conditions of the production environment. 
  • Product releasing pipeline
    • Release candidates should automatically promote through a well defined environments pipeline (for example: integration, pre-production, production). Despite this, automatic steps could be mixed with manual checkpoints (no more than one or two, and at the end of the pipeline, if you want to maintain agility in the process). A good example of manual checkpoint would be smoke tests, which validate the critical operations of the product.  
    • Use code static analysis tools, to detect bugs, check the testing coverage, violated code conventions, etc. Define thresholds for manually or automatically accept or decline the quality of a release candidate. 
    • Use a common management database (CMDB) to control your deployed services versions and status, over your systems infrastructure. 
    • If you have a well defined, fixed dimensioned infrastructure, use a push deployment system. Otherwise, use a pull deployment system or the deployment strategy will become unnecessary complex. 
Finally, applications deployed at production environments should be continuously monitored, in order to detect bugs and obtain continuous feedback about the quality of the described agile development process. 

Here is a great book with more info about continuous integration, continuous delivery and continuous deployment.