Month: May 2020

Docs-as-code workflow: the missing link; a collaboration tool

Writing

Docs-as-code workflow: the missing link; a collaboration tool

Docs as code is a technical documentation movement to use the same tools that developers use in the documentation workflow. It’s a great way to enable collaboration with developers, and now that I’ve been doing it for more than a year, I can’t imagine writing documentation for developers, with developers in any other toolchain. But one thing is missing from most docs-as-code workflows: a collaboration tool to easily share the work and solicit feedback.

Why do you need a collaboration tool in a docs-as-code workflow?

One might question why you need a collaboration tool beyond the git provider when you’re writing technical documentation for and with developers. Just commit, push it to your preferred git provider (I mostly use GitHub), make a pull request, and request review.

Sure, fine, that’s all well and good for a simple text change. But what if you’re adding new pages, or entire new sections, to the documentation? What if you’re adding images, callout elements, and other styling? What if you’re changing visual elements on a page? Reading text in GitHub is easy enough, but anything more complex than that, such as clicking through the navigation of a new page or new sections, seeing images in line with text, or really looking at any visual change adds that much more resistance to reviewing a PR.

If it’s not something that parses easily in text, or if it’s a change to linking or navigation that wants human verification, whomever you’re collaborating with must maintain a local version of the documentation site, pull down the branch or check out the PR locally, and then build the site locally in order to view the changes. If the reviewer doesn’t already have a local version installed, how much longer do you think it’ll take them to review your documentation PR? Ugh, now I’ve got to install this web framework, clone down the repo, and then get the whole thing set up just to check out these three new pages… I’ll do it later.

Then you have the issue of whether your reviewer is a non-technical stakeholder. What if you need the product manager to review and sign off on your documentation before it can go live? What if someone in marketing, or someone on the leadership team, wants to see details about how the hot new feature works before you push publish? That person isn’t installing a local and cloning down a git repository just to look at a few pages. That person may not even have access to the git repository.

What you need is a collaboration tool that doesn’t require the reviewer to have a local install of the documentation site at all.

Enter Tugboat, the missing link

So how do you solve this problem? There are a number of ways you might approach it, but I think the best case scenario is to add a continuous integration tool that can build your site before you push the changes live. Unfortunately, for many technical writers, setting up that tech stack is a bit beyond us.

Setting up a CI solution requires adding services, having access to servers where the site can be deployed, etc. The organization may not have the appetite for that kind of infrastructure investment just for documentation. Even if it does, you’ll need a developer to set it up and maintain it. But even if you can get a developer’s time to set it up, that’s the kind of project people wander away from, and when it inevitably breaks at some future point, good luck getting a developer’s time again to debug it.

This is where Tugboat comes in. It’s a git pull request builder that automatically generates a working version of the website for every pull request/merge request. (This is also a developer tool that developers use when building websites, so it’s a good match for the docs-as-code workflow. And who among us doesn’t love introducing developers to a good tool they’re going to love?)

How Tugboat works

Using Tugboat involves a few steps: set up a project in Tugboat, link it to the git repository where your documentation site lives, and commit a config.yml file that lives in a .tugboat folder at the root of your directory.

The config gives Tugboat the instructions it needs to build your site. The documentation site (that I write!) offers starter configs for some common static site builders, as well as things like building a WordPress or Drupal website, with more configs and tutorials added as they’re requested.

While the sample config files are helpful, you probably don’t need one that’s specific to your static site builder. I made the Hugo and MkDocs files myself by working from the old config for our deprecated GitBook legacy documentation site. If you do get stuck, I’m happy to help, or Tugboat has a Support Slack that anyone can join to ask questions.

With Tugboat configured, there are a couple of ways to view the website previews; either directly in the Tugboat UI:

Or you can configure Tugboat to post the website preview right to your pull request in your git provider, either as a deploy environment or as a link in the comments on your PR:

At this point, anyone with access to the git PR can click on the Tugboat link and view a live preview of the site. You could also copy the URL and send it to any non-technical stakeholder who wants to review the site – be it a product manager or a member of the leadership team. Anyone you send the link to can view the site, with no need to have a git or Tugboat account. For a docs-as-code project, developers who are reviewing your PRs can do it in Tugboat, without checking out the PRs and building them locally.

This is the Tugboat preview for this site (just an example site for testing):

That’s a fully working version of the site, with clickable links and everything, just as if I had built it locally. It’s hosted at a temporary URL at Tugboat, and when I merge the PR, the Tugboat preview gets deleted automatically – no need for me to do any cleanup. If I make changes to the PR, the Tugboat preview can be rebuilt to include those changes.

Conduct simultaneous reviews easily

With this collaboration tool in my pocket, I can have anyone I want review changes to the documentation site before it goes live. I don’t have to worry about maintaining a staging or QA server for the documentation site, or getting stuck with review bottlenecks while I wait for a developer to deploy changes so someone can look at my work.

Even cooler is the ability to conduct simultaneous reviews easily. Say, for example, my company has a new user admin feature coming, so I update the docs and make a PR. A Tugboat preview gets generated, and I can share it with the product manager and/or developers responsible for that feature for review.

Separately, there’s a new tool being added to my company’s app. As long as I’m using a proper branching workflow and branching from master, I can create those docs independent of the user admin feature above. Make a PR for that documentation, and a different Tugboat preview gets generated. I can send those docs to a different product manager and development team for review. That review can be happening simultaneous to the one above, and whichever review is completed first can get merged into the documentation.

