The A-Z of Code Craft – C is for Continuous

Image

Old-fashioned approaches to creating software often encourage us to think of the activities involved as stages or phases in the process: the design phase, the coding phase, the testing phase, the integration phase, the release phase, and so on.

This approach has some major drawbacks. In fact, many of us have found that it simply doesn’t work on problems of any appreciable complexity.

The moment we start writing code, we see how the design needs to change. The moment we start testing, we see how the code needs to change. The moment we integrate our changes, we see how ours or other people’s code needs to change. The moment we release working software into the world, we learn how the software needs to change.

Around and around we go, feeding back our lessons into a never-ending continuous cycle of designing, coding (which I might argue is also designing), testing, integrating and releasing. The lines between these activities become very blurred. If I’m writing a failing test in a test-driven approach, am I designing, or am I coding, or am I testing? When I’m refactoring code, am I designing, or coding, or testing?

The correct answer is: YES.

And if we work backwards from the goal of having working software that can be shipped at any time, we inevitably arrive at the need for continuous integration, and that doesn’t work without continuous testing, and that doesn’t work if we try to design and write all the code before we do any testing. Instead, we work in micro feedback loops, progressing one small step at a time, gathering feedback throughout so we can iterate towards a good result.

But the continuous loops don’t end there. To ensure the software’s open to change, we also need to be continuously reviewing or inspecting the code. And to get the bigger picture right as the software grows – considering how the pieces of the jigsaw fit together – we need to be continuously architecting our products and systems on that larger scale.

And, finally, to be capable of doing these things well – abilities none of us are born with – we need to be continuously learning. In each nugget of feedback, we can see things that went well, and things we could do better. Rather than saving it all up for a “post-mortem” after a major release, and trying to change 1,001 things in our approach – which never works out! – we need to act on that feedback throughout the process, evolving our approach one lesson at a time.

Some, myself included, might say that if code craft could be crystallised in one word, that word would be “continuous”.


If you’re serious about building your team’s capability to rapidly, reliably and sustainably evolve software to meet rapidly changing business needs, my Code Craft and Test-Driven Development live remote training workshops are HALF PRICE until March 31st 2025.

The A-Z of Code Craft – B is for Builds

Image

Automated software builds, where the product’s prepared for a potential release from the source files, are a central part of code craft. 

Every time developers merge their code to the main (“trunk”) branch, an automated build’s triggered that checks out the latest version of the code, resolves its dependencies, compiles the code if necessary, and runs the automated tests to make sure it all works in the build environment (and not just on the developer’s machine).

If all is good, and all the tests – and other possible quality checks, like code linting – pass, then we can have confidence that the current version of the code sitting on the trunk could be shipped if we wanted, though that might require further steps like containerisation.

It’s important that our build “pipeline” – the sequence of steps performed in an automated build – contains sufficiently robust quality gates to give us that confidence, or issues may leak into production. 

As well as constructing a shippable version of the software from the source code, we can also think of automated builds as being like passport control at an airport departure gate, preventing software getting on the release plane if it’s likely to present a problem.

If any tests or checks fail during an automated build, we say that the build is “broken”, and the software’s blocked from being released. This makes it everybody’s problem, so it’s important that broken builds are fixed quickly, or the code on the trunk is rolled back to the previous working build so the team can carry on delivering value.

The best developers are very “build-aware”. They keep one eye on the status of the build, because it signals changes to the code base being made by other people on the team. If a build succeeds, they’ll get those latest changes and merge them into their local copy to keep in sync. If a build fails, they know it’s not safe to merge their changes into the trunk, or to get changes from the trunk, until the build’s fixed.

The execution time of builds has a profound effect on delivery lead times, due a phenomenon known as “short delay, long queue”. This is why performing builds manually isn’t a realistic option in continuous delivery. It’s very often the case that speeding up builds will increase agility at the team level.

_____________________________

If you’re serious about building your team’s capability to rapidly, reliably and sustainably evolve software to meet rapidly changing business needs, my Code Craft and Test-Driven Development live remote training workshops are HALF PRICE if delivered by March 31st 2025.