Continuous Delivery Assessment

Report based on workshop and interviews
sample
https://model.mindovermachine.dk
November 24, 2016
Author: Lars Kruse
Co-authors:

Table of Contents

Context

Your Awesome Company and the CoDe assessment

This report summarizes the findings of a series of workshop conducted in relation to the CoDeMeMo performed for Your Awesome Company on 2024-04-07 00:00:00 +0000.

Here follows a short intro to Your Awesome Company

The Continuous Delivery Assessment

The interviews and workshops related to the CoDeMeMo has the purpose of getting a complete overview of the organization with specific focus on software development, the tool stack that surrounds and supports it and the processes used to develop, verify, deploy, test and release software.

The goal of the interviews and workshops is two-fold:

Awareness is achieved by conducting a considerable part of the interviews and workshops and facilitated discussions with the developers in the software team.

The roadmap is manifested in the report you are currently reading.

This report

The report is structured around the Continuous Delivery Metric Model which was presented to all participants during the workshop. The chapters in the report reflect the focus areas in the model.

Throughout the report, findings and observations are given their own section header and paragraphs under each section are marked with an up-arrow indicating that it contains a recommended action mitigating an issue.

Mitigation’s are tagged with a prioritization (M, S, C or W in parentheses). These letters represent the authors opinionated recommendation of priority for the suggested actions.

The lettering refers to the MoSCoW principle for prioritization:

The prioritization that we have come up with is meant to be a catalyst for your internal discussions - you may not agree with our priorities in which case you should obviously go with your own.

Each section is designed as a standalone piece so that the suggested remedies and improvements can be applied independently. This approach should enable you to copy most sections marked with directly into JIRA and prioritize them. All you need to do hereafter is to groom the task, estimate the work, and put it on your backlog.

Summary

Read this if you don't have time to read the entire report

Note: the following is a sample summary from an anonymous client

In general we were quite impressed with your enthusiasm and commitment at Universal Robots. Such level of engagement is a rare sight, and it’s obvious to us that you take pride in your craft.

We found that you have a very high level of technical proficiency and continuously challenge each other, but do so in a very respectful and professional manner. Although it’s quite a challenge running so many workshops in such a short time span, this made running them with you very enjoyable and fruitful.

Some of the things you showcased during the workshops were also rather impressive. The fact that you have implemented quite a battery of automation and improvements as part of everyday work, also shows us that this is something you care for.

In the next chapter, we will go into detail on every observation we’ve made and noted. As not all of you will want to read the entire report cover to cover, this summary is presented as a narrative compilation of recommendations that scored a clean Must Have.

Culture and Organization

Some of your highly engaged teams have already identified many improvements and areas of technical debt. You’ve already got the mindset for the task and had already identified many of the common issues we usually encounter during these workshops. “It’s like an aircraft engine. You need to do the maintenance to keep it in the air” was an apt analogy you brought up. This is a great start, you understand the need to continuously take care of your asset.

However, your current approach was also described as an ad-hoc “boy scout” approach. Meaning you do the right thing by making improvements as you identify them. It creates hidden effort and can actually create more debt than it fixes. The approach to maintaining your asset needs to go to the shop, it needs to be analyzed and planned. Create them as issues in Jira, theme them, commit to doing them as part of your sprints and measure your progress. You have technical leads for the main subsystems. They should be driving this in a planned and organized manner.

There is also a certain level of acceptance towards manual testing from a cultural perspective. This means that tacking quality on is, to a degree, accepted. We think you should start with promoting testing to a first class citizen in the development process. There will always be some form of manual validation, but you want to ingrain testing as an automated process into your culture, as manual testing is inefficient. You can only do this if you implement some form of test management and define a strategy that will enable effective, flexible and scalable tests. This test strategy needs to be embedded into your culture and organization.

Code reviews should not be used for verification and should only be done after all automated verification has run. The best code reviews are those that check code semantics, often involving people with specific domain knowledge. Consider if pair programming is an option, which can be easily planned up front and helps creating cross-functional teams.

The last thing we’d like to highlight is the existence of team subcultures. Some of it may be domain pride, which is quite okay, but it seems to be partially driven misaligned processes across the teams, causing friction. Your branching strategies are a good example of this. How you develop software affects how you interact with each other. Aligning your important processes, like branching, versioning and test approach will give you a lot of value. At the end of the day you are delivering one product to the customer.

Tests

