bdunagan

Brian Dunagan

February 5 2022
Building a Technical Documentation DocOps/DevOps Pipeline

Unsplash - @syinq

Retrospect Backup is designed to be easy to use for non-technical customers, but it has a deep set of features for the technical subset. To understand its capabilities, customers need well-written, up-to-date documentation, in the form of user guides and knowledgebase articles in their language, with targeted content accessible as a URL. Retrospect has been around for 33 years and supports six languages, so achieving that goal is a significant ongoing DocOps/DevOps project.

In the past, we used Adobe FrameMaker for our user guides and a Salesforce Force.com Site for our knowledgebase. Using FrameMaker meant only someone with FrameMaker knowledge could update the user guides, typically an outside contractor. It was difficult to see what changed when updating the content, so the team had to trust spot-checking. Using Force.com meant Support could manage the knowledgebase content, but it wasn’t easy and had no search capabilities at the time. Moreover, language support for both simply multiplied the required tasks.

All these barriers led to fewer documentation updates, detracting from our customer experience and increased Support tickets from confused customers.



Documentation Pipeline

To simplify the process of keeping documentation current and adding new information, we updated our documentation DocOps/DevOps pipeline with a set of goals and the following tools:

  • Markup: Documents need to be readable plain text with markup => AsciiDoc and Markdown
  • Source Control and WYSIWYG: Documents need to be versioned, diffable, and editable by non-technical staff => Git and GitHub
  • Languages: Documents need to be easily localized => Gengo
  • Deployment, Search, and Links: Document generation needs to be automated and deployable with search and deep linking => Website, Prince, and Swiftype

Documentation Pipeline


Markup: AsciiDoc and Markdown

Markup languages like AsciiDoc and Markdown are excellent at embedding sophisticated styles and layouts in plain text. AsciiDoc in particular was designed for generating books from markup, so it works well for both HTML generation and PDF generation. We use AsciiDoc for most parts of our documentation now, both user guides and KB articles, and mix in Markdown documents when it’s easier.

Converting Adobe FrameMaker to AsciiDoc was painful. The Retrospect Backup for Windows User’s Guide was 500 pages long, and the Retrospect Backup for Mac User’s Guide was 300 pages long. Each was localized into six languages: English, German, Spanish, French, Italian, and Japanese. First, we exported from FrameMaker to HTML, but the HTML was very messy. Next, we used many passes of regular expressions in Ruby to clean it up, and finally, we used pandoc to convert from HTML to AsciiDoc.

Compared to the Adobe FrameMaker conversion, we had a far easier time ingesting the SFDC Article pages that populated our Force.com knowledgebase. We used a Ruby gem to read the objects in from the API and write them out to files with bits of Ruby to convert it into Markdown. There were a small subset of KB article that had already been localized, and those were saved as kb_name.language.adoc (i.e. error_1101.ja.adoc).

With all of our documentation now in a plain text format, we could easily add, edit, delete, and localize it.



Language: Gengo

Gengo translates content within a few hours at low price point. We use them for all of our localization needs. Compared to our previous service, it has saved us thousands of dollars and months of waiting. Getting a string translated for a couple dollars in an hour by a professional sounded absurd to us before we discovered Gengo.



Source Control and WYSIWYG: Git and GitHub

We switched to Git and GitHub almost a decade ago: Migrating Retrospect from SVN to GitHub Enterprise. By adding our documentation to Git, we could easily version the content and diff any changes. We now have 402 KB articles in Git, and our user guides total 104k lines. When we recently added a new chapter in the user’s guide, it only took 10 minutes and became a GitHub pull request to be diff’d and reviewed. When Support writes up a new KB article, Engineering can add to the production website in about 10 minutes.

Moreover, GitHub provides an excellent WYSIWYG editor for AsciiDoc and Markdown files, with rich styles and preview available.

GitHub - WYSIWYG Editor

GitHub - WYSIWYG Preview

