How To Automate Documentation Workflow For Developers
To get the most out of this tutorial, you should be familiar with: Git, GitHub and Linux and the command line.
Why Should You Care About High-Quality Documentation?Many teams struggle with writing documentation. When you go to check a framework, the documentation will often be out of date or unclear. This can lead to internal frustration when a team member tries to add a feature, but they don’t understand how the current feature works because of poor documentation. This can lead to unproductive hours on the job.
Poor documentation also compromises a good customer experience. According to Jeff Lawson, author of Ask Your Developer and founder of Twilio, if you are selling an API as a product, documentation is the ultimate advertisement for technical stakeholders. IBM did a study on the importance of documentation, and 90% of respondents admitted that they made their purchasing decisions based on the quality of a product’s documentation.
Writing good documentation is important for the developer and customer experiences.
If Documentation Is So Important, Then Why Do Engineering Teams Deprioritize It?Writing documentation can break developers out of the “flow”. Documentation often lives outside of the main code base, and it is cumbersome to find and update. Putting it in an Excel spreadsheet or a proprietary CMS is not uncommon.
Automating documentation and improving documentation workflow fixes this.
Automating Documentation From a High LevelWhat does automating documentation mean? It means adopting common software development practices. When you automate documentation, you are:
- writing your documentation in Markdown;
- using a continuous integration and continuous deployment (CI/CD) pipeline to run tasks such as correcting errors and deploying updates (in this tutorial, we are going to highlight GitHub Actions);
- implementing tools like Vale to enforce a style guide and to correct common grammatical mistakes.
Before you use tools such as Vale and GitHub Actions to automate the style guide, let’s take a moment to define what exactly is a style guide.
You know that feeling when you are writing documentation and something seems a little off? Your explanations don’t fit the rest of the documentation, but you can’t quite describe why they’re wrong. The writing explains the concept, but it doesn’t seem to fit.
When you get this feeling, your voice and tone might be off. Refining the voice and tone is a way to make writing sound cohesive even if you are developing documentation that has been edited by the QA, engineering, and product teams. Below is an example style guide from the city bus application TAPP, taken from the book Strategic Writing for UX by Torrey Podmajersky.
TAPP is a transit application (for buses and trains). The header of the table announces TAPP’s values as a company, being efficient, trustworthy, and accessible. The left side of the table lists the different parts covered by the style guide: concepts, vocabulary, verbosity, grammar, and punctuation.
Together, these make a style guide. The header introduces the values, and the left side of the table shows the different components that you would find in any written material: vocabulary, grammar, and punctuation. The beauty of this style guide is that engineers and copywriters will clearly know what capitalization to use and which punctuation to use in order to promote Tapp’s brand identity.
Technical Writing Style Guide
Not all style guides come in tables. Microsoft has a whole website that serves as a comprehensive guide, covering everything from acronyms to bias-free communication to chatbots. Microsoft of course isn’t the only company that has a style guide. Google has one, too.
The Trouble With Style Guides
Style guides are a great starting point for companies that are serious about documentation. They solve a lot of the confusion that developers might have about how exactly to write about a major feature that they are pushing out.
The problem with style guides is that they add friction to the writing process. Many writers, including me, don’t bother to stop writing and look at the style guide every time they have a question. Sometimes, a style guide is cumbersome and too difficult to reference — for instance, the Microsoft Style Guide is over a thousand pages long!
Linters and CI/CD for DocumentationIf you are a programmer, then you are probably familiar with linters. Linters are an ideal way to enforce coding standards on your team. The same is true with documentation. When you create a linter, you are setting a benchmark of quality for your documentation. In this tutorial, we are going to use the Vale linter.
Using some sort of documentation automation alongside a linter is common. When we say automation in this context, we’re referring to the continuous integration and continuous deployment (CI/CD) workflow. CI automates the building and testing of documentation. CD automates the release of code.
You can use many different types of apps to implement a CI/CD workflow. In this tutorial, we are going to use GitHub Actions to run our documentation linter. GitHub Actions run CI directly in a GitHub repository, so there is no need to use a third-party application, such as CircleCI or Travis.
Finally, GitHub Actions are event-driven, which means they are triggered when something happens, such as when someone writes a pull request or an issue. In our example, a GitHub action will occur when someone pushes changes to their main branch.
GitHub ActionsFirst, create a GitHub repository. Then, locally, create a folder and cd
into it.
mkdir automated-docs
cd automated-docs
Once you are in the folder, initialize the directory for Git.
git init
Once you have initialized the repository, proceed to create a workflow directory to your folder.
mkdir .github/ && cd .github/ && mkdir workflows/ && cd workflows/
Workflows are where we will store all of our GitHub actions. Once you’ve created a workflows
folder, make a new workflow. We are going to name this workflow vale.yml
.
touch vale.yml
Vale.yml
is a YAML file. In this workflow file, we will include actions and jobs.
Now, open vale.yml
in your favorite text editor.
nano vale.yml
Copy and paste the following into vale.yml
, and let’s go over the context and syntax.
# This is a basic workflow to help you get started with Actions
name: CI
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the main branch
push:
branches: [ main ]
pull_request:
branches: [ main ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
# Runs a single command using the runners shell
- name: Run a one-line script
run: echo Hello, world!
# Runs a set of commands using the runners shell
- name: Run a multi-line script
run: |
echo Add other actions to build,
echo test, and deploy your project.
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
name
This is the name, or what we are calling our workflow. It is a string.on
This controls the workflow and the triggers.jobs
This is where we set up and control our actions. We select the environment where our actions will run — it is usually a good bet to go with Ubuntu. And this is where we will add our actions.
GitHub has a guide on all of the other workflow syntax and variables, in case you’re curious.
In this section, we have:
- learned what GitHub actions are,
- created our first GitHub workflow,
- identified the most important parts of a GitHub workflow YAML file.
Next, we are going to customize our GitHub workflow to use Vale.
Set Up Vale in GitHub Actions FileOnce we’ve copied the base workflow file, it is time to customize it, so that we can start using Vale actions. The first thing to do is change the name of the YAML file to Docs-Linting
.
# This is a basic workflow to help you get started with Actions.
name: Docs-Linting
Next, we want to run the Vale test once someone has pushed their changes to the main branch on GitHub. We don’t want the test to run when someone creates a pull request, so we’ll delete that part of the YAML file.
on:
# Triggers the workflow on push or pull request events but only for the main branch
push:
branches: [ main ]
The jobs
section is the main part of the workflow file, and it is responsible for running the GitHub actions.
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@master
These actions are going to run on the latest version of Ubuntu. The Checkout
action checks out the repository in order for the GitHub workflow to access it.
Now it is time to add a Vale action to our GitHub workflow.
- name: Vale
uses: errata-ai/vale-action@v1.4.2
with:
debug: true
styles: |
https://github.com/errata-ai/write-good/releases/latest/download/write-good.zip
https://github.com/errata-ai/Microsoft/releases/latest/download/Microsoft.zip
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
We have named our action Vale
. The uses
variable shows which version of Vale we’re going to implement — ideally, we should use the most recent version. In the with
variable, we set debug
to true
.
The styles
section gives us the option to add a style guide to Vale. In this example, we are going to use write-good
and Microsoft’s official style guide. Keep in mind that we can use other style guides as well.
The final part of this GitHub action is env
. In order to run this GitHub action, we need to include a secret token.
This is what the result should look like:
# This is a basic workflow to help you get started with Actions.
name: Docs-Linting
# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events but only for the main branch
push:
branches: [ main ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
prose:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@master
- name: Vale
uses: errata-ai/vale-action@v1.4.2
with:
debug: true
styles: |
https://github.com/errata-ai/write-good/releases/latest/download/write-good.zip
https://github.com/errata-ai/Microsoft/releases/latest/download/Microsoft.zip
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
Once you’ve finished making changes, save the file, commit to Git, and push your changes to GitHub.
git add .github/workflows/vale.yml
git commit -m "Added github repo to project"
git push -u origin main
To recap, in this section, we have:
- triggered the action to occur when we push new code to the
main
branch; - added a Vale action, setting
debug
totrue
and identifying style guides; - added a GitHub token;
- committed changes and pushed to GitHub.
In the next section, we are going to create a Vale configuration file.
Setting Up Vale Configuration FileGo to the root of your project’s directory, and then touch .vale.ini
. Open .vale.ini
in a text editor. Copy and paste the following into .vale.ini
:
StylesPath = .github/styles
MinAlertLevel = warning
[formats]
Markdown = markdown
[*.md]
BasedOnStyles = write-good, Microsoft
StylesPath = .github/styles
TheStylesPath
gives the path of the Vale styles.MinAlertLevel = warning
The minimum alert level shows the scale of severity in alerts. The options aresuggestion
,warning
, anderror
.[formats]
Markdown = markdown
sets the format as Markdown.[*.md]
The configurationBasedOnStyles = write-good, Microsoft
will run write-good and the Microsoft style guide on all Markdown files ending with.md
.
This set-up is the bare minimum. If you are interested in learning more about configuring Vale, head over to the documentation.
When you are finished making changes, save the file, and commit and push to GitHub.
git add .vale.ini
git commit -m "Added Vale config file"
git push -u origin main
In this part, we’ve learned the internals of a Vale configuration file. Now it’s time to create sample documentation.
Creating Documentation and Triggering the Vale GitHub ActionsNow it is time to see Vale and GitHub Actions in action! We are going to create a Markdown file and fill it with text. And we are going to get our text from DeLorean Ipsum.
Go to the root of your project, and then touch getting-started.md
. Once you’ve created the getting-started
file, go to DeLorean Ipsum and create some dummy text for your documentation. Then, return to your text editor and paste the text in getting-started-md
.
# Getting Started Guide
I can’t play. It’s my dad. They’re late. My experiment worked. They’re all exactly twenty-five minutes slow. Marty, this may seem a little foreward, but I was wondering if you would ask me to the Enchantment Under The Sea Dance on Saturday. Well, they’re your parents, you must know them. What are their common interests, what do they like to do together?
Okay. Are you okay? Whoa, wait, Doc. What, well you mean like a date? I don’t wanna see you in here again.
No, Biff, you leave her alone. Jesus, George, it’s a wonder I was ever born. Hey, hey, keep rolling, keep rolling there. No, no, no, no, this sucker’s electrical. But I need a nuclear reaction to generate the one point twenty-one gigawatts of electricity that I need. I swiped it from the old lady’s liquor cabinet. You know Marty, you look so familiar, do I know your mother?
Save the file, commit it, and push it to GitHub.
git add getting-started.md
git commit -m "first draft"
git push -u origin main
Once you’ve pushed the changes, head over to GitHub where your repository is located. Go to the Actions
tab.
You will see all of your workflows on the left side. We have only one, named Docs-Linting
, the same name we put in the vale.yml
file.
When we push the documentation to GitHub, we will trigger the action.
If the action has run without any problems, we will get a green checkmark.
Click on “Added docs” to get a full report.
You will see that we got 11 warnings. Let’s deal with the “weasel word” warning. Go back to the text editor, open getting-started.md
, and delete the word “exactly”.
# Getting Started Guide
I can’t play. It’s my dad. They’re late. My experiment worked. They’re all twenty-five minutes slow. Marty, this may seem a little foreward, but I was wondering if you would ask me to the Enchantment Under The Sea Dance on Saturday. Well, they’re your parents, you must know them. What are their common interests, what do they like to do together?
Okay. Are you okay? Whoa, wait, Doc. What, well you mean like a date? I don’t wanna see you in here again.
No, Biff, you leave her alone. Jesus, George, it’s a wonder I was ever born. Hey, hey, keep rolling, keep rolling there. No, no, no, no, this sucker’s electrical. But I need a nuclear reaction to generate the one point twenty-one gigawatts of electricity that I need. I swiped it from the old lady’s liquor cabinet. You know Marty, you look so familiar, do I know your mother?
Save the changes, commit it to Git, and push the new version of the file to GitHub. It should trigger the GitHub action.
If we click on “Deleted the weasel word”, we will see that we have only 10 warnings now, and the “weasel word” warning is gone. Hooray!
We are finished, and we’ve covered a lot of ground. In this section, we have:
- added documentation to our Vale GitHub Actions repository,
- triggered the Vale GitHub action,
- corrected an error produced by Vale and pushed the change back to GitHub.
In a world that is increasingly going remote, prioritizing good documentation and good documentation workflow is important. You first have to define what “good” is by creating a style guide. Once you’ve figured out the rules of your documentation, then it’s time to automate.
Documentation should be treated like your code base: a living body of work that is constantly being iterated and becoming a bit better than the last time you updated it.