diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..2a0607f --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,46 @@ +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 diff --git a/README.md b/README.md index d137452..bdbc272 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,9 @@ [![maven](https://img.shields.io/maven-central/v/com.github.adriankuta/tree-structure?style=plastic)](https://mvnrepository.com/artifact/com.github.adriankuta/tree-structure) [![License: MIT](https://img.shields.io/github/license/AdrianKuta/Tree-Data-Structure?style=plastic)](https://github.com/AdrianKuta/Tree-Data-Structure/blob/master/LICENSE) [![Publish](https://github.com/AdrianKuta/Tree-Data-Structure/actions/workflows/publishRelease.yml/badge.svg)](https://github.com/AdrianKuta/Tree-Data-Structure/actions/workflows/publishRelease.yml) +[![API docs](https://img.shields.io/badge/docs-API%20reference-blue?style=plastic)](https://adriankuta.github.io/Tree-Data-Structure/) + +📖 **[API reference](https://adriankuta.github.io/Tree-Data-Structure/)** — full KDoc for the core and all modules. A lightweight n-ary tree for Kotlin Multiplatform. You get a generic `TreeNode`, a small DSL for building trees, three traversal orders, lazy `Sequence` traversal, and a set of navigation and diff --git a/build.gradle.kts b/build.gradle.kts index 0a53aa1..66ac2e4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -59,6 +59,29 @@ repositories { mavenCentral() } +dependencies { + // Include this module's own docs in the aggregation — DGP v2 requires the + // aggregating project to list itself explicitly. + dokka(project(":")) + dokka(project(":tree-structure-serialization")) + dokka(project(":tree-structure-coroutines")) + dokka(project(":tree-structure-compose")) +} + +dokka { + moduleName.set("Tree Data Structure") + dokkaSourceSets.configureEach { + sourceLink { + localDirectory.set(projectDir.resolve("src")) + // For the root project projectDir == rootDir, so `module` is "" and links resolve to /blob/master/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") + } + } +} + kotlin { explicitApi() jvmToolchain(21) diff --git a/docs/superpowers/plans/2026-06-07-api-reference-github-pages.md b/docs/superpowers/plans/2026-06-07-api-reference-github-pages.md new file mode 100644 index 0000000..9d9db45 --- /dev/null +++ b/docs/superpowers/plans/2026-06-07-api-reference-github-pages.md @@ -0,0 +1,435 @@ +# 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` (line `dokka = "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]`: + +```toml +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`): + +```properties +# 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** + +```bash +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 {}`): + +```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): + +```kotlin +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** + +```bash +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 to `tree-structure-serialization/build.gradle.kts`** + +Add this top-level block (after the `repositories {}` block, before `kotlin {}`): + +```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 {}`): + +```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 {}`): + +```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: +```bash +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** + +```bash +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: + +```yaml +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** + +```bash +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: + +```markdown +[![Publish](https://github.com/AdrianKuta/Tree-Data-Structure/actions/workflows/publishRelease.yml/badge.svg)](https://github.com/AdrianKuta/Tree-Data-Structure/actions/workflows/publishRelease.yml) +``` + +add this new line: + +```markdown +[![API docs](https://img.shields.io/badge/docs-API%20reference-blue?style=plastic)](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: + +```markdown +📖 **[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** + +```bash +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`: + +```bash +./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** + +```bash +git push -u origin docs/api-reference-github-pages +``` + +- [ ] **Step 3: Open the pull request** + +```bash +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)** + +1. **Settings → Pages → Source = "GitHub Actions"** (one-time; otherwise `deploy` fails). +2. Trigger **Actions → Docs → Run workflow** (`workflow_dispatch`) to publish immediately. +3. 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. diff --git a/docs/superpowers/specs/2026-06-07-publish-api-reference-dokka-github-pages-design.md b/docs/superpowers/specs/2026-06-07-publish-api-reference-dokka-github-pages-design.md new file mode 100644 index 0000000..2c6ee78 --- /dev/null +++ b/docs/superpowers/specs/2026-06-07-publish-api-reference-dokka-github-pages-design.md @@ -0,0 +1,237 @@ +# Design: Publish API reference (Dokka HTML) to GitHub Pages + +- **Issue:** [#32](https://github.com/AdrianKuta/Tree-Data-Structure/issues/32) — *Publish API reference (Dokka HTML) to GitHub Pages* +- **Date:** 2026-06-07 +- **Status:** Approved (design); pending spec review + +## Summary + +Generate a browsable, multi-module API reference with Dokka and host it on GitHub +Pages. The site aggregates the core (`tree-structure`) plus the `-serialization`, +`-coroutines`, and `-compose` modules, links every symbol back to its source on +GitHub, and is (re)deployed on each GitHub release or on demand. The README points +to it. + +## Background / current state + +- **Dokka 1.9.20** is applied to all four modules (root core + three submodules) via + `alias(libs.plugins.dokka)`. Today it runs only because the **vanniktech + maven-publish plugin (0.34.0)** uses it to build the `-javadoc.jar` that Maven + Central requires. There is no aggregation config, no docs site, no source links. +- Plugin/library versions are centralized in `gradle/libs.versions.toml`. +- The **root project is itself the published core module** and the natural Dokka + aggregation root. +- Existing workflows: `test.yml` (reusable matrix: JVM/JS/Wasm/Native + `apiCheck`, + plus iOS on macOS) and `publishRelease.yml` (on GitHub release → tests → + `./gradlew publishToMavenCentral`). Both use `actions/checkout@v4` + + `actions/setup-java@v4` (temurin, JDK 21) with no Gradle cache action. +- Gradle wrapper **8.5**; Kotlin **2.1.0**. + +### Verified compatibility (de-risking) + +- **Dokka 2.2.0** (latest stable) requires **Gradle 7.6+** and **Kotlin 1.9+** → our + 8.5 / 2.1.0 satisfy both. **No wrapper bump, no Kotlin bump.** +- **vanniktech 0.34.0** already supports Dokka `V2Enabled` (added in 0.30.0), so the + Maven Central `-javadoc.jar` keeps building under Dokka 2.x. **No vanniktech bump.** + (For reference, 0.36.0 *removes* Dokka v1 support entirely — so V2 is the forward + direction regardless.) + +## Goals + +1. Migrate Dokka `1.9.20` → `2.2.0` (DGP v2 / `V2Enabled`) without breaking the + release pipeline's javadoc jar. +2. Produce one aggregated multi-module HTML site for all four modules. +3. Link every documented symbol to its source on GitHub. +4. Deploy the site to GitHub Pages on each release and on manual dispatch. +5. Link the site from the README. + +## Non-goals (per the issue's "follow-up" note) + +- Versioned / per-release docs (one published version at a time, tracking the latest + release / manual run). +- Long-form `Module.md` package descriptions. +- Changing the publishing tool (vanniktech stays; out of scope for #32). +- Adding a Gradle cache action to CI (keep parity with existing workflows). + +## Detailed design + +### 1. Dokka 2.x migration + +**`gradle/libs.versions.toml`** + +```toml +dokka = "2.2.0" # was 1.9.20 +``` + +**`gradle.properties`** — enable DGP v2 and silence the migration notice: + +```properties +org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled +org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true +``` + +The four `alias(libs.plugins.dokka)` plugin applications stay unchanged. + +### 2. Multi-module aggregation (root `build.gradle.kts`) + +Add a top-level `dependencies { }` block declaring the three submodules as Dokka +aggregation inputs. The root documents itself and pulls in the three: + +```kotlin +dependencies { + dokka(project(":tree-structure-serialization")) + dokka(project(":tree-structure-coroutines")) + dokka(project(":tree-structure-compose")) +} +``` + +- Generating task: **`:dokkaGeneratePublicationHtml`** (root project). +- Output directory: **`build/dokka/html`** (the aggregated site, default location). + +### 3. Source links + site title + +A `dokka { }` block is added to **each of the four module build files**. The +`sourceLink` derives the per-module GitHub path from the project layout so each +module is correct without hardcoding paths: + +```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") + } + } +} +``` + +- For the **root** module, `module` is empty → links resolve to `…/blob/master/src/…`. +- For a submodule (e.g. serialization) → `…/blob/master/tree-structure-serialization/src/…`. +- Links point at the **`master`** branch. Trade-off: a previously deployed page links + to current `master`, which may have drifted. Accepted for simplicity; tag-accurate + links are a possible follow-up. + +The **root** module additionally sets a friendly site title: + +```kotlin +dokka { + moduleName.set("Tree Data Structure") + // ...sourceLink block as above... +} +``` + +Submodules keep their default module names (`tree-structure-serialization`, +`tree-structure-coroutines`, `tree-structure-compose`). + +### 4. Pages workflow — `.github/workflows/docs.yml` + +```yaml +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 +``` + +- Triggers: `release: [released]` (matches the issue) **+** `workflow_dispatch` + (manual rebuild without a release). +- Official GitHub Pages Actions (no `gh-pages` branch). +- Runs on `ubuntu-latest` to match `publishRelease.yml`. **Fallback:** if Dokka + cannot resolve the Apple source sets on Linux CI, switch the `build` job to + `macos-latest` (as the iOS test job already does). + +### 5. README + +In the badge row near the top, add a docs badge and a one-line pointer: + +```markdown +[![API docs](https://img.shields.io/badge/docs-API%20reference-blue?style=plastic)](https://adriankuta.github.io/Tree-Data-Structure/) +``` + +Plus a short line under the badges: + +```markdown +📖 **[API reference](https://adriankuta.github.io/Tree-Data-Structure/)** — full KDoc for all modules. +``` + +Site URL: `https://adriankuta.github.io/Tree-Data-Structure/`. + +### 6. One-time manual step (repo owner, not code) + +GitHub Pages must be enabled once: **Settings → Pages → Source = "GitHub Actions"**. +Until then the `deploy` job fails. This will be called out in the PR / final summary. + +## Verification (before claiming done) + +1. `./gradlew :dokkaGeneratePublicationHtml --console=plain` locally on **macOS** + (covers Apple source sets) → confirm `build/dokka/html/index.html` exists and the + site lists **all four** modules, with working source links. +2. `./gradlew javadocJar --console=plain` → confirm the vanniktech javadoc jar(s) + still build under Dokka 2.x (release pipeline unaffected). Optionally + `./gradlew publishToMavenLocal -Psnapshot=true` for an end-to-end check. +3. `./gradlew apiCheck` and the existing test tasks still pass (no API/source impact). +4. Validate `docs.yml` YAML (well-formed, correct action versions). + +## Risks & mitigations + +| Risk | Mitigation | +| --- | --- | +| Dokka 2.x breaks the javadoc jar | vanniktech 0.34.0 supports `V2Enabled`; verify with `javadocJar` step 2 above. | +| Dokka can't resolve Apple source sets on Linux CI | Verify locally on macOS; fallback `macos-latest` for the build job. | +| Source-link paths wrong for a module | Derived from `projectDir.relativeTo(rootDir)`; visually verify links in step 1. | +| Pages deploy fails on first run | Documented manual prerequisite (Settings → Pages → GitHub Actions). | + +## Files touched + +- `gradle/libs.versions.toml` — Dokka version bump. +- `gradle.properties` — `V2Enabled` flags. +- `build.gradle.kts` (root) — aggregation `dependencies`, `dokka { moduleName + sourceLink }`. +- `tree-structure-serialization/build.gradle.kts` — `dokka { sourceLink }`. +- `tree-structure-coroutines/build.gradle.kts` — `dokka { sourceLink }`. +- `tree-structure-compose/build.gradle.kts` — `dokka { sourceLink }`. +- `.github/workflows/docs.yml` — new Pages workflow. +- `README.md` — docs badge + link. diff --git a/gradle.properties b/gradle.properties index 7fc6f1f..279da73 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1,4 @@ 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 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c60ae65..edfd871 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] kotlin = "2.1.0" -dokka = "1.9.20" +dokka = "2.2.0" mavenPublish = "0.34.0" binaryCompatibilityValidator = "0.16.3" kover = "0.8.3" diff --git a/tree-structure-compose/build.gradle.kts b/tree-structure-compose/build.gradle.kts index 817ee2b..9027215 100644 --- a/tree-structure-compose/build.gradle.kts +++ b/tree-structure-compose/build.gradle.kts @@ -49,6 +49,19 @@ repositories { google() } +dokka { + dokkaSourceSets.configureEach { + sourceLink { + // Resolve this module's GitHub source path relative to the repo root. + 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") + } + } +} + kotlin { explicitApi() jvmToolchain(21) diff --git a/tree-structure-coroutines/build.gradle.kts b/tree-structure-coroutines/build.gradle.kts index a5d8056..616b6c9 100644 --- a/tree-structure-coroutines/build.gradle.kts +++ b/tree-structure-coroutines/build.gradle.kts @@ -46,6 +46,19 @@ repositories { mavenCentral() } +dokka { + dokkaSourceSets.configureEach { + sourceLink { + // Resolve this module's GitHub source path relative to the repo root. + 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") + } + } +} + kotlin { explicitApi() jvmToolchain(21) diff --git a/tree-structure-serialization/build.gradle.kts b/tree-structure-serialization/build.gradle.kts index b1d250a..a778aa3 100644 --- a/tree-structure-serialization/build.gradle.kts +++ b/tree-structure-serialization/build.gradle.kts @@ -47,6 +47,19 @@ repositories { mavenCentral() } +dokka { + dokkaSourceSets.configureEach { + sourceLink { + // Resolve this module's GitHub source path relative to the repo root. + 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") + } + } +} + kotlin { explicitApi() jvmToolchain(21)