Share Go package docs

Every other language's doc tool writes files. Go's serves them. go doc prints to a terminal, pkgsite -http=:8080 runs a web app, and pkg.go.dev indexes the public module graph — which covers open source completely and internal code not at all.

So the docs for the module five teams depend on exist only as a port on somebody's laptop, and the actual documentation anyone reads is the source.

Mirror pkgsite to static HTML

go install golang.org/x/pkgsite/cmd/pkgsite@latest
pkgsite -http=localhost:8080 ./... &

wget --mirror --convert-links --adjust-extension --page-requisites \
     --no-parent http://localhost:8080/github.com/acme/widgets

--convert-links is the load-bearing flag: it rewrites absolute links to relative ones so the mirrored tree works detached from the server. --page-requisites pulls the CSS and JS the pages reference.

The quick alternative, for one package and no styling:

{ echo '<!doctype html><meta charset="utf-8"><title>widgets</title><pre>'
  go doc -all ./widgets
  echo '</pre>'; } > widgets.html

Ugly, accurate, and one file.

Publish the folder

Drag the mirrored directory (or a zip of it) into Comma:

  • The package index page becomes the report body.
  • Subpackage pages, CSS and JS upload alongside it, with relative references rewritten to the uploaded copies, so cross-package links resolve.
  • Scripts run inside a sandboxed iframe (allow-scripts, no allow-same-origin), so the outline sidebar and the expandable example blocks keep working.

Access is set per report — private, your team, anyone signed in at your domain, or anyone with the link. An internal module's docs should be the second of those, which is exactly the option pkg.go.dev does not have. See sharing & access control.

From the release job

curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html mirror/index.html \
        --arg t "widgets — $(git describe --tags)" '{title: $t, html: $html}')"

Supporting pages go up through POST /api/v1/reports/$REPORT_ID/assets as base64. See the API reference and publishing from CI.

PATCHing one saved id keeps a permanent URL whose content tracks the current tag, and the revision history is an honest answer to "when did that signature change?"

Review the doc comments, not the diff

Doc comments get reviewed in the worst possible place: inline in a PR, where the reviewer sees the comment and not the rendered page it becomes. Publishing the rendered docs and commenting there — "this says what it does, not when it returns an error" — puts the feedback where the reader's experience actually is. Threads stay anchored across rebuilds. See commenting on HTML.

Limits

  • Entry HTML: 5 MB. Assets: 25 MB per file, 250 MB and 500 files total. A mirror of a large module tree can pass 500 files — mirror the package subtree people actually consume, not the whole repo.
  • Scripts run, sandboxed — no same-origin access.
  • 60 requests/minute per token.

Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision history.

Publish Go docs →

Related