Documentation versioning best practices with docs-as-code
calendar_today
October 20, 2023
persondomaindoctave
Many software products end up having multiple releases over their lifetimes.
When this happens, the documentation needs to be versioned along with the
product.
In this post we will look at documentation best practices when using a
Git-based docs-as-code workflow.
Software versioning basics
Before going into how we should version documentation, let’s take a look at how
software projects generally handle versioning.
Disclaimer: there is more than one way to version software. The method
outlined in this post works for many projects, but there are other valid
workflows too.
Versioned releases
Products like Windows, PostgreSQL, or React JS all have versioned releases.
Every once in a while, depending on their release cadence, a new version with
new features is released.
A long list of versions for PingCap's TiDB documentation
Different projects will use different versioning schemes, but Semantic
Versioning is a popular way of giving
structure to your version numbers. Another option is using a date-based scheme.
Usually, different versions are managed in separate Git branches.
A typical branching strategy is to have all work for the upcoming release
happening on a main or development branch. Then, when a new release is
ready, a new branch is created from the main branch and named after the
release (for example v4.0).
1
2
3
4
5
6
7
main # Development happens in this branch*
| v4.0 # New branch for the release**
| /
* ——
|
There’s a few reasons for this. Firstly, it’s clear what code belongs in the
release, and what does not. But importantly, you can apply hotfixes to the
release branch:
1
2
3
4
5
6
7
8
9
main
*
| v4.0
**# <- New hotfix commit
| |
**
| /
* ——
|
This allows you to update and fix the 4.0 version, while you keep moving
forward in your main branch towards the next release. Perhaps you’ll even
release a patch release with bug fixes: a 4.0.1.
This strategy also makes it clear which features and commits belong to which
version. You don’t have code for multiple versions mixed together. There is
clear separation between versions.
When is versioning not needed?
There are some software products that do not have multiple versions. Take a
service like Slack. There is only one version of it: the currently live version.
In such cases, you typically have one set of documentation that lives with the
product. New features are built, documented, released, and ultimately deprecated
in unison.
What these kinds of products however may require is API versioning (see
below).
Git versioning strategies for documentation
Ok now that we have an idea of how software versioning works, how do we apply
this to documentation?
One of the reasons you want to use docs-as-code is to mirror the release process
of the rest of your product. When you release a new version of your code, you
also release the corresponding documentation.
How is this managed in Git?
Versioning documentation in multiple branches
With this method, you put the documentation for each version in its own branch:
Version 3.4 -> branch v3.4
Version 4.0 -> branch v4.0
New development -> branch main
This is essentially the same strategy as described above with source code.
When you’re ready to create a new release, you create a new branch from the main
branch:
1
2
3
4
5
# Ensure you are on the main branch
git checkout main
# Checkout a new branch with the name of the version
git checkout -b v2.0
Pros and cons
The main benefit here is that you are able to match the workflow of the source
code itself. There is also no duplication of content: the content for each
version lives in its own branch.
The downside of this approach is that many docs-as-code tools do not support
this workflow. Static site generators like Docusaurus
cannot construct one site from multiple Git branches. Instead, you have to
deploy separate sites for each version, which can add a lot of complexity.
Doctave supports this form of versioning and can
build your documentation from separate branches into a single documentation
site. The user can then select which version of the documentation to view from
a dropdown menu.
On the open source side, the AsciiDoc documentation site generator
Antora also supports this workflow.
So in short:
✅ Mirror how source code is versioned
✅ Little duplication of content
⚠️ Requires specialized support from your tools or managing multiple sites
Versioning documentation in one branch
You can also choose to version your documentation all in one branch. This is
arguably the simpler way to manage documentation.
The idea is to structure your documentation something like this in your Git
repository:
Each version lives in its own subdirectory, in a single branch. Docusaurus
supports this method of versioning,
and it is able to generate a dropdown that lets the user swap between versions.
You can also decide to build each version into a separate site that can be
deployed and hosted independently. But then the same issues regarding routing
come into play as in the multi-branch setup.
Pros and cons
The main benefit here is simplicity. If you are not an experienced Git-user,
having everything in one branch is easier than juggling multiple branches.
There are however some significant downsides to this workflow.
The main issue is around content duplication and build times. For example,
adding a new version in Docusaurus means copying all of the content you have
in your existing docs into a new subdirectory, which now becomes your new
version.
If you only change 20% of your docs between versions, 80% of your files will be
needlessly duplicated.
This can lead to very long build times. The Write The Docs Slack, popular among
technical writers, is full of anecdotes of Docusaurus builds even taking over 30
minutes.
Some other tools may be faster, but the fact is that the more content you have,
the slower your builds will be. Tools that cannot build versions independently
will always struggle when you add more versions.
So, to recap:
✅ Simple - no need to manage multiple branches
⚠️ Duplicated content
⚠️ Can be a big cause of long build times
Versioning documentation using Git tags
One final option that works in some cases is using Git tags.
Tags are a feature in Git
that lets you effectively give a name to a specific commit.
In this workflow, when you are ready to publish the documentation for a given
version, you add a tag to that commit:
1
git tag -a v1.4 -m"Version 1.4"
You can then go back to any tag you’ve created easily by checking out that tag: