* docs: design spec for Dokka HTML API reference on GitHub Pages (#32) * docs: implementation plan for Dokka API reference on GitHub Pages (#32) * build: migrate Dokka 1.9.20 -> 2.2.0 (DGP v2) (#32) * docs: aggregate all modules into one Dokka HTML site with source links (#32) * docs: add Dokka source links to serialization/coroutines/compose modules (#32) * ci: add docs workflow to deploy Dokka HTML to GitHub Pages (#32) * docs: link the published API reference from the README (#32)
16 KiB
API Reference (Dokka HTML) on GitHub Pages — Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Migrate Dokka to 2.x and publish an aggregated, source-linked multi-module API reference for all four modules to GitHub Pages on each release and on demand.
Architecture: Bump Dokka 1.9.20 → 2.2.0 and switch on the Dokka Gradle Plugin v2 (V2Enabled). The root project (the published core module) aggregates the three submodules via dokka(project(...)) dependencies, producing one HTML site at build/dokka/html. A new docs.yml workflow builds that site and deploys it with the official GitHub Pages Actions. The vanniktech maven-publish plugin (0.34.0) keeps building the Maven Central -javadoc.jar — it already supports Dokka V2, so the release pipeline is unaffected.
Tech Stack: Kotlin Multiplatform 2.1.0, Gradle 8.5, Dokka Gradle Plugin 2.2.0, vanniktech maven-publish 0.34.0, GitHub Actions (upload-pages-artifact@v3, deploy-pages@v4).
Spec: docs/superpowers/specs/2026-06-07-publish-api-reference-dokka-github-pages-design.md
Note on "tests": This is build/CI work, so each task's verification is a Gradle command or a YAML lint with a concrete expected result rather than a unit test. Treat the "verify" steps as the failing/passing check.
File Structure
| File | Responsibility | Action |
|---|---|---|
gradle/libs.versions.toml |
Centralized Dokka version | Modify (dokka = "2.2.0") |
gradle.properties |
Enable DGP v2 plugin mode | Modify (add 2 flags) |
build.gradle.kts (root) |
Aggregate 3 submodules; root site title + source links | Modify (add dependencies + dokka {} blocks) |
tree-structure-serialization/build.gradle.kts |
Source links for this module | Modify (add dokka {} block) |
tree-structure-coroutines/build.gradle.kts |
Source links for this module | Modify (add dokka {} block) |
tree-structure-compose/build.gradle.kts |
Source links for this module | Modify (add dokka {} block) |
.github/workflows/docs.yml |
Build + deploy site to Pages | Create |
README.md |
Docs badge + link | Modify |
Work happens on branch docs/api-reference-github-pages (already created; spec already committed there).
Task 1: Migrate Dokka to 2.2.0 and enable DGP v2
Files:
-
Modify:
gradle/libs.versions.toml(linedokka = "1.9.20") -
Modify:
gradle.properties -
Step 1: Bump the Dokka version in the catalog
In gradle/libs.versions.toml, change the dokka version under [versions]:
dokka = "2.2.0"
(Leave the dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" } plugin line unchanged.)
- Step 2: Enable the Dokka Gradle Plugin v2
Append these two lines to gradle.properties (current content is only kotlin.code.style=official):
# Dokka Gradle Plugin v2 (https://kotl.in/dokka-gradle-migration)
org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled
org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true
- Step 3: Verify the v2 task exists and there is no V1 warning
Run: ./gradlew :dokkaGeneratePublicationHtml --dry-run --console=plain
Expected: BUILD SUCCESSFUL, a list of :dokkaGenerate* tasks printed, and no message containing Dokka Gradle plugin V1 or migration guide. (At this point only the root/core module is documented — aggregation is added in Task 2.)
- Step 4: Verify the Maven Central javadoc jar still builds under Dokka 2.x
Run: ./gradlew javadocJar --console=plain
Expected: BUILD SUCCESSFUL. This is the vanniktech-generated jar that Maven Central requires; it must keep working. (If the task name isn't found, list it with ./gradlew tasks --all | grep -i javadoc and run the reported task — it is the per-module javadocJar.)
- Step 5: Commit
git add gradle/libs.versions.toml gradle.properties
git commit -m "build: migrate Dokka 1.9.20 -> 2.2.0 (DGP v2) (#32)"
Task 2: Aggregate all modules + root site title and source links
Files:
-
Modify:
build.gradle.kts(root) -
Step 1: Add the Dokka aggregation dependencies
Add this top-level block to the root build.gradle.kts (place it after the repositories { mavenCentral() } block, at the top level — not inside kotlin {}):
dependencies {
dokka(project(":tree-structure-serialization"))
dokka(project(":tree-structure-coroutines"))
dokka(project(":tree-structure-compose"))
}
- Step 2: Add the root
dokka {}configuration (site title + source links)
Add this top-level block to the root build.gradle.kts (e.g. right after the dependencies {} block from Step 1):
dokka {
moduleName.set("Tree Data Structure")
dokkaSourceSets.configureEach {
sourceLink {
localDirectory.set(projectDir.resolve("src"))
val module = projectDir.relativeTo(rootDir).invariantSeparatorsPath
val prefix = if (module.isEmpty()) "" else "$module/"
remoteUrl("https://github.com/AdrianKuta/Tree-Data-Structure/blob/master/${prefix}src")
remoteLineSuffix.set("#L")
}
}
}
- Step 3: Build the aggregated site
Run: ./gradlew :dokkaGeneratePublicationHtml --console=plain
Expected: BUILD SUCCESSFUL and the file build/dokka/html/index.html exists.
Run: ls build/dokka/html
Expected: per-module output directories including tree-structure, tree-structure-serialization, tree-structure-coroutines, and tree-structure-compose (plus index.html, navigation.html, assets).
- Step 4: Verify the four modules and root source links are present
Run: grep -roh "tree-structure-serialization\|tree-structure-coroutines\|tree-structure-compose" build/dokka/html/index.html | sort -u
Expected: all three submodule names listed (confirming aggregation).
Run: grep -rl "github.com/AdrianKuta/Tree-Data-Structure/blob/master/src/" build/dokka/html/tree-structure | head -1
Expected: at least one file path printed (confirming the root/core module's source links resolve to .../blob/master/src/...). Optionally open build/dokka/html/index.html in a browser and click a core class's "source" link to confirm it lands on the right GitHub file.
- Step 5: Commit
git add build.gradle.kts
git commit -m "docs: aggregate all modules into one Dokka HTML site with source links (#32)"
Task 3: Source links for the three submodules
The submodules are documented by the aggregation but need their own sourceLink so their symbols point at the correct subdirectory on GitHub. The block below is path-derived and identical for every module — add the exact same block to all three files.
Files:
-
Modify:
tree-structure-serialization/build.gradle.kts -
Modify:
tree-structure-coroutines/build.gradle.kts -
Modify:
tree-structure-compose/build.gradle.kts -
Step 1: Add the
dokka {}block totree-structure-serialization/build.gradle.kts
Add this top-level block (after the repositories {} block, before kotlin {}):
dokka {
dokkaSourceSets.configureEach {
sourceLink {
localDirectory.set(projectDir.resolve("src"))
val module = projectDir.relativeTo(rootDir).invariantSeparatorsPath
val prefix = if (module.isEmpty()) "" else "$module/"
remoteUrl("https://github.com/AdrianKuta/Tree-Data-Structure/blob/master/${prefix}src")
remoteLineSuffix.set("#L")
}
}
}
- Step 2: Add the same block to
tree-structure-coroutines/build.gradle.kts
Add the identical block (after repositories {}, before kotlin {}):
dokka {
dokkaSourceSets.configureEach {
sourceLink {
localDirectory.set(projectDir.resolve("src"))
val module = projectDir.relativeTo(rootDir).invariantSeparatorsPath
val prefix = if (module.isEmpty()) "" else "$module/"
remoteUrl("https://github.com/AdrianKuta/Tree-Data-Structure/blob/master/${prefix}src")
remoteLineSuffix.set("#L")
}
}
}
- Step 3: Add the same block to
tree-structure-compose/build.gradle.kts
Add the identical block (after the repositories { mavenCentral(); google() } block, before kotlin {}):
dokka {
dokkaSourceSets.configureEach {
sourceLink {
localDirectory.set(projectDir.resolve("src"))
val module = projectDir.relativeTo(rootDir).invariantSeparatorsPath
val prefix = if (module.isEmpty()) "" else "$module/"
remoteUrl("https://github.com/AdrianKuta/Tree-Data-Structure/blob/master/${prefix}src")
remoteLineSuffix.set("#L")
}
}
}
- Step 4: Rebuild the site
Run: ./gradlew :dokkaGeneratePublicationHtml --console=plain
Expected: BUILD SUCCESSFUL.
- Step 5: Verify each submodule's source links resolve to its subdirectory
Run:
for m in serialization coroutines compose; do
echo -n "tree-structure-$m: "
grep -rl "github.com/AdrianKuta/Tree-Data-Structure/blob/master/tree-structure-$m/src/" build/dokka/html/tree-structure-$m | head -1 || echo "MISSING"
done
Expected: a file path printed for each of the three modules (none "MISSING").
- Step 6: Commit
git add tree-structure-serialization/build.gradle.kts tree-structure-coroutines/build.gradle.kts tree-structure-compose/build.gradle.kts
git commit -m "docs: add Dokka source links to serialization/coroutines/compose modules (#32)"
Task 4: GitHub Pages workflow
Files:
-
Create:
.github/workflows/docs.yml -
Step 1: Create the workflow file
Create .github/workflows/docs.yml with exactly:
name: Docs
on:
release:
types: [released]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: false
jobs:
build:
name: Build Dokka HTML
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '21'
- name: Generate API docs
run: ./gradlew :dokkaGeneratePublicationHtml --console=plain
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v3
with:
path: build/dokka/html
deploy:
name: Deploy to GitHub Pages
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy
id: deployment
uses: actions/deploy-pages@v4
- Step 2: Validate the YAML is well-formed
Run: ruby -ryaml -e "YAML.load_file('.github/workflows/docs.yml'); puts 'OK'"
Expected: prints OK with no error. (Ruby ships with macOS. Alternatively, if actionlint is installed: actionlint .github/workflows/docs.yml → no output.)
- Step 3: Commit
git add .github/workflows/docs.yml
git commit -m "ci: add docs workflow to deploy Dokka HTML to GitHub Pages (#32)"
Task 5: Link the site from the README
Files:
-
Modify:
README.md(top badge block, lines 1-6) -
Step 1: Add the API docs badge
In README.md, immediately after the existing Publish badge line:
[](https://github.com/AdrianKuta/Tree-Data-Structure/actions/workflows/publishRelease.yml)
add this new line:
[](https://adriankuta.github.io/Tree-Data-Structure/)
- Step 2: Add a one-line pointer under the badges
After the badge block and its following blank line, and before the intro paragraph that starts A lightweight n-ary tree for Kotlin Multiplatform., insert:
📖 **[API reference](https://adriankuta.github.io/Tree-Data-Structure/)** — full KDoc for the core and all modules.
- Step 3: Verify the link is present
Run: grep -n "adriankuta.github.io/Tree-Data-Structure" README.md
Expected: two matches (the badge and the 📖 line).
- Step 4: Commit
git add README.md
git commit -m "docs: link the published API reference from the README (#32)"
Task 6: Full verification, push, and pull request
Files: none (verification + integration)
- Step 1: Full local verification
Run each and confirm BUILD SUCCESSFUL:
./gradlew :dokkaGeneratePublicationHtml --console=plain # site builds, all 4 modules
./gradlew javadocJar --console=plain # release javadoc jar intact
./gradlew apiCheck --console=plain # binary-compat baseline unchanged
Expected: all three succeed. apiCheck must pass with no diff — this change touches only build config and docs, not public API. Optionally open build/dokka/html/index.html in a browser for a final visual check (module nav + a couple of source links).
- Step 2: Push the branch
git push -u origin docs/api-reference-github-pages
- Step 3: Open the pull request
gh pr create --base master --head docs/api-reference-github-pages \
--title "Publish API reference (Dokka HTML) to GitHub Pages (#32)" \
--body "$(cat <<'EOF'
Closes #32.
Migrates Dokka 1.9.20 → 2.2.0 (DGP v2) and publishes an aggregated, source-linked
multi-module API reference to GitHub Pages.
## What changed
- **Dokka 2.2.0 / DGP v2** (`V2Enabled` in `gradle.properties`). Gradle 8.5 and Kotlin
2.1.0 already satisfy Dokka 2.2.0's minimums (7.6+ / 1.9+), so no wrapper/Kotlin bump.
- **Aggregation**: the root (core) module pulls in `-serialization`, `-coroutines`, and
`-compose` via `dokka(project(...))` → one site at `build/dokka/html`
(`:dokkaGeneratePublicationHtml`).
- **Source links** on every module, pointing each symbol at its source on `master`.
- **`.github/workflows/docs.yml`**: builds the site and deploys via the official Pages
Actions on each release and on manual `workflow_dispatch`.
- **README**: docs badge + link to https://adriankuta.github.io/Tree-Data-Structure/
## Release pipeline unaffected
vanniktech 0.34.0 already supports Dokka `V2Enabled`, so the Maven Central
`-javadoc.jar` keeps building (verified locally with `./gradlew javadocJar`).
## ⚠️ One-time manual step required before the site goes live
Enable Pages: **Settings → Pages → Source = "GitHub Actions"**. Until then the
`deploy` job will fail. After enabling, run the **Docs** workflow once via
*Actions → Docs → Run workflow* (`workflow_dispatch`) to publish without waiting for a
release.
EOF
)"
Expected: PR URL printed.
- Step 4: Post-merge manual steps (call these out to the repo owner)
- Settings → Pages → Source = "GitHub Actions" (one-time; otherwise
deployfails). - Trigger Actions → Docs → Run workflow (
workflow_dispatch) to publish immediately. - Confirm the site is live at https://adriankuta.github.io/Tree-Data-Structure/ and the module nav + source links work.
Self-Review
Spec coverage:
- Dokka 1.9.20 → 2.2.0 + V2 mode → Task 1 ✓
- Multi-module aggregation in root → Task 2 ✓
- Source links (root + 3 submodules) + site title → Tasks 2 & 3 ✓
docs.yml(release + workflow_dispatch, official Pages Actions) → Task 4 ✓- README badge + link → Task 5 ✓
- Verify javadoc jar / apiCheck / local docs build → Tasks 1, 2, 6 ✓
- Manual Pages-enable prerequisite → Tasks 4/6 PR body + post-merge steps ✓
- Out-of-scope items (versioned docs, Module.md, vanniktech swap, CI cache) → correctly excluded ✓
Placeholder scan: No TBD/TODO/"handle edge cases"/"similar to Task N". The identical source-link block is repeated in full in each of Task 3's steps (not referenced) ✓
Type/name consistency: Task name :dokkaGeneratePublicationHtml, output dir build/dokka/html, config functions (moduleName.set, dokkaSourceSets.configureEach, sourceLink { localDirectory.set / remoteUrl / remoteLineSuffix.set }), and dokka(project(...)) aggregation are used identically across Tasks 1–6 and the workflow ✓
Open risk carried from spec: if Dokka cannot resolve Apple source sets on ubuntu-latest in CI (Task 4), switch the build job's runs-on to macos-latest (mirrors the iOS test job). Local verification runs on macOS, which covers Apple source sets.