First and foremost, you need to get your tests under control. As it stands, they are really slowing you down and causing unwanted side effects such as long feedback loops, unstable pipelines, etc. The result is that the value of your pipelines are degrading, eventually leading to red builds being ignored.

We suggest you start by stabilizing the automated tests you already have. Valuable tests need to be fixed, while redundant tests need to be removed.

Focus on defining and implementing a test strategy and building up an inventory of tests. Follow best practice as far as the test pyramid goes. Rotating your pyramid 90° clockwise will give you a solid idea of when to run which tests in your pipeline.

Currently, your functional tests, also referred to as E2E, are being executed prior to the aggregated UR upgrade package. This is what you actually want to run such a high level of tests on. As functional tests are inherently more complex, they also affect the feedback loop, so run them after the first level of feedback is given to developers. In addition, consider running the tests in parallel where possible.

Version Control System

You need to move to Git. Subversion is simply too bulky and inflexible for a real CI/CD approach. It doesn’t do branching and merging very well, which you will be doing a lot in an automated release train workflow.

This is one thing we really feel you should focus on. You need to start defining your migration strategy.

You also need a defined branching strategy that supports a CI/CD and release train approach. This branching strategy should be the same across all the teams. This will enable automation and CI/CD by doing automated verification as a toll gate for entering the integration (main) branch. You want logical commits, which are automatically verified on branches and automatically merged into the integration branch.

Architecture

Large monolithic code bases, which take a long time to build and validate do not play well with CI/CD, regardless of the VCS or branching strategy chosen. A lot of the perceived problems are rooted in this: the complex build system, implicit dependencies, slow builds, etc. This is by far your biggest and most daunting task, but it is the one that will give the most value. We’re pretty sure we are preaching to the choir here. You want a more modular, loosely architecture.

PolyScope has some monolithic tendencies. Notable, there’s a single JAR that’s composed of 80% of the PolyScope code. You should investigate a more modular approach.

There is a tight coupling between PolyScope and the Controller. This can be loosened by splitting the dependency out into its own versioned and controlled artifact. An added benefit is that you’ll be able to manage the public API explicitly.

Breaking down your architecture into modules and creating individual pipelines for them implies you’ll need a structured and cohesive approach to dependency management and releases. Though we sadly didn’t have the time to dig deeply into this area, we know you are aggregating your dependencies in the firmware subsystem and the UR upgrade package. This means that you are already doing dependency management, you just need to make sure it is a cohesive approach where you can automate the creation of a versioned release from a branch and identify the dependency from the version. This is what the version, release and branching strategies will give you. The ability to automate the process.

Builds

One of your biggest pains right now is your unstable integration branch (trunk). The main drivers behind this are the lack of a cohesive branching strategy, unreliable tests and the absence of an automated toll gate. Start by setting up a toll gate to your integration branch. Define what makes code good enough to share with colleagues, e.g. can compile and run unit tests, and set this up as a barrier into the mainline.
Once development is done solely on topic branches and the automated toll gate is the only way into the mainline, you will have a stable trunk.

The build script looks to be a point of friction as it’s an attempt to combine some of the subsystem builds due to dependencies. The shell script is a pre-step, followed by Maven and SCons to build the subsystems. This is in reality just a reaction to the coupling between PolyScope and the Controller. The result is a slow feedback loop. This pre-step should be handled as a dependency instead of a build requirement, so you won’t have to build needlessly.

At least once, during the workshop, it was stated that not all of the build setup was found in scripts, but it was located somewhere in Jenkins. We have extrapolated this to mean the pipeline definitions. Your pipeline definitions are separate from the code. As a result, it is difficult for developers to get an overview of what they need to control. You need to build a better separation of concerns here. The DevOps team should provide the pipeline framework while the domain specific configuration should live in the repositories. The developers should be able to control what to build, which suite of tests to execute, etc. while the framework should just ensure that the definition of done is executed.

You need to push your pipeline into Front Office. The tests that are being done, or triggered manually, on the UR upgrade package should be part of a pipeline and the final image given to the customer needs to be generated as well. In reality your final automated tests should be done on the generated image. In general there are too many manual steps in the Front End release process. You should focus on automating these to the extent possible.

DevOps

It is quite evident that this has been an area of focus, a lot of work has been put into it and quite a lot of benefits have already been reaped. However, you have a low bus factor here. Therefore we would recommend that some effort be put into opening up the information bottleneck. DevOps, obviously, wants and needs a certain amount of control. But there is a fine balance between control and flexibility.

