[placeholder]

Making Documentation Simpler and Practical: Our Docs-as-Code Journey

Making Documentation Simpler and Practical: Our Docs-as-Code Journey

In the fast-paced world of software development, documentation often gets a bad rap. It's perceived as a chore, a necessary evil, and sometimes, unfortunately, an afterthought. But what if writing documentation could be as dynamic and collaborative as writing the code itself? What if it could be simpler to write and more practical to use?

Our Squarespace Domains engineering team has embarked on a journey to transform our approach to documentation, embracing the "Docs-as-Code" (DaC) philosophy. This blog post will share our experiences, insights, and the benefits we've reaped from treating documentation like code.

To set the stage with a visual, a typical DaC flow often looks like the image below:

Figure 1 — A typical Docs-as-Code flow

In our process that started around a year ago, our team’s docs and code are versioned together in Git. Pull request (PR) review is the same for both scenarios, including code and documentation changes existing in the same PR at times. Once those changes are approved and merged to our master branch, they flow through our CI/CD pipeline until they’ve made their way to production. 

We’ve been loving it so far given the simplicity of keeping documentation up-to-date. But, all of this sounds like a lateral process change – we could still draft documents in Google Docs, ask our teammates to review them, sign off on a formal approval chart, and share links to those docs. So, why is it better?

Why Docs-as-Code?

Traditional documentation methods often suffer from several drawbacks:

  • Inefficiency: Code and documentation are typically created and maintained on different platforms, leading to disjointed workflows. If you can do all of your tasks in one workflow with one approval process, it encourages doing the “boring” stuff.

  • Tooling Challenges: Tracking changes and maintaining consistency between code and documentation can be a nightmare. And, outdated documentation easily lacks relevant context, increasing toil to understand our docs while undermining trust in them.

  • Confusing Ownership: Traditional tools default to the author owning the doc, which is known to cause friction or information loss when members switch teams. When systems are designed with narrow ownership, it’s often unclear who has the authority to apply updates. By default, DaC empowers anyone who can access the repository to propose a change, and it still provides ownership for a specific set of approvers.

  • Less Iteration: Docs are traditionally written in the waterfall model where changes come in bulk, delivered less frequently. This is at odds with Agile software development, which prioritizes incremental delivery. Agile is a core value in our product development processes across Squarespace.

Also known as Continuous Documentation, or Agile Documentation, DaC addresses these challenges by introducing software engineering principles into the documentation process. It means using the same tools and workflows for writing and maintaining documentation as we do for our code. This involves:

  • Version Control: Storing documentation in the same repositories as our code, leveraging tools like Git for version control. Git not only gives us versioning, but allows us to use GitHub as our review tool. This is handy because it's a tool our whole team already uses for review purposes on a daily basis. And, anyone can contribute since our repositories are open to all of Engineering.

  • Plain Text Markup: Using lightweight markup languages like Markdown for easy readability, editing, and reviewing. No need to fight with the invisible syntax markers in a word processor – unless you want to!

  • Continuous Deployment: Integrating documentation into our continuous integration and deployment pipelines. Every time doc changes are merged to our master branch, our team's CI/CD pipeline updates Backstage* automatically. This gives us confidence that every time there’s a documentation update, it’s guaranteed to land in a standard, easily searchable place.

*Backstage, an open-source framework, empowers organizations to build developer portals. It streamlines microservices and infrastructure through a centralized software catalog, enabling product teams to deliver high-quality code and reference material rapidly while preserving their independence.

By adopting these practices, we've created an environment where code and docs can be written on the same platform, providing an incentive to write documentation while working on features. Less friction leads to more collaboration and, ultimately, better communication within and beyond our team.

But Wait, There’s More

Embracing Docs-as-Code has brought about significant improvements in our documentation efforts across so many facets of our roles as engineers. Streamlining our docs process in this way has given us additional inspiration due to reduced friction, benefitting us more than we imagined. Most notably, we have:

  • A renewed focus on architecture and system design: with docs integrated deeply into our workflow, we’ve put our diagrams next to our code. We can quickly maintain them, and have a tighter feedback loop because of pull requests. We've also adopted tools that allow us to create diagrams using plain text, ensuring they are version controlled, easily updated, and used consistently as standard tooling.

  • Richer traceability: The change history of our docs in relation to our code has been greatly enhanced, making it easier to understand changes over time and identify people with exposure to specific areas of the system.

  • Faster iteration and better collaboration on all document types: Service alert runbooks, cron job overviews, how-to articles, FAQs, API documentation generated from OpenAPI specs, and more. If it’s technical, it belongs in our repos where anyone can find it and propose edits as needed.

Our Implementation: How We Do It

At this point, we’ve listed and praised the benefits associated with DaC. So, we’ll share some of the details and a few tips on how we work in this mode daily.

As mentioned, we use Markdown. We use it for writing documentation, RFCs, and specs in .md files, which are stored alongside our source code. Markdown's widespread familiarity stems from its decade-plus-long status as an industry-standard markup language. Just about any engineer knows it or can pick it up with ease. Additionally, many of our documents incorporate Mermaid syntax, to define system flows, state diagrams, and sequence diagrams as code, facilitating the creation of versioned visual documentation. Check out how easy it is!

Figure 2 — Mermaid example

Tip: For newbies to Markdown, you can actually write your documentation in Google Docs and download it as a Markdown file. Note that only features with a Markdown equivalent can be exported this way, but it’s a low-friction way for engineers to contribute without jumping into writing Markdown from scratch.

Figure 3 — Google Docs Markdown download option

Backstage Integration

We use Backstage as our developer portal, which plays a crucial role in our Docs-as-Code workflow as a reliable, central hub for all of our teams’ docs – and it’s built to integrate with deployment pipelines. Our documentation is easily discoverable and accessible to not only our team, but any team that needs it.

Figure 4 — User receiving a hint of a new version of documentation, a benefit of our CI/CD approach

We also encourage team members to participate in internal training courses, available on our learning hub, to effectively utilize these tools. This way, we’re all onboarded into a common process, setting expectations for how we communicate. A side note, if your company doesn’t already have a learning hub for training materials like this, it’s a massively helpful resource to consider!

Previewing Changes

Last, but not least, to ensure the quality and accuracy of our documentation, we chose robust previewing mechanisms. Immediate feedback is essential for effective communication, so we standardized on a solution to keep things visual. This ensures our process doesn’t treat documents too much like code – or at least code you have to compile!

For local previews, we use the Intellij Mermaid plugin to check diagrams during development and run Backstage’s TechDocs CLI to preview changes locally using their TechDocs server.

Figure 5 — Local preview example

For remote previews, we push changes to a branch with the techdocs-preview suffix (e.g. update-trainings-techdocs-preview). This creates a preview in our staging environment, giving us an opportunity to verify our changes on a production-like instance of Backstage before sending them to actual production.

Figure 6 — Remote preview example

Tip: You’ll want to add the Kroki plugin to enable Mermaid rendering in TechDocs. A small price to pay for a sweet convenience!

Conclusion

The Docs-as-Code/DaC approach has revolutionized how our engineering team handles documentation. It has made documentation a more integrated, efficient, and enjoyable part of our development process. By treating docs like code, we've not only improved its quality and maintainability but also fostered a culture where documentation has increased value, and is seen as an essential component of every project.

Leveraging Change Data Capture For Database Migrations At Scale

Leveraging Change Data Capture For Database Migrations At Scale