Back
blog

Continuous Documentation Through Continuous Integration with Swimm

Continuous Documentation

Does the thought of updating your documentation bring back memories of spending entire cool down cycles bringing things up-to-date, just to see it become obsolete again in a few months? You’re definitely not alone, this perennial march is one of the biggest reasons that teams just give up on ever having current documentation. It's incredibly hard to see your work lose value so quickly.

When we talk about continuous integration with Swimm, we’re referring to really any automated process that results in breaking changes not being merged into the main branch. This could be a Github Action, Bitbucket Pipeline, or just a team that agrees to add our verification checks to their pre-commit hooks. For all intents and purposes, we just need something that wakes up when new changes are merged in. We support practically any setup:

Continuous Integration Swimm

We knew that for Swimm to show immediate value to teams, it would need to effectively prevent this with less effort than another documentation sprint. We solved it in a pretty interesting way, by making documentation itself continuous through the continuous integration loop. We considered use cases in modern development paradigms such as microservice architecture as well as those that need a lot of effort to bring things back into date, and this approach really does align with Swimm’s core language-agnostic goals.

We also learned that CI servers operate in vastly different ways depending on the needs of the organization and the team. Even basic questions like “how long does it take for your CI server to run?” were answered completely differently by each of our early adopters and design partners. Some let us know that a full build including all dependencies and tests takes around five hours to complete, so we also had to make sure performance was a key feature for the myriad of checks that we need to do. We also learned that because of how busy these things can be, adding additional checks can be met with resistance from the team.

So, how does Swimm run on your continuous integration server, and when should it run within your existing automation? The best way to answer this is to run you through the steps in the process, so you can make the best decision based on your setup.

First, Swimm needs a complete clone of the repository.

To save time and bandwidth, many continuous integration servers offer the ability to perform a ‘shallow’ pull of your code because the entire history isn’t required for the checks to run successfully. Swimm’s algorithms need to be able to analyze changes in the history to determine if any code snippets are out of date, and if so, if those changes can be automatically synchronized or if the documentation check should fail.

Next, Git is going to need a bare minimum configuration.

Swimm doesn’t commit during the CI verification checks, but there are some Git commands that require `user.name` and `user.email` to be set. It doesn’t matter what these fields contain, they just can’t be unset. Most CI servers allow you to pass this as part of the job configuration, but our example scripts show you how to set it at run time without any additional fuss.

Then, your CI server will fetch our latest command line interpreter.

Your CI container will need to have a POSIX shell available, be it Bash, Dash, ZSH or something else. Busybox can be used if curl is available, or curl can be downloaded via `wget`. You’ll also need to be using a 64 bit Linux image. Our demo configurations call for `ubuntu:latest`, but you can use any distribution such as Debian, CentOS, Arch, and others.

After environment checks, the continuous integration checks run.

Swimm checks your code snippets, smart tokens and smart paths against the latest version of the code and in cases where things don’t seem to line up, Swimm looks to see what can be automatically synced. In many cases, code simply shifts a few lines from where it was, or a variable is renamed, or something else functionally inconsequential enough that Swimm can understand.

When things require attention, the CI tool will exit with a non-zero status while providing meaningful output.

You then decide what happens next.

When the continuous integration check fails, you have a couple of options available. Ignoring failure isn’t one of the options, because that completely defeats the purpose of running to begin with. The option that we recommend most is that you block the pull request or commit until any snippets that need accepting or re-selecting have been addressed. If this is your default reaction, your documentation will always be current, which will encourage others to trust and expand it even further.

Your other option is to kick off an issue or ticket in whatever task or bug system that you use. You can do this with curl directly, or set up a web hook for automation at Zapier:

Web hook for automation at Zapier

The best way is whatever way is best for your team. What’s important is that everyone follows it, so try not to let striving for a perfect setup prevent you from actually reaching a good one.

Is the continuous integration server too contentious? Try commit hooks.

We know that it’s not always easy for things to be added to the CI process. Fortunately,  there are workarounds that you can do on your own.

Git hooks offer you the flexibility of running any checks that can run locally prior to the commit transaction finalizing, which can be utilized to run things like static analysis and lints. Swimm runs well in this setting, as long as you make sure you pull any remote changes prior to committing.

You have the same flexibility in handling the checks failing as you would in the continuous integration environment, although you wouldn’t have the handy guided interfaces that many CI servers provide. Just make sure everyone that can introduce or change code also runs the checks, or it’ll disproportionately fall on those that have them to keep things updated.

When does Swimm actually realize that the code has changed?

There’s two very strong arguments for when that should happen. Some would rather that Swimm be able to detect changes as soon as they’re written to disk by the editor. That is to say, verification checks should look at the file in situ even if it differs from the last committed version.

Then, there are others that would find that behavior frustrating, and would much rather Swimm only look at changes once they are staged for committing.

We’ve heard a lot of feedback, and decided to go with changes needing to be staged before Swimm sees them for now. This is important to keep in mind when using pre-commit hooks, or trying to deliberately trigger failure during testing.

So in conclusion, we knew we’d need to run efficiently on everything from GitHub Actions, Bitbucket Pipelines, Azure Pipelines, Gitlab, Travis, Jenkins, CircleCI, Husky and even pre-commit. A big part of our philosophy is remaining language and platform agnostic, because a need for great documentation is something we all share.

But, once you integrate Swimm and our continuous integration checks and stick to them, you won’t have to worry about knowledge rot again.