Using Git and GitHub allows us to integrate our documentation into our existing build and deployment pipeline while providing editor abilities to non-technical staff.



Deployment, Search, Links: Website, Prince, and Swiftype

The documentation is now in plain text and versioned, but we still need to deploy it with search and links. Most companies use Wordpress for their websites, but we use Ruby-on-Rails. The tradeoff is extensibility. Ruby-on-Rails is a less common choice, so fewer web developers have experience with it compared to Wordpress. However, Rails lets us quickly build new functionality: Building Deep, Scalable Customer Relationship Management Tools.

For the knowledgebase, we built a new page with categories and links to all of the articles. To populate it, we wrote a simple Rails initializer to read in all of the articles in the directory and store their frontmatter in memory to be used later by the KB index page.

Website - Knowledgebase

The user’s guides took more effort. We could easily build a section of the website for Documentation. The trick was handling the chapters well. We wanted to enable Support to link directly to specific sections of chapters without loading the entirety of the user’s guide in a single page. We manually build the chapters in the guide to allow custom sorting, but we dynamically build the subchapters by reading and parsing the AsciiDoc files within Rails. With both, we can display the any chapter along with a sidebar of the overall structure of the guide for context.

Website - User's Guide

It took some time to work out the correct AsciiDoc syntax to integrate well with Rails via asciidoctor. For instance, every chapter needed the following frontmatter:

----
:showtitle:
:idprefix:
:idseparator: -

= Chapter Title [[chapter-title]]
——

Another hurdle was incorporating ERB code into AsciiDoc, so that we could use our Rails helper functions, like short references to our S3 assets:

+++<%= image_tag(s3_image("docs/example.png"), :class => "whitepaper_image") %>+++

The user’s guides also needed to be converted into PDFs for offline usage. We use Prince to convert them from a single HTML page into 300+ page PDFs, wrapped into a Rails rake task.

Because the knowledgebase and user’s guides are on the website, all of their content is indexed by Google and others. For search, we use Swiftype to index the content, rank the results when necessary, and integrate a simple search field at the top of the page.



Alternatives

We are an engineering-focused company, and many companies optimize their documentation pipeline for other goals.

  • Full Service: Services like ZenDesk provide a complete customer service experience, from ticketing to knowledgebase.
  • Domain-Specific Documentation: There are other projects to leverage, like Slate, to create documentation for a specific purpose, like API documentation.

There are clear downsides to our approach. Retrospect Engineering is the bottleneck for feature development compared to using a third-party service. I touched on these sorts of trade-offs in Building Deep, Scalable Customer Relationship Management Tools. The issue comes down to what is best for a company at a given time.



Internal Documentation

Along with customer-facing documentation, we migrated our internal documentation from MediaWiki to AsciiDoc hosted on GitHub Wikis: 542 pages. GitHub Wikis are version controlled, in plain text, with universal search, and with access via a local repo. The wiki lives in its own repo but under the Wiki feature, so that we had access the better WYSIWYG editor with sidebar support and have the universal search separate the wiki entries correctly.

For the migration, we used Git’s wiki extension to clone MediaWiki to a Git repo then used pandoc to convert the pages from MediaWiki format to AsciiDoc. Most of the pages are old and unused, another reason why we wanted the content in GitHub. It’s easy to see the entirety of the wiki as local text files rather than a long HTML list. The biggest downside was migrating the 300 embedded images and files from MediaWiki. We opted to migrate selectively when we found one missing in a relevant wiki page in GitHub. In the end, we only migrated a couple dozen files.



Lowering Barriers

Retrospect Engineering has consistently found that better tools and workflows lead to significantly improved experiences. We found that with Git and GitHub, and we found that with these documentation pipeline upgrades. The improved DocOps/DevOps pipeline reduced our documentation schedule from weeks to days.

Leveraging Forever-Incremental Backup Technology for Customer-Centric Data Protection Containerizing our Web Development Toolchain with Docker
LinkedIn GitHub Email