There are a couple of findings that have to do with resource management, both hardware and human resources. We recommend you take a closer look at how you manage both of these. Ask yourself what the best strategy for scalability from a hardware perspective is. Is it really fewer, more powerful, machines, or does the problem lay somewhere else? The one Windows build machine is an obvious bottleneck but you should make sure you identify the core problem.

Should the DevOps team really be maintaining the Jira and Confluence instances? We recommend that you shift such tasks away from the DevOps team and have them focus on feedback times, pipeline structure, automation, access to more production like environments, etc. The DevOps team should still own the ‘how’, i.e. the process flows, but shouldn’t have to deal with the installations.

Get the last pieces in place as far as your present infrastructure is concerned. You’re utilizing Docker images, which is great. Many organizations are far from containerization. But the base images are being built constantly. This means that they could move under your feet. Consider bringing Docker Registry into the picture.

Your environments should be managed as code. Start to make this a reality with a CMS like Ansible, Chef, Puppet, or whichever you choose. Use these clean environments as much as possible. Why could they not be the basis for developers environments?

A high level road map

For a high level road map of our recommendations, we’d suggest the following:

  1. Move to Git and start using a branching strategy that supports a release train workflow.
  2. Define and implement your toll gate into the integration branch.
  3. Stabilize your integration branch and react when it goes unstable.
  4. Define and implement your test strategy.
  5. Start chewing away at that elephant! Break the monolith down with an iterative approach. It’s too big to eat in one sitting.
  6. Automate Front Office’s manual processes and put them into a pipeline.

Scores

The cards scores based on the workshop exercise

During the individual workshops for each area, we do an exercise where the participants evaluate and score the five cards that belong to the area. Through six workshops over two days we ended up scoring all 30 cards in the model.

The participants were split into smaller groups of 3-4 people, and each group was given one card to score. The exercises was to discuss the best-practice described on each card and score them in terms of the four gauges throughput, feedback, payback and simplicity.

After scoring the cards each group presented their scoring briefly, and the rest of the group had the option to affect or discuss it, if they found a need for it.

Throughput, feedback and payback are added together and multiplied by simplicity to calculate the total score on each card.

All the cards that got a score are listed in the following:

Note: the following is a sample analysis from an anonymous client

Analysis

The majority of the cards received some type of score in the value gauges. With the exception of the following

It could be beneficial to revisit the cards, which you scored a zero in one of the value gauges, after reading this report. It might have given you inspiration to find the benefits from a holistic view.

Low hanging fruits

The scoring algorithm favors the simplicity gauge, putting easy-to-implement solutions higher up on the list.

This is a deliberate choice, as it helps identify the aptly named “low-hanging fruits” - ideas that should provide easy wins with high value. These are perfect issues to get started with as the quick gains often help you down the road and help motivate the organization to tackle its bigger, harder-to-solve pains.

Looking at your self-assessment, a few cards stood out:

Buy-in from management scored a 24 in the Organization and Culture category. You have evaluated this quite high in throughput and feedback. You gave it two stars for payback and feel it is simple to implement. We agree with this self assessment. We feel this is directly related to how you are going about paying off technical debt and implementing tasks to improve the way you work. Not so much as to whether you are allowed to. More about the approach of making it visible, organizing it better and planning it. This score is only a few points from being the ultimate low hanging fruit.

Pristine integration branch scored a 21 in the Version Control category. You have evaluated this as something that is easy to implement but gives fairly high value in feedback and throughput while affecting the architecture quite heavily. This is a good view, and to some extent, will not be the most difficult task of the results from this assessment. It might be a little more difficult than you anticipate. You need to align the definition of done across the teams and get the tooling, a DVCS for example, in place before this can be achieved effectively. Keep in mind that you want to make sure you do not impede the pace of the team with the automated toll gate. This could be slightly more complex than at first glance due to build and architectural dependencies.

Release train branching strategy scored an 18 in the Version Control category. This was assessed as being easy to implement, while giving a high value of throughput and fairly high value on feedback. It is interesting is that you gave it only one star for Payback. If you keep in mind the requirements a release train will impose on test-ability, trace-ability and maintain-ability, you may find that the value return is bigger here than you initially believe.

Falling back to the cards that score high with two stars in simplicity we get:

The code metrics are a sure win and, in reality, should be part of your toll gate to get in to the integration branch. It can, generally, be kept fast and give definitive feedback.

