I can tell you a little bit about my experience in my workplace. A priori summary: we are working to try to start a reliable IC to then have a CD to deliver value to the customer as soon as possible.
History of development cycle
In 2013, where I currently work, I used a single Generation 2 VCS (SVN itself; for nomenclature, see Eric Sink) to store Java fonts; we had 2 products that, in theory, should perform the same set of functions: one project for mobile device (Totalcross) and another for management portal (GWT). Ultimately (including the habits of this generation and the company’s culture), this meant that code changes to innovations (Features additions, experiments, etc.) and maintenance (bug fixes and performance improvements) were done in the same branch. At the end of the day, that meant that:
- the developer worked on a code scheme
V1
;
- when there was a conflict, the one who ultimately won was the one who left to deliver the job last, overwriting the code of whoever stirred concurrently;
- in the end, what was actually committed was the code
v2
(after resolving the conflicts);
- the code was built
v3
for testing;
- the test finds a flaw in
v3
, but the developer who picks this flaw is already on v5
(!!!!);
- the correction is made and delivered
v6
;
- make the test build
v7
for testing;
- test approves
v7
, then the build is made v8
for production;
v8
presents obvious problems in production that v7
did not present;
- saw each other nights with the code
v12
to produce a v13
final;
v13
corrects all problems of v8
, but then a customer detects a regression in relation to what he was using;
- get
v17
and tries to correct quickly by producing a v18
;
- the tester picks up the test build
v21
and points out other regression problems;
- you take the code in
v30
and correct these problems, generating the trial version v31
;
- the tester approves the build of
v32
;
- customers approve the build of
v37
;
- goes to production the build of
v42
(!!!).
Yes, that was the size of the trauma to release versions... In the end, a release cycle of new features was 6 to 8 months, so a mysterious box arrived that the customer tried to use.
This began to change in September 2014, when the following changes took place:
- development of projects;
- switching to a Generation 3 VCS (git);
- adoption of a variation of Gitflow;
- all code only enters the
master
or develop
after revision (route merge request);
- visual management through a web portal (Gitlab CE).
This avoided having maintenance chaos in production, now allowing developers to get sleepless nights. What the tester approves now is the same build that the client approves and uses in production. Also, due to the homologation environment, errors were captured in a much safer sandbox. This paradigm break (of unique code for stable code / master
and unstable code / develop
) improved our code quality and stability of new versions, but did not help in the release speed.
Even with the constant revisions of codes, it happened that the build broke after the acceptance of one or other merge request; the motives were really random, but anyway... Then, the first step towards the IC was given: all creation of a merge request results in automatic build execution for merge output. This detected many problems concerning it, saving the time of the proofreader and the blessed one who would correct it.
At the end of 2014, it was detected that most of the problems found in the portal code were identical to those of the mobile code; then, in May 2015, the unification of the code bases was made, creating the heart of the system that needed two substrates: UI and bank access. In this case, the least effort we had to achieve this unification was to inject the bank dependencies into the heart, while the UI called the heart to make the right referrals. After a period of stabilization due to this change of architecture (sometime between July and October 2015), we were able to release versions every 3 months. Much of the technical delay of the portal (not implemented Features and fixed bugs in mobile) was fixed with this, being therefore the focus of attention now new features and performance.
Even so, we were below our goal of speed: a final version closed and tested per week (not yet CD, but almost there). Reason for our slowness? Regression. What did we need to prevent regression? Test. However, hiring test personnel to do silly and repetitive things for every released version is a huge waste of money. The workable solution? Automated testing.
Automated testing began in August 2015, but the creation of these tests only gained traction in July 2016. In October 2016, we put that one merge request would only be accepted if it had automatic testing. This served for several reasons:
- if the merge request were a
hotfix
, was proof that the production code was wrong;
- ensures that a new Feature behaves well for some expected/common scenarios;
- avoids the mere existence of regression.
From the moment it gained traction (in July 2016) until the end of March this year (2017), the automated tests did not bring the speed increase in release, but gave more credibility to the builds. From April 10, then, we are at the pace of 1 version for every two weeks, with increasing stability with each version.
Completion
Well, we are making increasingly smooth the development of our software (mobile, portal and heart). When the development reaches a very large softness, then we get continuous integration. The objectives of continuous integration, in our context, are two:
- value the software (from the customer’s point of view) more quickly;
- ensure that what works before continues to work.
With continuous integration, we can move on to a next stage: continuously delivering value to the customer.
We are not in a race to put CD simply because CD is beautiful, because it is fashionable. Imagine having a continuous delivery with the delivery flow described right at the beginning? Continuous delivery should target the customer and should be done responsibly. We don’t want to lose customer because each bi-weekly release breaks everything that there was before; I recognize that sometimes we annoy customers when we change the look or let the navigation more fluid/intuitive, because he was already used to the old scheme, but we didn’t lose them at least =)
The greatest risk that CD can cause is to fail in the second objective described above: ensure that what works before continues to work. A CD made irresponsibly does not guarantee this stability.
The risk imposed by IC is infinitely lower than that imposed by CD, but it is very large when compared to a slower integration. Basically, an irresponsible IC can disrupt the first objective described above: value the software (from the customer’s point of view) more quickly, for the branch with the unstable code develop
will be more unstable than desirable, causing a lead time greater between the beginning of the development of a new functionality until the actual delivery of this functionality.
At a glance at this article it may be useful: https://lhlima.wordpress.com/2015/08/04/differca-entre-ci-integracao-continua-e-cd-distribuicao-continua/
– usuario