Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
2a18157
Publish project documentation from the projects' repositories
phillip-kruger Oct 14, 2026
d856636
Docs sync: refuse paths outside the docs, links that are not http(s),…
phillip-kruger Oct 15, 2026
700326b
Docs sync: keep every read inside the project's checkout
phillip-kruger Oct 15, 2026
b795bba
Move the Antora documentation (Fault Tolerance, Health, JWT, Metrics)…
phillip-kruger Oct 15, 2026
2bcad53
Publish the MkDocs projects' documentation (Config, Mutiny, Reactive …
phillip-kruger Oct 15, 2026
488f466
Add the tool that points a project's old mike site at smallrye.io
phillip-kruger Oct 15, 2026
f7cb149
Docs sync: project-version first, and the newest release for main
phillip-kruger Oct 15, 2026
5087261
Docs converters: fixes found while converting the projects' own sources
phillip-kruger Oct 15, 2026
b46c74e
Docs: take Reactive Messaging's dependency versions from its pom.xml
phillip-kruger Oct 15, 2026
f311c6e
Docs: card grids and button links, and Mutiny's home page cards back
phillip-kruger Oct 15, 2026
b009793
Docs: render Mermaid diagrams written as source blocks, resolve attri…
phillip-kruger Oct 15, 2026
714a375
Docs: project and version in the header, a sidebar that starts closed…
phillip-kruger Oct 15, 2026
1a52701
Docs: no visible title on a version's start page, the header names th…
phillip-kruger Oct 15, 2026
42065c6
Docs: diagrams stay readable in dark mode (light paper behind block i…
phillip-kruger Oct 15, 2026
af93c0c
Docs tools in Java (JBang) instead of Python, and a preview for projects
phillip-kruger Oct 15, 2026
cd556c5
Docs: code, tables, diagrams and cards use the whole column; cards in…
phillip-kruger Oct 15, 2026
3de56fa
Docs: a version's start page lists its documentation, from the naviga…
phillip-kruger Oct 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
32 changes: 9 additions & 23 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ on:
- 'NOTICE'
- 'README*'
# Daily, so a post dated later than the merge publishes on its date
# (future-dated posts are left out until then), and the docs pick up new releases.
# (future-dated posts are left out until then).
schedule:
- cron: "0 6 * * *"
workflow_dispatch:
Expand All @@ -34,33 +34,13 @@ jobs:
build:
runs-on: ubuntu-latest

services:
kroki:
image: yuzutech/kroki
env:
KROKI_MERMAID_HOST: kroki-mermaid
ports:
- 8000:8000
kroki-mermaid:
image: yuzutech/kroki-mermaid

steps:
- name: checkout
uses: actions/checkout@v4
with:
# The sitemap plugin reads each page's last change from git history.
fetch-depth: 0

# Before the site: the Roq build leaves a node_modules/ in the repository root, and
# npm would install Antora there instead of in docs/.
- name: generate docs
run: |
cd docs
# asciidoctor-kroki must stay on 0.18.1: since 1.0.0, its extensions are
# async and require Asciidoctor.js 4, while Antora 2.3 uses Asciidoctor.js 1.5.9
npm i @antora/cli@2.3 @antora/site-generator-default@2.3 asciidoctor-kroki@0.18.1
./node_modules/@antora/cli/bin/antora --stacktrace generate antora-playbook.yml

- name: generate website
uses: quarkiverse/quarkus-roq@v1.1
with:
Expand All @@ -72,8 +52,14 @@ jobs:
- name: put the stylesheet in the pages
run: java .github/InlineStyles.java target/roq

- name: add docs to the website
run: cp -r docs/build/site target/roq/docs
# GitHub Pages cannot redirect: the documentation addresses this site published before
# (Antora's /docs/<project>/<release>/<page>.html) get small redirect pages.
- uses: jbangdev/setup-jbang@2b1b465a7b75f4222b81426f23a01e013aa7b95c # v0.1.1
with:
version: 0.138.0

- name: add redirects for moved documentation
run: jbang tools/docs/Docs.java redirects target/roq

- name: attach website
uses: actions/upload-artifact@v4
Expand Down
88 changes: 88 additions & 0 deletions .github/workflows/docs-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: Check project documentation

# Reusable: a SmallRye project calls this on pull requests that touch its docs. It renders the
# pull request's AsciiDoc with the smallrye.io site exactly as it will be published, fails on a
# missing include or a page that does not render, and attaches the rendered docs as an artifact.
#
# jobs:
# docs:
# uses: smallrye/smallrye.github.io/.github/workflows/docs-check.yml@develop
# with:
# project: smallrye-graphql # the key in smallrye.github.io data/docs.yml

on:
workflow_call:
inputs:
project:
description: 'Project key in data/docs.yml'
type: string
required: true

# It renders pull-request content: read-only, no secrets.
permissions:
contents: read

jobs:
check:
runs-on: ubuntu-latest
# Diagram blocks ([mermaid], [plantuml], ...) are rendered to SVG by the sync (tools/docs/Docs.java).
services:
kroki:
image: yuzutech/kroki
env:
KROKI_MERMAID_HOST: kroki-mermaid
ports:
- 8000:8000
kroki-mermaid:
image: yuzutech/kroki-mermaid
env:
KROKI_URL: http://localhost:8000
steps:
- name: checkout the project
uses: actions/checkout@v4
with:
path: project

- name: checkout smallrye.io
uses: actions/checkout@v4
with:
repository: smallrye/smallrye.github.io
ref: develop
path: site

- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 21
cache: maven
cache-dependency-path: site/pom.xml

- uses: jbangdev/setup-jbang@2b1b465a7b75f4222b81426f23a01e013aa7b95c # v0.1.1
with:
version: 0.138.0

- name: copy the docs into the site
env:
PROJECT: ${{ inputs.project }}
run: jbang site/tools/docs/Docs.java sync --strict --project "$PROJECT" --version main --source project

- name: render the site
working-directory: site
env:
QUARKUS_ROQ_GENERATOR_BATCH: 'true'
run: |
./mvnw -B -q package quarkus:run -DskipTests 2>&1 | tee ../render.log
# Asciidoctor warnings (such as a section level out of sequence) are reported; a page that
# fails to render, or an include that cannot be resolved, fails the check.
grep -E 'WARNING \[asciidoctor\]' ../render.log | sed 's/^.*WARNING \[asciidoctor\] ([^)]*) /::warning::/' || true
if grep -E 'Roq request failed|Error occurred while rendering|SEVERE \[asciidoctor\]' ../render.log; then
echo "::error::The documentation does not render cleanly, see the lines above"
exit 1
fi

- name: attach the rendered docs
uses: actions/upload-artifact@v4
with:
name: docs-${{ inputs.project }}
path: site/target/roq
retention-days: 7
101 changes: 101 additions & 0 deletions .github/workflows/docs-sync.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
name: Sync project documentation

# Pulls each project's AsciiDoc documentation (data/docs.yml) into content/docs/ and commits it to
# develop, which then builds and deploys the site. Nightly it picks up new commits on the projects'
# main branches and new release tags; it can also be run by hand for one project or one version.

on:
schedule:
- cron: "30 4 * * *"
workflow_dispatch:
inputs:
project:
description: 'Project key from data/docs.yml (empty: all projects)'
required: false
version:
description: 'Version id (main, latest, a stream id); with ref, syncs exactly that'
required: false
ref:
description: 'Branch or tag to sync the version from'
required: false
force:
description: 'Sync even when nothing changed upstream'
type: boolean
default: false

concurrency:
group: docs-sync
cancel-in-progress: false

jobs:
sync:
if: github.repository_owner == 'smallrye'
runs-on: ubuntu-latest
# Diagram blocks ([mermaid], [plantuml], ...) are rendered to SVG by the sync (tools/docs/Docs.java).
services:
kroki:
image: yuzutech/kroki
env:
KROKI_MERMAID_HOST: kroki-mermaid
ports:
- 8000:8000
kroki-mermaid:
image: yuzutech/kroki-mermaid
env:
KROKI_URL: http://localhost:8000
steps:
- uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ vars.CI_APP_ID }}
private-key: ${{ secrets.CI_APP_PRIVATE_KEY }}

