Share a DocC archive
DocC produces genuinely good documentation — symbol pages, tutorials,
articles, all generated from the source of truth. Then it hands you a
.doccarchive, which is an Xcode artifact, and the handoff falls apart the
moment the reader is a backend engineer, a partner, or anyone on a machine
without Xcode installed.
Zipping it does not help. Unzipped, index.html opens to a blank page: the
DocC renderer is a JavaScript app that fetches its content as JSON, and a
browser blocks that fetch from a file:// origin. The docs are all there. The
page just never asks for them successfully.
Build the static-hosting output
One flag changes the shape of the output from "Xcode bundle" to "folder of files a browser can serve":
swift package --allow-writing-to-directory ./docs \
generate-documentation --target MyKit \
--transform-for-static-hosting \
--output-path ./docs
For an Xcode project:
xcodebuild docbuild -scheme MyKit -derivedDataPath ./dd
xcrun docc process-archive transform-for-static-hosting \
./dd/Build/Products/Debug-iphoneos/MyKit.doccarchive \
--output-path ./docs
docs/
├── index.html
├── documentation/ # per-symbol pages
├── data/ # the JSON the renderer fetches
├── css/ js/ images/
└── metadata.json
Drop the folder in
Drag docs/ (or a zip of it) into Comma:
index.htmlbecomes the report body.data/,js/,css/and every symbol page upload alongside it, with relative references rewritten to the uploaded copies — which is the step that fixes the blank page, because the JSON now resolves overhttps://.- Scripts run inside a sandboxed iframe (
allow-scripts, noallow-same-origin), so the renderer boots, the sidebar tree works, and in-page search runs.
No bucket, no Pages workflow, no server-side rewrite rules to get right.
From the release job
swift package --allow-writing-to-directory ./docs \
generate-documentation --target MyKit --transform-for-static-hosting --output-path ./docs
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 docs/index.html \
--arg t "MyKit — $VERSION" '{title: $t, html: $html}')"
Supporting files go up through POST /api/v1/reports/$REPORT_ID/assets as
base64 — one call per file, worth scripting once. See the
API reference and publishing from CI.
Doc review that lands on the symbol
"This doesn't say whether it can throw" is worth something attached to the initializer and nothing at all in a channel. Threads anchor to the rendered content and survive rebuilds, so the list of places where the types are self-explanatory and the behaviour is not stays attached to the docs. See commenting on HTML.
Limits
- Entry HTML: 5 MB. Assets: 25 MB per file, 250 MB and 500 files total.
A large framework's
data/tree can exceed 500 files — narrow to the public target, or publish one module per report. - Scripts run, sandboxed — no same-origin access.
- 60 requests/minute per token.
Try it
Comma is free — unlimited reports, unlimited commenters, unlimited revision history.