Documenting Go Github Repo

17 April 2020

The Go language makes the documentation very accessible. The documentation serves two types of clients - developers who work on the documented code, which consume it from the code itself, and code users which consume the documentation from a web UI or from the go doc command line. In Go, the documentation is a first-class citizen of the code, and writing it properly can make code development easier and results in a magnificent pkg.go.dev (the new godoc.org) site for your package. Github, the code hosting service for many Go packages, does not support Go documentation, but does support markdown readme file in the package root directory, by rendering in the home page of the repository. This page is important since it is the first thing that developers see when they find your project, and it is usually being used to get information about the project. Both the Go doc and the readme file are important - the upside is that it is possible to design them to share common content - the flipside is that constantly maintaining both of them can be a burden… Or is it?

:heart: I would love to know what you think. Please use the comments platform on the bottom of the post for discussion.

Github Readme

From Github:

You can add a README file to your repository to tell other people why your project is useful, what they can do with your project, and how they can use it.

Once a readme file is added to the repository, Github will show it in the front page, and most Github users use it in order to introduce themselves with the unfamiliar repository. Other code hosting services, such as Bitbucket and Gitlab use the same approach.

Github readme of the Go programming language

Markdown

Even though Github supports other readme formats, markdown seems to be the most common one used to document the repository. According to its creators, Markdown allows you to write using an easy-to-read, easy-to-write plain text format, then convert it to structurally valid XHTML (or HTML). It supports headings, paragraphs, text formatting, inlining code and code blocks, bulleted and numbered lists, adding links, images, quoting, inlining some HTML tags and more. Github has its own flavor with some “extensions” to the markdown syntax such as tables and checked-list (look for “(extensions)” in the linked spec).

Godoc

We all love documenting our code. It is important for developers who are working with the source code (or to ourselves in two weeks from the time we wrote it), or to developers who want to use the code in their project through the go doc command line or the pkg.go.dev (the new godoc.org) web UI.

The go doc syntax enables a small number of formatting features: heading, paragraphs, code blocks and links. Amit Lavon made a wonderful page that explains how to use them.

go.dev Go doc of the net/http package

goreadme

Usually, developers maintain both the Go doc and the readme file for the enumerated reasons above. Sometimes developers recognize the duplicated work and set a short readme that just refers to the Go doc page.

As an open source developer, I want attractive readme files, as well as good code documentation and a helpful go doc sites. In the past, I found myself spending too much time on synchronizing the readme file with the code. Now I can save time thanks to goreadme - a tool that converts the Go documentation to markdown readme.

goreadme generates a markdown readme file from a package Go documentation. It is available as a command line tool, as Github action, or as a library.

Extending godoc syntax

When working on this project, one of the first problems I noticed was the limited syntax of Go doc. It lacks support for images, bulleted or numbered lists, or declaring a language for a code block. When writing the Go doc to also be used as a markdown file, there are two possible scenarios: Using the full markdown syntax in the Go doc, which then results in an attractive Github page but weird looking Go doc. Or limit the markdown features to the one supported by the Go doc syntax, which results in an uninviting Github page but readable Go doc.

Choosing which path to follow is actually up to the developer who writes the documentation. However, the goreadme converter extends the Go doc syntax in a way that it enables some more markdown features without harming the Go doc readability, such as link titles, images and diff blocks.

Github Actions Integration

One last question is - how do we keep the documentation and the readme file synchronized. One option is to constantly run the goreadme command line tool and commit the modifications with the code. The problem is that it is still a burden to remember to do this task.

Goreadme is available also with Github actions integration, in two flows:

  1. Pull request flow: When a new PR is created, the pull request flow will check if this change results in any changes to the readme file, and if so - it will comment the PR with the expected readme file diff.

    pull request comment example

  2. Push flow: When a new change is pushed which results in a readme change, the Github action will push a new commit with the updated readme file.

    commit example

Opting into the integration is as easy as adding a single file to a repository. The parameters for the Github actions are available here. The integration does not require any credentials - providing the Github token parameter is only needed to enable the diff comments option. Just put the following content in .github/workflows/goreadme.yml:

on:
  push:
    branches: [master]
  pull_request:
    branches: [master]
jobs:
    goreadme:
        runs-on: ubuntu-latest
        steps:
        - name: Check out repository
          uses: actions/checkout@v2
        - name: Update readme according to Go doc
          uses: posener/goreadme@v1
          with:
            badge-travisci: 'true'
            badge-codecov: 'true'
            badge-godoc: 'true'
            badge-goreadme: 'true'
            # Optional: enable goreadme to comment on PRs.
            github-token: '${{ secrets.GITHUB_TOKEN }}'

Wrap up

Adopting the goreadme workflow may require some work. Usually the Go doc is not written in a way that suits Github readme files. But this work pays off - first, by doing so you will improve your Go doc page, which is also very important. Second, after doing it once, goreadme is doing all the hard work for you, and all you have to do is to update your code documentation - something that we all :heart: to do!