- uses: actions/checkout@v4
with:
ref: develop
# A push made with the app token (not GITHUB_TOKEN) starts the website build.
token: ${{ steps.app-token.outputs.token }}

- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 21

- uses: jbangdev/setup-jbang@2b1b465a7b75f4222b81426f23a01e013aa7b95c # v0.1.1
with:
version: 0.138.0

# Releases still documented with MkDocs are converted with pandoc.
- name: install pandoc
run: sudo apt-get update -qq && sudo apt-get install -y -qq pandoc

- name: sync
env:
PROJECT: ${{ inputs.project }}
VERSION: ${{ inputs.version }}
REF: ${{ inputs.ref }}
FORCE: ${{ inputs.force }}
run: |
if [ -n "$VERSION" ] && [ -n "$REF" ]; then
args=(--project "$PROJECT" --version "$VERSION" --ref "$REF")
else
args=(--auto)
[ -n "$PROJECT" ] && args+=(--project "$PROJECT")
[ "$FORCE" = true ] && args+=(--force)
fi
jbang tools/docs/Docs.java sync "${args[@]}" --summary "$GITHUB_STEP_SUMMARY"

- name: commit
run: |
git add -A content/docs data/docversions.yml
if git diff --cached --quiet; then
echo "Documentation unchanged"
exit 0
fi
slug='${{ steps.app-token.outputs.app-slug }}'
git config user.name "$slug[bot]"
git config user.email "$(gh api "/users/$slug%5Bbot%5D" --jq .id)+$slug[bot]@users.noreply.github.com"
git commit -q -m "Sync project documentation"
git push origin develop
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ package-lock.json
.idea
.vscode
.quarkus
__pycache__/
65 changes: 57 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,71 @@ Add `content/posts/YYYY-MM-DD-name.adoc`. The header carries the post's details:
`:page-author:` is a key in `data/authors.yml`; add yourself there first. A post dated in the
future is published by the first build on or after that date (the workflow runs daily).

