This is an automated email from the ASF dual-hosted git repository.

hansva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git


The following commit(s) were added to refs/heads/main by this push:
     new 5a8e12e417 Issue #8885 : Pin cross-manual xrefs and check them in the 
docs PR build (#8891)
5a8e12e417 is described below

commit 5a8e12e41714314c2577e4171111e4216b67db37
Author: Bart Maertens <[email protected]>
AuthorDate: Tue Oct 13 16:58:43 2026 +0200

    Issue #8885 : Pin cross-manual xrefs and check them in the docs PR build 
(#8891)
---
 .github/workflows/pr_build_docs.yml                | 36 +++++++++++++++++++++-
 .../ROOT/pages/annotation-derived-widgets.adoc     |  2 +-
 .../pages/architecture/logging-and-debugging.adoc  |  2 +-
 .../modules/ROOT/pages/database/index.adoc         |  2 +-
 .../modules/ROOT/pages/hopweb/index.adoc           |  2 +-
 docs/hop-dev-manual/modules/ROOT/pages/index.adoc  |  2 +-
 .../modules/ROOT/pages/plugin-types/gui.adoc       |  2 +-
 .../pages/plugin-types/metadata-configuration.adoc |  2 +-
 .../modules/ROOT/pages/writing-documentation.adoc  |  5 ++-
 .../ROOT/pages/installation-configuration.adoc     |  2 +-
 .../ROOT/pages/technology/openlineage/index.adoc   |  4 +--
 11 files changed, 49 insertions(+), 12 deletions(-)

diff --git a/.github/workflows/pr_build_docs.yml 
b/.github/workflows/pr_build_docs.yml
index b3c507f06d..874b53d972 100644
--- a/.github/workflows/pr_build_docs.yml
+++ b/.github/workflows/pr_build_docs.yml
@@ -25,7 +25,7 @@ on:
       - 'docs/**'
       - '.github/workflows/pr_build_docs.yml'
   pull_request:
-    branches: [ 'main' ]
+    branches: [ 'main', 'release/**' ]
     paths:
       - 'docs/**'
       - '.github/workflows/pr_build_docs.yml'
@@ -70,6 +70,25 @@ jobs:
         with:
           path: hop
 
+      # A reference to the other manual without a version goes to that manual's
+      # latest stable release on the website, but to this checkout in the build
+      # below, which only reads HEAD. A link to a page that is not released yet
+      # passes here and breaks the website build. Pin the version instead:
+      # xref:{page-component-version}@manual::page.adoc[]. This catches every
+      # resource ID with a component and no version: xref:, <<...>>, include::,
+      # image:: and attribute values alike.
+      - name: Check cross-manual references
+        working-directory: hop
+        run: |
+          components=$(sed -n 's/^name: *//p' docs/*/antora.yml | paste -sd'|')
+          if grep -rnE "(^|[^@A-Za-z0-9_.-])($components):[A-Za-z0-9_-]*:" 
docs \
+              --include='*.adoc' > "$RUNNER_TEMP/unversioned.txt"; then
+            while IFS=: read -r file line _; do
+              echo "::error file=$file,line=$line::Reference to another manual 
without a version. Prefix it with {page-component-version}@, for example 
xref:{page-component-version}@manual::page.adoc[]"
+            done < "$RUNNER_TEMP/unversioned.txt"
+            exit 1
+          fi
+
       - name: Check out the website build
         uses: actions/checkout@v7
         with:
@@ -108,6 +127,21 @@ jobs:
           npx antora --log-level=warn --log-failure-level=error 
--log-format=json \
             --to-dir "$GITHUB_WORKSPACE/site" antora-playbook-hop.yml 2>&1 | 
tee antora.log
 
+      # Antora does not check #fragments, and the website build runs a link
+      # checker over its output that does. Run the same checks here, over the
+      # manuals plus the Astro site pages they link to. npm run check:links is
+      # not used as is: it only checks the next/ manuals, and with HEAD alone
+      # the manuals are published as latest/. check:absolute is left out: the
+      # manuals link with relative URLs, and the site pages' links to 
/manual/next/
+      # cannot resolve in this build.
+      - name: Check links
+        working-directory: hop-website
+        run: |
+          npx astro build
+          cp -r "$GITHUB_WORKSPACE/site/." public/
+          npx link-checker public --disable-external --mkdocs 
--allow-hash-href \
+            --url-ignore '^/' --url-ignore '^file:'
+
       # Error annotations on the offending .adoc lines, a job summary and, for 
a
       # pull request, the body of the PR comment. The comment itself is posted
       # by pr_docs_comment.yml: this job runs with the read-only token of a
diff --git 
a/docs/hop-dev-manual/modules/ROOT/pages/annotation-derived-widgets.adoc 
b/docs/hop-dev-manual/modules/ROOT/pages/annotation-derived-widgets.adoc
index eda3e952b5..a20d494cca 100644
--- a/docs/hop-dev-manual/modules/ROOT/pages/annotation-derived-widgets.adoc
+++ b/docs/hop-dev-manual/modules/ROOT/pages/annotation-derived-widgets.adoc
@@ -68,7 +68,7 @@ public class DataSetOutputMeta extends 
BaseTransformMeta<DataSetOutput, DataSetO
 `id`::
 Stable name of this widget.
 Dialog code uses it to find the control, and a distribution can hide the 
widget by listing the id in `disabledGuiElements`.
-See xref:manual::hop-gui/disable-ui-elements.adoc[Disabling UI elements].
+See 
xref:{page-component-version}@manual::hop-gui/disable-ui-elements.adoc[Disabling
 UI elements].
 
 `order`::
 Sort key among the widgets in this parent, compared as a string.
diff --git 
a/docs/hop-dev-manual/modules/ROOT/pages/architecture/logging-and-debugging.adoc
 
b/docs/hop-dev-manual/modules/ROOT/pages/architecture/logging-and-debugging.adoc
index 1eb1a556bf..b85b7de7d7 100644
--- 
a/docs/hop-dev-manual/modules/ROOT/pages/architecture/logging-and-debugging.adoc
+++ 
b/docs/hop-dev-manual/modules/ROOT/pages/architecture/logging-and-debugging.adoc
@@ -47,7 +47,7 @@ String logText =
 ----
 
 The second argument clears the buffer as it is read.
-This is the same path a `logBasic()` call from a 
xref:manual::pipeline/transforms/userdefinedjavaclass.adoc[User Defined Java 
Class] takes: the transform's own channel, the same store.
+This is the same path a `logBasic()` call from a 
xref:{page-component-version}@manual::pipeline/transforms/userdefinedjavaclass.adoc[User
 Defined Java Class] takes: the transform's own channel, the same store.
 
 === SLF4J and the Log4j2 binding
 
diff --git a/docs/hop-dev-manual/modules/ROOT/pages/database/index.adoc 
b/docs/hop-dev-manual/modules/ROOT/pages/database/index.adoc
index 7157be2135..9ad6b60d92 100644
--- a/docs/hop-dev-manual/modules/ROOT/pages/database/index.adoc
+++ b/docs/hop-dev-manual/modules/ROOT/pages/database/index.adoc
@@ -22,7 +22,7 @@ A database plugin teaches Hop to speak to one database.
 Hop ships around fifty of them, and writing another is one of the more common 
reasons to extend Hop.
 
 This section is about writing one.
-For connecting to a database that already has a plugin, see the 
xref:manual::database/databases.adoc[database pages in the user manual] instead.
+For connecting to a database that already has a plugin, see the 
xref:{page-component-version}@manual::database/databases.adoc[database pages in 
the user manual] instead.
 
 == What a database plugin is made of
 
diff --git a/docs/hop-dev-manual/modules/ROOT/pages/hopweb/index.adoc 
b/docs/hop-dev-manual/modules/ROOT/pages/hopweb/index.adoc
index d7ffb5cc3f..0852517fbe 100644
--- a/docs/hop-dev-manual/modules/ROOT/pages/hopweb/index.adoc
+++ b/docs/hop-dev-manual/modules/ROOT/pages/hopweb/index.adoc
@@ -20,7 +20,7 @@ under the License.
 
 == Building or customizing Hop Web
 
-Hop Web is available as a basic Docker container image from Docker Hub. Check 
the xref:manual::hop-gui/hop-web.adoc[user manual for Hop Web] for more 
information.
+Hop Web is available as a basic Docker container image from Docker Hub. Check 
the xref:{page-component-version}@manual::hop-gui/hop-web.adoc[user manual for 
Hop Web] for more information.
 
 Follow the steps in this guid to learn how you can build your own Hop Web 
installation or docker image.
 
diff --git a/docs/hop-dev-manual/modules/ROOT/pages/index.adoc 
b/docs/hop-dev-manual/modules/ROOT/pages/index.adoc
index 24dec2044a..4c2908c68e 100644
--- a/docs/hop-dev-manual/modules/ROOT/pages/index.adoc
+++ b/docs/hop-dev-manual/modules/ROOT/pages/index.adoc
@@ -19,7 +19,7 @@ under the License.
 = Development documentation
 
 This manual is for people working *on* Hop: contributors to the Hop codebase, 
and anyone writing a plugin for it.
-For using Hop, see the xref:manual::index.adoc[user manual].
+For using Hop, see the xref:{page-component-version}@manual::index.adoc[user 
manual].
 
 == New here?
 
diff --git a/docs/hop-dev-manual/modules/ROOT/pages/plugin-types/gui.adoc 
b/docs/hop-dev-manual/modules/ROOT/pages/plugin-types/gui.adoc
index d4fa54768b..6f84f53cd2 100644
--- a/docs/hop-dev-manual/modules/ROOT/pages/plugin-types/gui.adoc
+++ b/docs/hop-dev-manual/modules/ROOT/pages/plugin-types/gui.adoc
@@ -113,7 +113,7 @@ Annotation:: `@HopPerspectivePlugin`
 Implement:: `IHopPerspective`
 Plugin type:: `HopPerspectivePluginType`, id `HOP_PERSPECTIVES`
 Examples:: `ui/src/main/java/org/apache/hop/ui/hopgui/perspective`
-Related:: xref:manual::hop-gui/perspective-plugin.adoc[the user manual page on 
perspectives]
+Related:: 
xref:{page-component-version}@manual::hop-gui/perspective-plugin.adoc[the user 
manual page on perspectives]
 
 Perspectives are sorted by id, so ids carry a numeric prefix that decides the 
sidebar order:
 
diff --git 
a/docs/hop-dev-manual/modules/ROOT/pages/plugin-types/metadata-configuration.adoc
 
b/docs/hop-dev-manual/modules/ROOT/pages/plugin-types/metadata-configuration.adoc
index 869c67fb6d..c011a97cd6 100644
--- 
a/docs/hop-dev-manual/modules/ROOT/pages/plugin-types/metadata-configuration.adoc
+++ 
b/docs/hop-dev-manual/modules/ROOT/pages/plugin-types/metadata-configuration.adoc
@@ -177,7 +177,7 @@ It is selected by the `HOP_PASSWORD_ENCODER_PLUGIN` 
variable or system property
 ====
 Obfuscation is not encryption.
 The default encoder keeps passwords out of plain sight in files; it does not 
protect them from someone who has the files.
-See xref:manual::password/passwords.adoc[the password documentation] for what 
the guarantees actually are.
+See xref:{page-component-version}@manual::password/passwords.adoc[the password 
documentation] for what the guarantees actually are.
 ====
 
 == Authentication provider and consumer
diff --git a/docs/hop-dev-manual/modules/ROOT/pages/writing-documentation.adoc 
b/docs/hop-dev-manual/modules/ROOT/pages/writing-documentation.adoc
index 6c42ff53d6..3caaf79ed3 100644
--- a/docs/hop-dev-manual/modules/ROOT/pages/writing-documentation.adoc
+++ b/docs/hop-dev-manual/modules/ROOT/pages/writing-documentation.adoc
@@ -43,7 +43,10 @@ Without it, Apache RAT fails the build.
 . Add a `:description:` line. It is used as the page summary and for search.
 . Add the page to `modules/ROOT/nav.adoc`, or it will not be published.
 . Link between pages with an `xref` macro, with the path relative to `pages/` 
rather than to the current file: `+xref:database/index.adoc[Database plugins]+`.
-Across manuals, prefix the component name — `manual` or `dev-manual`: 
`+xref:manual::pipeline/transforms/tableinput.adoc[Table input]+`.
+Across manuals, prefix the component name — `manual` or `dev-manual` — and pin 
the version with `+{page-component-version}@+`: 
`+xref:{page-component-version}@manual::pipeline/transforms/tableinput.adoc[Table
 input]+`.
+Without the version, Antora links to the latest stable release of the other 
manual, not to the version of the current page.
+A link to a page that is not in that release yet then breaks the website 
build, even though the pull request build passed.
+The pull request build rejects cross-manual xrefs without a version.
 
 == Documenting a plugin
 
diff --git 
a/docs/hop-user-manual/modules/ROOT/pages/installation-configuration.adoc 
b/docs/hop-user-manual/modules/ROOT/pages/installation-configuration.adoc
index 26e50b29d5..277fd2f339 100644
--- a/docs/hop-user-manual/modules/ROOT/pages/installation-configuration.adoc
+++ b/docs/hop-user-manual/modules/ROOT/pages/installation-configuration.adoc
@@ -158,7 +158,7 @@ For example:
 
 Check the documentation for your JRE for more information about additional JVM 
configuration, tuning and garbage collection parameters. 
https://www.baeldung.com/jvm-parameters[This guide] may help you to get started.
 
-TIP: **Developers**: a couple of lines below the `-Xmx` parameter, you'll find 
another `HOP_OPTIONS` line that contains `-Xdebug`. Uncomment this line to 
allow debuggers to attach to your running Hop instance. Check the 
xref:dev-manual::setup-dev-environment.adoc[developer documentation] for more 
information.
+TIP: **Developers**: a couple of lines below the `-Xmx` parameter, you'll find 
another `HOP_OPTIONS` line that contains `-Xdebug`. Uncomment this line to 
allow debuggers to attach to your running Hop instance. Check the 
xref:{page-component-version}@dev-manual::setup-dev-environment.adoc[developer 
documentation] for more information.
 
 
 === Hop environment variables [[envvars]]
diff --git 
a/docs/hop-user-manual/modules/ROOT/pages/technology/openlineage/index.adoc 
b/docs/hop-user-manual/modules/ROOT/pages/technology/openlineage/index.adoc
index a11d1378b3..ba55541eb9 100644
--- a/docs/hop-user-manual/modules/ROOT/pages/technology/openlineage/index.adoc
+++ b/docs/hop-user-manual/modules/ROOT/pages/technology/openlineage/index.adoc
@@ -23,7 +23,7 @@ under the License.
 
 https://openlineage.io/[OpenLineage] is an open standard for lineage metadata 
collection.
 The OpenLineage technology plugin is a Hop **lineage sink**: it subscribes to 
the in-engine
-xref:dev-manual::lineage.adoc[lineage observation hub] and maps Hop's neutral 
lineage events
+xref:{page-component-version}@dev-manual::lineage.adoc[lineage observation 
hub] and maps Hop's neutral lineage events
 to spec-correct OpenLineage `RunEvent` JSON, which it posts to any 
OpenLineage-compatible collector.
 The primary target is https://marquezproject.github.io/marquez/[Marquez].
 
@@ -34,7 +34,7 @@ back-pressure.
 == Enabling the sink
 
 The lineage hub is disabled by default. Enable it and select the OpenLineage 
sink with these
-**engine-scoped** variables (see xref:dev-manual::lineage.adoc[the lineage 
hub] for the hub-wide
+**engine-scoped** variables (see 
xref:{page-component-version}@dev-manual::lineage.adoc[the lineage hub] for the 
hub-wide
 variables):
 
 [cols="2,1,3",options="header"]

Reply via email to