The dependency management, on the other hand, will be pretty heavily related to what you already have implemented in this area. We know you have some dependency management from Maven. But what about the other technologies in play? How about an aligned version strategy that will support dependency management of releases in a good way? There are some rather hard relations to the architecture across the technologies here. This might, in reality, be a two in simplicity instead of a one?

Biggest blockers

Another thing we look for are your major pain points.

Judging the self-assessment scores, we now look further down the list for cards that were judged as very hard to implement but giving huge benefits when done.

These are cards that score high in throughput, feedback and payback but only a one in simplicity - indicating that they are difficult to implement.

There are three cards that stand out here.

The Explicit knowledge transfer scored a 9 in Organization and Culture category. A full three stars in Throughput, Feedback and Payback. But is perceived to be very difficult. This assessment is probably due to the hero factor which is exhibited at UR. There is also a bit of a low bus factor in the DevOps team, but our clear impression is the difficulty lays with the system complexity and architecture. Meaning it is hard to get an overview of the dependencies and how changes may affect the system.

But the same may also be said about the Delivery Pipeline self assessment. This card scored a 9 in Build category. Again a full three stars across the value gauges but is perceived to very difficult to implement. It is, most likely, also rooted in the system complexity, architecture and dependencies.

Your self assessment on Testable code scored an 8 in Architecture and Design category. Only a two in the Throughput but a full three in the other two value gauges, while still being perceived as difficult to implement. This is a bit harder to analyze without really looking into the automated tests and the code itself.

Looking at the three blockers that stand out. We could imagine, that we see a red thread leading back to the system complexity, architecture and dependencies. What do you think?

Outliers

There was one self assessment that we wanted to highlight which did not fit into either low hanging fruits or blockers.

Use distributed VCS scored a 6 in the Version Control category. You scored it a three for Throughput, a two for Feedback and a one for Payback. You perceived it as being difficult to implement. The result is that it does not end as either a low hanging fruit nor a blocker. However, we feel, you will find it difficult to implement an effective branching strategy that will help you in achieving a pristine integration branch in a CI/CD environment without moving to a DVCS. We think the Payback may be higher than a one.

Our picks for you

If we look at where our focus has been, and where you have self identified the most findings with high priority it falls in the following 7 cards, minus the Explicit knowledge transfer.

Your own picks regarding a release train branching strategy, and a pristine integration branch really fit well with where we could see you putting your focus to start. With the addition of:

Dependencies are managed and a Delivery pipeline also fit well with what we would recommend starting with. Mainly because we think it will give a good starting point for eating the elephant as we like to call it. We would also like to point out that the move to a distributed VCS could also help in this regard. It could give you the opportunity to discover implicit dependencies. See our solution Split them with an automated approach under the finding regarding Current VCS.

We left out the Explicit knowledge transfer because we feel it is a very difficult blocker to deal with presently. But also because we think that it will be less difficult as you make the, planned, incremental improvements. As you eat the elephant, institute a release train branching strategy, etc, there will be less of a need for hero’s.

Findings

The findings and observations, including their mitigation, recommendations and prioritization

The findings and recommendations have mainly been picked up throughout the interviews and workshops. We conducted this part as targeted group interviews focusing on the 4 main areas of the regenerative software model.

On the first day, after the initial Continuous Delivery presentation, we had an exercise where all attendees together were asked to illustrate the process from the point where a requirement or a change request arrives until the implemented result can be accessed by the end-users.

The participants were also equipped with stickers with 6 different pictograms representing: Wait state, unplanned work, manual work, conflicts, queued work and anything that needs repair.

The result was discussed during the workshop and then used as a reference point during the various discussions on the following day.

Ecological Alignment

Observation

The card is strongest when it is tied to an explicit trigger, such as carbon intensity, time window, or batch size threshold. That makes the operational goal visible to the team instead of leaving it as a vague aspiration.

Elaboration

If the workload is allowed to run at any time, the environmental benefit becomes incidental. Treat the scheduling rule as part of the definition of done so the energy decision is made where the work is planned.

Recommendation

For this client, start with one non-interactive job and document the grid or battery condition that justifies delaying it.

Open-Source Stewardship

Socio-Technical Well-being

Observation

This practice is most credible when the team can point to a recent incident where a mistake was surfaced early and handled without blame.

Annotation

The surrounding process should make it easy to report ambiguity, not just defects. That keeps the card focused on the social system that allows technical issues to be spoken about.

Elaboration

Psychological safety is not softness. It is a control mechanism for surfacing weak signals before they become outages, handoff failures, or silent workarounds.

Generative Evolution