## Building the documentation
## Project documentation

The documentation at `/docs/` is built separately with Antora, from the repositories listed in
`docs/antora-playbook.yml`, and copied into the site by CI.
Each project keeps its documentation in its own repository, as AsciiDoc laid out like the
Quarkus guides (`docs/src/main/asciidoc/`: one page per `.adoc` file, `_nav.yml` for the sidebar,
`_attributes.adoc` for shared attributes, examples included from compiled sources). This site
pulls it in and publishes it at `/docs/<project>/<version>/`.

1. Install Antora. See [Antora installation](https://docs.antora.org/antora/2.3/install/install-antora/).
2. Go to the `docs` directory and run
| What | Where |
| --- | --- |
| The projects, their repositories and the versions followed | `data/docs.yml` |
| The synced pages, one directory per version | `content/docs/<project>/<version>/` |
| Synced versions, their refs and navigation (generated) | `data/docversions.yml` |
| The documentation layout and its sidebar | `templates/layouts/doc.html`, `templates/partials/docs-nav.html` |
| The `/docs/` hub | `content/docs/index.html` |
| Sync and conversion tools | `tools/docs/` |

The tools are one [JBang](https://www.jbang.dev) program, `tools/docs/Docs.java`: Java and JBang are
all they need (pandoc, or podman to run it in a container, only to convert releases still
documented with MkDocs).

`sync` copies a project's docs from a branch or tag (or a local checkout) into `content/docs/`.
The `Sync project documentation` workflow runs it nightly: each project's `main` branch becomes
`main`, and its newest release tag becomes `latest`; the commit to `develop` then deploys. A release
whose docs are still MkDocs or Antora is converted on the fly by `mkdocs2adoc` or `antora2adoc`,
which are also the tools to convert a project's sources once.

```bash
jbang tools/docs/Docs.java sync --auto # what the nightly job does
jbang tools/docs/Docs.java sync --project smallrye-graphql --version main --source ../smallrye-graphql
jbang tools/docs/Docs.java --help # every tool
```

### Previewing a project's documentation

In a project's checkout, `jbang docs-preview@smallrye/smallrye.github.io` (or `./mvnw -Pdocs-preview`
where the project has that profile) shows its documentation on a local smallrye.io at
`http://localhost:8080/docs/<project>/main/`, and publishes it again whenever a page or an included
example changes. It downloads this site's sources once a day; `--site ../smallrye.github.io` uses a
checkout instead, to try changes to the site itself.

Projects call `.github/workflows/docs-check.yml` from their pull requests: it renders their docs
with this site and fails on a broken include or a page that does not render.

Converting a project once (then commit the result in the project's repository):

```bash
jbang tools/docs/Docs.java mkdocs2adoc --mkdocs ../project/mkdocs.yml --out ../project/docs/src/main/asciidoc
jbang tools/docs/Docs.java antora2adoc --antora ../project/doc --out ../project/docs/src/main/asciidoc
```

Diagram blocks (`[mermaid]`, `[plantuml]`, ...) are rendered to SVG during the sync, by a Kroki
server (`KROKI_URL`, https://kroki.io by default; the workflows run their own).

antora generate antora-playbook.yml --fetch
### Old addresses

3. The HTML for the SmallRye documentation is now in `docs/build/site`.
The documentation addresses this site published before (Antora's
`/docs/<project>/<release>/<page>.html`) are listed under `legacy` in `data/docs.yml`. The build
writes a redirect page for each of them (`Docs.java redirects`), and
`Docs.java rewrite-links --check target/roq content/posts/*.adoc` points blog links at the new
addresses, checking every page and anchor against the generated site.

## Deployment

Pushing to `develop` runs `.github/workflows/build.yml`: it generates the site with the Roq
GitHub Action, builds the documentation with Antora, and pushes the result to the `main`
GitHub Action (project docs included), adds the redirects for old documentation addresses, and pushes the result to the `main`
branch, which GitHub Pages serves. Pull requests build the site without deploying it. The
workflow also runs daily and can be started by hand from the Actions tab.

Expand Down
19 changes: 18 additions & 1 deletion config/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,21 @@ quarkus.roq.generator.timeout=180
# the Jekyll site. The layouts print the title, so Asciidoctor must not repeat it: a key
# ending in "!" unsets the attribute (the value is ignored but cannot be empty).
quarkus.asciidoc.attributes."showtitle!"=unset
quarkus.asciidoc.attributes.idseparator=_
# Asciidoctor renders in SAFE mode, which keeps includes inside base_dir. The site root (rather
# than each page's directory) lets a docs page in a subdirectory include its version's
# _attributes.adoc and _examples/, while nothing outside the site can be included.
quarkus.asciidoc.base-dir=site
# "@" makes it a default a page can override: blog posts keep Jekyll's ids (_like_this), while
# project docs set Quarkus-style ids (like-this) in their _attributes.adoc.
quarkus.asciidoc.attributes.idseparator=_@

# Project documentation, pulled from each project's repository by tools/docs/sync.py into
# content/docs/<project>/<version>/ and published at /docs/<project>/<version>/<page>/.
site.collections.docs=true
site.collections.docs.layout=doc
site.collections.docs.link=/:path
# Docs are AsciiDoc: their {attribute} references are not Qute expressions.
site.escaped-pages=docs/*/**
# The docs templates walk data/docs.yml and data/docversions.yml, whose list items Qute can
# only type as Object; as on quarkus.io, check those expressions at render time instead.
quarkus.qute.type-check-excludes=java.lang.Object.*
2 changes: 1 addition & 1 deletion content/404.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@
# own grey screen instead of the site's.
link: /404.html
---
<p>The requested page could not be found. Try the <a href="{=site.url}">home page</a>, the <a href="{=site.url('projects')}">project list</a> or the <a href="{=site.url('docs/index.html')}">documentation</a>.</p>
<p>The requested page could not be found. Try the <a href="{=site.url}">home page</a>, the <a href="{=site.url('projects')}">project list</a> or the <a href="{=site.url('docs/')}">documentation</a>.</p>
31 changes: 31 additions & 0 deletions content/docs/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
layout: page
title: Documentation
description: Documentation for every SmallRye project, from the latest release back to the main branch.
eyebrow: SmallRye
link: /docs/
---
{@io.quarkiverse.roq.frontmatter.runtime.model.Site site}
{! The projects and their documentation versions come from data/docs.yml and data/docversions.yml. !}
{#for g in cdi:docs.getJsonArray('groups')}
<h2>{=g.getString('name')}</h2>
<ul class="docs-hub">
{#for p in cdi:docs.getJsonArray('projects')}{#if p.getString('group') == g.getString('key')}
<li>
{#if p.containsKey('path') && cdi:docversions.containsKey(p.getString('key'))}
{#let versions=cdi:docversions.getJsonObject(p.getString('key')).getJsonArray('versions')}
<h3><a href="{=site.url('docs/' + p.getString('key') + '/' + versions.getJsonObject(0).getString('id') + '/')}">{=p.getString('name')}</a></h3>
<p>{=p.getString('description')}</p>
<p class="docs-hub-versions">
{#for v in versions}<a href="{=site.url('docs/' + p.getString('key') + '/' + v.getString('id') + '/')}">{#if v.getString('id') == 'latest'}{=v.getString('ref')}{#else if v.getString('id') == 'main'}main{#else}{=v.getString('ref')}{/if}</a>{#if !v_isLast} &middot; {/if}{/for}
{#if p.containsKey('archive')} &middot; <a href="{=p.getString('archive')}">older versions</a>{/if}
</p>
{/let}
{#else}
<h3><a href="{=p.getString('url')}">{=p.getString('name')}</a></h3>
<p>{=p.getString('description')}</p>
{/if}
</li>
{/if}{/for}
</ul>
{/for}
Loading
Loading