dagblog.
← Archive

How I introduced continuous integration at our company


It all started with an innocent chat with Vlastík about building and versioning

applications. During development we need a flexible way
to create versions of the product to send for testing.

  • Who will run the build?
  • Where will it run?
  • Which source files and versions will it use?
  • How, when and where will the build be delivered for testing?
  • How will we version the build?

Thinking about it, I should first clarify what a build is. A build

is the process of assembling the application into a form suitable for distribution.

Ours consisted of a server part, a WAR (Web Archive

Resources), and a client part made up of thin-client binaries.

The build itself involves several steps, such as creating the appropriate

directory structure and compiling the source. An Ant script handled the Java server

part. The problem was that anyone who wanted to create their own

WAR had to check out all the source from CVS and run the build

locally. Compiling the thin clients was out of the question.

Automated testing was another complication. We’d been fairly successful at

introducing JUnit tests, but keeping them current was a problem. We had

tests, as the saying goes, but we didn’t check all of them or run them repeatedly.

People often forgot to run them when they changed the internals.

These problems are common. They’re a natural part of integrating the work

of dozens of people. Developers constantly add features,

fix reported bugs and change existing features. Where the work of several

people overlaps on one feature, their responsibilities overlap

too. Tomáš works on A. Roman builds B and C on A,

and Michal and Luděk build on C. Luděk needs a change to C, Roman makes it,

and it may affect Michal, who shares C.

These are just situations that can arise when you integrate

a group’s work on one product. Integration is nothing new, so it’s

no wonder people look for ways to make it easier. One approach to software

development, eXtreme Programming (XP), introduced or defined

a practice for solving integration problems. XP called it

continuous integration.

Continuous integration

How do we describe continuous integration?

A basic definition of continuous integration, or CI, is

an automated process for integrating individual software components.

The prerequisite is simple. We need something

to integrate, and it needs to be stored in one shared place. The integration

then runs at intervals we define.

How do we integrate things?

There are many ways to decide what successful integration means for a product

or its parts. At the source level, it means the files

compile at all. Sometimes someone changes an API without getting all the
changes into the shared repository, or forgets a library. Passing

unit and smoke tests should indicate a successful integration. Load tests and

tools for checking code structure, such as PMD, can provide further criteria.

What does integration produce?

It produces a whole, also called a build. In our case that’s a software

product we can hand over to our human testers. Of course integration

can succeed or fail. If it fails, something has gone wrong.

CI lets us find that error when it first appears, before testers

are breathing down our necks demanding a version we can’t deliver, perhaps

because of incompatibilities. With CI, we can catch many errors

early.

How often should we integrate?

It depends on developer activity. If you’re closing in on a release and developers are pouring changes into the repository every few minutes, run it hourly. If development is slower, you can run a nightly build.

That’s all for today. Next time I’ll cover Luntbuild, the tool I used to implement CI, and integrating it with GForge. That means spamming developers with build results, versioning builds and a host of details I can’t think of right now.

Medium version

Related articles

Related CZ Podcast episodes