I don’t have to worry about the user admin review being done, so I can then get the documentation for the new tool loaded to the staging server for sharing with relevant stakeholders, etc. And if the documentation for the new tool gets approved first, I can merge that PR and the Tugboat preview goes away, while the link to the user admin documentation change persists.

I’ve been super happy with having this tool in my technical documentation workflow, and I wish I’d had it at prior jobs. Now that I do, I can’t imagine working in a docs-as-code workflow without it.

Learning to code: redux

Coding

Learning to code: redux

A little over a year ago, I wrote here about how I was learning Swift because there are a couple of apps I want to write. I’ve gone through a few courses online, and had started working through an Everyone Can Code book: AP Computer Science Principles with Swift. I was making good progress, had done the data modeling for my “main” app, but then got a little overwhelmed with the idea of actually starting it. Like, how does a n00b sit down and begin writing an app for the first time?

Then came some health issues last fall, and then Christmas, and then this spring the whole world has turned upside down…

So here we are a year later, and I haven’t written my apps, although I’ve been getting cozier with the code needed to modify the functionality in the static site generators we use for work (Jekyll and Hugo) and my Git foo has gotten to be second nature. But the actual proper “learning to code” I had wanted to do has been nagging away at me. So when one of my co-workers posted that Stanford University’s Engineering department was offering a free intro to coding class, Code in Place, I jumped at the chance to sign up.

Fast forward to six weeks later. I was one of 10,000 interested geeks-in-training who got accepted in this massive international experiment of teaching a diverse student base how to code in Python, entirely online.

I attended all the “sessions” – video chat classes, of sorts, consisting of a group of 10 students working under a “section leader” to practice solving various problems with code. I’ve watched 14 recorded lectures via YouTube, led by Stanford instructors, and have worked through all of the slides and code from each lecture. I’ve learned about decomposition, control flow, images, graphics, and animation – in addition to things like variables, expressions, functions, lists, and dictionaries – all the fundamentals to build a solid coding foundation.

My “deliverables” for class have included three assignments, which I uploaded to an autograder to see if they functioned and passed various tests. I also did a “diagnostic” to help determine which concepts I understood thoroughly, and where I needed additional help. (That was supposed to take an hour, but it took me an hour and 40 minutes – but I worked through the whole dang thing, without bothering my husband the experienced web dev for help, until I got it all done and it all worked.)

Now, we’ve arrived at the final week of class, and I’m doing a final project. For this final project, I’m writing an app! Finally. Not one of the apps I had planned to write a year ago; this is a new idea, which is based on a recent experience I had at work and seems well-suited to be a Python project.

Here’s the premise: the technical documentation I write at work contains screenshots. The screenshots are images taken on various pages of our app. When we make changes to the app’s UI, I need to update the screenshots to reflect the new UI. Sometimes that’s easy, like when the User Profile options change, I know I need to update docs around the user profile. But what about things like adding a git provider, or changing the API key, which are options that you get to through the User Profile menu? It might not be obvious to me that I need to update those screenshots in seemingly unrelated sections of the documentation.

For my Code in Place final project, I’ve decided to write an app to solve this issue: a screenshot inventory tool, which can call out to a visual diffing tool, and then return to me a list of screenshots I need to update based on pages that have visual diffs.

So far, I’ve got the screenshot inventory piece working; I can create a list of all the screenshots in my technical documentation, and associate those screenshots with URLs in the app (dictionaries are awesome). I added some fun calculations to tell me how much coverage I’ve got in this screenshot inventory; for example, I’ve got 181 screenshots in my documentation, but have only inventoried 14 of them so far, so roughly 7% of my screenshots have been inventoried. I’ll work toward 100% coverage, because that becomes more important when I get the second piece working: the visual diffing element.

For the visual diffing element, I’m learning how to make API calls to a visual regression tool, Diffy, that can generate visual diffs of pages across environments. So I can have it diff production and staging, for example, and tell me which of the pages that I’m tracking contain changes in staging. Then my app will give me a list of the screenshots associated with that page, so I’ll know which screenshots I need to update when there are changes to the app.

Bonus: the process of making these associations has made me realize there are some nearly duplicate screenshots in my technical docs, which could be streamlined a bit. So hopefully this exercise will help me tighten up my documentation images and maintain fewer assets. Bonus win!

I’m handling a lot of this data storage and processing in JSON. Code in Place didn’t cover writing to files, so I don’t have databases and am trying to keep the scope small enough to finish a final project in a week (while also working a full-time job and prepping my veggie garden for spring). Fortunately, my data storage needs are simple, and JSON lends itself well to API calls, so that helps.

API calls are also out of scope of what we learned in Code in Place, but I’ve documented APIs before and am familiar enough with the basic functionality that I’m hopeful I can get that part working before the final project is due. If not, I’ve got the screenshot inventory part working, and can always keep working toward the visual diffing processing after class is “over.”

At this point, though, I think I can finally check off the box that says: “learning to code.” I’ve written an app that does a thing, and it’s a step beyond the Hello World type stuff I’ve done so far in Swift. I’m enjoying the problem solving; I spend a couple of hours every evening working on code, and go to sleep with code in my head and wake up with problems solved. I might eventually pick up a Python web framework and give it a web UI, or maybe I’ll leave it a command-line tool and change gears back to Swift now that I’ve actually started and written a thing.

Or maybe I’ll go even deeper down the rabbit hole, because learning is fun, and poke the Python/Swift interoperability stuff and give it an iOS app. Why not? The sky’s the limit once you’re well and truly started down the path of programming.