From 95b8269c60df62d25b99d4b84de1b39d04a8cc1a Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Thu, 16 Apr 2026 20:03:49 +0200 Subject: [PATCH 01/33] trial 1 --- .pipeline/scripts/README.md | 16 +++++++ .pipeline/scripts/collect-release-javadocs.sh | 46 +++++++++++++++++++ pom.xml | 12 ++++- 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100755 .pipeline/scripts/collect-release-javadocs.sh diff --git a/.pipeline/scripts/README.md b/.pipeline/scripts/README.md index 94d66cdf3..297533565 100644 --- a/.pipeline/scripts/README.md +++ b/.pipeline/scripts/README.md @@ -2,3 +2,19 @@ The files here are used by the GitHub Actions workflows, but can also be used locally. Their purpose is to improve the pipeline UX by parsing result files and printing results in a readable way. + +## Local Javadoc Bundle + +Use `collect-release-javadocs.sh` to generate per-module Javadoc JARs for the release modules and copy them into one folder for manual upload. + +```bash +./.pipeline/scripts/collect-release-javadocs.sh +``` + +Optional custom output directory: + +```bash +./.pipeline/scripts/collect-release-javadocs.sh /absolute/path/to/output +``` + +Default output: `target/release-javadocs`. \ No newline at end of file diff --git a/.pipeline/scripts/collect-release-javadocs.sh b/.pipeline/scripts/collect-release-javadocs.sh new file mode 100755 index 000000000..9d785a772 --- /dev/null +++ b/.pipeline/scripts/collect-release-javadocs.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +OUTPUT_DIR="${1:-$ROOT_DIR/target/release-javadocs}" + +MODULES=( + "core:core" + "orchestration:orchestration" + "core-services/document-grounding:document-grounding" + "core-services/prompt-registry:prompt-registry" + "foundation-models/openai:openai" + "foundation-models/sap-rpt:sap-rpt" +) + +MODULE_LIST="$(printf '%s\n' "${MODULES[@]}" | cut -d: -f1 | paste -sd, -)" + +cd "$ROOT_DIR" + +echo "[INFO] Generating release-profile Javadocs for modules: $MODULE_LIST" +mvn --batch-mode --no-transfer-progress --fail-at-end --show-version \ + -Drelease \ + -pl "$MODULE_LIST" \ + -am \ + javadoc:jar@javadoc-jar + +rm -rf "$OUTPUT_DIR" +mkdir -p "$OUTPUT_DIR" + +echo "[INFO] Collecting generated Javadoc JARs into: $OUTPUT_DIR" +for entry in "${MODULES[@]}"; do + module="${entry%%:*}" + artifact="${entry##*:}" + jar_path="$ROOT_DIR/$module/target/$artifact-"* + jar_file=$(compgen -G "$jar_path-javadoc.jar" | head -n 1 || true) + + if [[ -z "$jar_file" ]]; then + echo "[ERROR] Missing Javadoc JAR for module '$module' (expected $artifact-*-javadoc.jar)." >&2 + exit 1 + fi + + cp "$jar_file" "$OUTPUT_DIR/" + echo "[OK] $(basename "$jar_file")" +done + +echo "[DONE] Javadoc bundle ready in: $OUTPUT_DIR" diff --git a/pom.xml b/pom.xml index 6ec369a03..e73335715 100644 --- a/pom.xml +++ b/pom.xml @@ -859,14 +859,24 @@ https://gitbox.apache.org/repos/asf?p=maven-pmd-plugin.git;a=blob_plain;f=src/ma true -Xdoclint:none protected - ${project.basedir}/target/delombok + ${project.basedir}/core/target/delombok:${project.basedir}/orchestration/target/delombok:${project.basedir}/core-services/document-grounding/target/delombok:${project.basedir}/core-services/prompt-registry/target/delombok:${project.basedir}/foundation-models/openai/target/delombok:${project.basedir}/foundation-models/sap-rpt/target/delombok + + + org.projectlombok + lombok + 1.18.44 + + javadoc-jar jar + + ${project.basedir}/target/delombok + From fb0c1566eaf11eb8a00569be38b5bbecacebbfa9 Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Wed, 22 Apr 2026 23:35:57 +0200 Subject: [PATCH 02/33] revert --- .pipeline/scripts/README.md | 16 ------- .pipeline/scripts/collect-release-javadocs.sh | 46 ------------------- 2 files changed, 62 deletions(-) delete mode 100755 .pipeline/scripts/collect-release-javadocs.sh diff --git a/.pipeline/scripts/README.md b/.pipeline/scripts/README.md index 297533565..94d66cdf3 100644 --- a/.pipeline/scripts/README.md +++ b/.pipeline/scripts/README.md @@ -2,19 +2,3 @@ The files here are used by the GitHub Actions workflows, but can also be used locally. Their purpose is to improve the pipeline UX by parsing result files and printing results in a readable way. - -## Local Javadoc Bundle - -Use `collect-release-javadocs.sh` to generate per-module Javadoc JARs for the release modules and copy them into one folder for manual upload. - -```bash -./.pipeline/scripts/collect-release-javadocs.sh -``` - -Optional custom output directory: - -```bash -./.pipeline/scripts/collect-release-javadocs.sh /absolute/path/to/output -``` - -Default output: `target/release-javadocs`. \ No newline at end of file diff --git a/.pipeline/scripts/collect-release-javadocs.sh b/.pipeline/scripts/collect-release-javadocs.sh deleted file mode 100755 index 9d785a772..000000000 --- a/.pipeline/scripts/collect-release-javadocs.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" -OUTPUT_DIR="${1:-$ROOT_DIR/target/release-javadocs}" - -MODULES=( - "core:core" - "orchestration:orchestration" - "core-services/document-grounding:document-grounding" - "core-services/prompt-registry:prompt-registry" - "foundation-models/openai:openai" - "foundation-models/sap-rpt:sap-rpt" -) - -MODULE_LIST="$(printf '%s\n' "${MODULES[@]}" | cut -d: -f1 | paste -sd, -)" - -cd "$ROOT_DIR" - -echo "[INFO] Generating release-profile Javadocs for modules: $MODULE_LIST" -mvn --batch-mode --no-transfer-progress --fail-at-end --show-version \ - -Drelease \ - -pl "$MODULE_LIST" \ - -am \ - javadoc:jar@javadoc-jar - -rm -rf "$OUTPUT_DIR" -mkdir -p "$OUTPUT_DIR" - -echo "[INFO] Collecting generated Javadoc JARs into: $OUTPUT_DIR" -for entry in "${MODULES[@]}"; do - module="${entry%%:*}" - artifact="${entry##*:}" - jar_path="$ROOT_DIR/$module/target/$artifact-"* - jar_file=$(compgen -G "$jar_path-javadoc.jar" | head -n 1 || true) - - if [[ -z "$jar_file" ]]; then - echo "[ERROR] Missing Javadoc JAR for module '$module' (expected $artifact-*-javadoc.jar)." >&2 - exit 1 - fi - - cp "$jar_file" "$OUTPUT_DIR/" - echo "[OK] $(basename "$jar_file")" -done - -echo "[DONE] Javadoc bundle ready in: $OUTPUT_DIR" From 251f09d5758cef1c97276772d4e8a7a1d0fa6060 Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Wed, 22 Apr 2026 23:44:23 +0200 Subject: [PATCH 03/33] Approach 1 --- .github/workflows/continuous-integration.yaml | 4 + pom.xml | 42 ++++- scripts/build-local-javadocs.sh | 175 ++++++++++++++++++ 3 files changed, 217 insertions(+), 4 deletions(-) create mode 100755 scripts/build-local-javadocs.sh diff --git a/.github/workflows/continuous-integration.yaml b/.github/workflows/continuous-integration.yaml index 9aead6955..742b2acc9 100644 --- a/.github/workflows/continuous-integration.yaml +++ b/.github/workflows/continuous-integration.yaml @@ -66,6 +66,10 @@ jobs: MVN_ARGS="${{ env.MVN_MULTI_THREADED_ARGS }} clean install -Dgenerate -DskipTests -DskipFormatting" mvn $MVN_ARGS + - name: "Build Local Javadocs" + run: | + bash scripts/build-local-javadocs.sh + - name: "Verify Local Changes" run: | CHANGED_FILES="$(git --no-pager diff --name-only)" diff --git a/pom.xml b/pom.xml index c49521644..9ef324a9d 100644 --- a/pom.xml +++ b/pom.xml @@ -80,6 +80,7 @@ 3.4.0 false + 3.4.5 false false @@ -859,7 +860,7 @@ https://gitbox.apache.org/repos/asf?p=maven-pmd-plugin.git;a=blob_plain;f=src/ma true -Xdoclint:none protected - ${project.basedir}/core/target/delombok:${project.basedir}/orchestration/target/delombok:${project.basedir}/core-services/document-grounding/target/delombok:${project.basedir}/core-services/prompt-registry/target/delombok:${project.basedir}/foundation-models/openai/target/delombok:${project.basedir}/foundation-models/sap-rpt/target/delombok + false @@ -874,9 +875,6 @@ https://gitbox.apache.org/repos/asf?p=maven-pmd-plugin.git;a=blob_plain;f=src/ma jar - - ${project.basedir}/target/delombok - @@ -999,6 +997,42 @@ https://gitbox.apache.org/repos/asf?p=maven-pmd-plugin.git;a=blob_plain;f=src/ma + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + ${maven-project-info-reports-plugin.version} + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.12.0 + false + + true + -Xdoclint:none + protected + false + + + org.projectlombok + lombok + 1.18.44 + + + + + + aggregate-no-fork + + aggregate-no-fork + + + + + + diff --git a/scripts/build-local-javadocs.sh b/scripts/build-local-javadocs.sh new file mode 100755 index 000000000..1cef83c22 --- /dev/null +++ b/scripts/build-local-javadocs.sh @@ -0,0 +1,175 @@ +#!/usr/bin/env bash +set -euo pipefail +shopt -s nullglob + +join_by() { + local sep="$1" + shift + local out="" + local first=1 + for item in "$@"; do + if (( first )); then + out="$item" + first=0 + else + out+="$sep$item" + fi + done + printf '%s' "$out" +} + +run_logged() { + local log_file="$1" + shift + + if ! "$@" >"$log_file" 2>&1; then + echo "Command failed: $*" >&2 + echo "See log: $log_file" >&2 + tail -n 40 "$log_file" >&2 || true + exit 1 + fi +} + +print_compact_aggregate_output() { + local aggregate_log="$1" + awk ' + /^\[INFO\]$/ { print; next } + /^\[INFO\] -+< / { print; next } + /^\[INFO\] Building / { print; next } + /^\[INFO\] from / { print; next } + /^\[INFO\] -+\[ jar \]-+$/ { print; next } + /^\[INFO\] --- javadoc:[^:]+:aggregate-no-fork .* ---$/ { print; next } + ' "$aggregate_log" +} + +repo_root="$(cd "$(dirname "$0")/.." && pwd)" +cd "$repo_root" + +module_paths=( + "core" + "orchestration" + "core-services/document-grounding" + "core-services/prompt-registry" + "foundation-models/openai" + "foundation-models/sap-rpt" +) + +module_names=( + "AI Core client" + "Orchestration client" + "Document Grounding Client" + "Prompt Registry client" + "OpenAI client" + "SAP RPT Model Client" +) + +module_artifact_ids=( + "sdk-parent" + "core" + "orchestration" + "document-grounding" + "prompt-registry" + "openai" + "sap-rpt" +) + +out_dir="$repo_root/target/local-javadocs" +logs_dir="$repo_root/.local-javadocs-logs" + +mkdir -p "$logs_dir" + +build_log="$logs_dir/build.log" +aggregate_log="$logs_dir/aggregate-no-fork.log" +delombok_javadoc_log="$logs_dir/delombok-javadoc.log" + +# Generate everything in one Maven run. +run_logged "$build_log" mvn -B -ntp -Dstyle.color=never -Drelease -DskipTests -Dmaven.javadoc.failOnError=false clean package site + +# Run aggregate-no-fork once in isolation so we can print a short, stable status block. +run_logged "$aggregate_log" mvn -B -ntp -Dstyle.color=never -Drelease -DskipTests -Dmaven.javadoc.failOnError=false javadoc:aggregate-no-fork + +for module_artifact_id in "${module_artifact_ids[@]}"; do + if ! grep -qE "^\[INFO\] --- javadoc:[^:]+:aggregate-no-fork .* @ ${module_artifact_id} ---$" "$aggregate_log"; then + echo "Missing aggregate-no-fork execution line for module artifact: ${module_artifact_id}" >&2 + echo "See log: $aggregate_log" >&2 + exit 1 + fi +done + +print_compact_aggregate_output "$aggregate_log" + +options_file="$repo_root/target/site/apidocs/options" +packages_file="$repo_root/target/site/apidocs/packages" +patched_options_file="$repo_root/target/site/apidocs/options.delombok" + +if [[ ! -f "$options_file" || ! -f "$packages_file" ]]; then + echo "Missing aggregate javadoc argument files in $repo_root/target/site/apidocs" >&2 + exit 1 +fi + +delombok_paths=() +for module_path in "${module_paths[@]}"; do + delombok_dir="$repo_root/$module_path/target/delombok" + if [[ ! -d "$delombok_dir" ]]; then + echo "Missing delombok sources for $module_path at $delombok_dir" >&2 + exit 1 + fi + delombok_paths+=("$delombok_dir") +done + +delombok_sourcepath="$(join_by : "${delombok_paths[@]}")" + +# Re-run javadoc using delomboked sources to avoid Lombok annotation parser errors. +awk -v sp="$delombok_sourcepath" 'BEGIN{replace_next=0} {if(replace_next==1){print "\047" sp "\047"; replace_next=0; next} print; if($0=="-sourcepath"){replace_next=1}}' "$options_file" > "$patched_options_file" +run_logged "$delombok_javadoc_log" javadoc @"$patched_options_file" @"$packages_file" + +# Javadoc jars were already built by the Maven command above. + +rm -rf "$out_dir" +mkdir -p "$out_dir" + +aggregate_dir="$repo_root/target/site/apidocs" +if [[ ! -f "$aggregate_dir/index.html" ]]; then + echo "Missing aggregate javadocs at $aggregate_dir" >&2 + exit 1 +fi +cp -R "$aggregate_dir" "$out_dir/aggregate" + +index_file="$out_dir/index.html" +cat > "$index_file" <<'HTML' + + + + + Local Javadocs + + +

Local Javadocs

+

Aggregate API docs

+
    +HTML + +for i in "${!module_paths[@]}"; do + module_path="${module_paths[$i]}" + module_name="${module_names[$i]}" + module_id="${module_path//\//-}" + module_dir="$out_dir/$module_id" + mkdir -p "$module_dir" + + jar_path=("$repo_root/$module_path"/target/*-javadoc.jar) + if [[ ${#jar_path[@]} -eq 0 ]]; then + echo "Missing javadoc jar for $module_path" >&2 + exit 1 + fi + + unzip -q "${jar_path[0]}" -d "$module_dir" + printf '
  • %s
  • \n' "$module_id" "$module_name" >> "$index_file" +done + +cat >> "$index_file" <<'HTML' +
+ + +HTML + +echo "Local javadocs are available at: $out_dir/index.html" \ No newline at end of file From fff14439d656239a5b5df528b2da46199b49d255 Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Thu, 23 Apr 2026 15:51:38 +0200 Subject: [PATCH 04/33] Approach 2 --- .github/workflows/build-local-javadocs.yaml | 204 ++++++++++++++++++ .github/workflows/continuous-integration.yaml | 8 +- scripts/build-local-javadocs.sh | 175 --------------- 3 files changed, 208 insertions(+), 179 deletions(-) create mode 100644 .github/workflows/build-local-javadocs.yaml delete mode 100755 scripts/build-local-javadocs.sh diff --git a/.github/workflows/build-local-javadocs.yaml b/.github/workflows/build-local-javadocs.yaml new file mode 100644 index 000000000..0fad5c579 --- /dev/null +++ b/.github/workflows/build-local-javadocs.yaml @@ -0,0 +1,204 @@ +name: "Build Local Javadocs" +on: + pull_request: + branches: [ "*" ] + push: + branches: [ "main" ] + workflow_dispatch: # triggered by the prepare-release workflow + workflow_call: + +env: + JAVA_VERSION: 21 + # keep the following two variables in sync with our 'cache-maven-dependencies.yaml' workflow + MAVEN_CACHE_KEY: maven-dependencies + MAVEN_CACHE_DIR: ~/.m2 + +jobs: + + build-local-javadocs: + runs-on: ubuntu-latest + steps: + + - name: "Checkout repository" + uses: actions/checkout@v6 + with: + fetch-depth: 1 + ref: ${{ github.event.pull_request.head.ref }} + repository: ${{ github.event.pull_request.head.repo.full_name }} + + - name: "Setup Java" + uses: actions/setup-java@v5 + with: + distribution: "sapmachine" + java-version: ${{ env.JAVA_VERSION }} + cache: 'maven' + + - name: "Restore Dependencies" + uses: actions/cache/restore@v5 + with: + key: ${{ env.MAVEN_CACHE_KEY }} + path: ${{ env.MAVEN_CACHE_DIR }} + + - name: "Build SDK and generate Javadoc site" + run: | + mvn -B -ntp -Dstyle.color=never -Drelease -DskipTests -Dmaven.javadoc.failOnError=false \ + clean package site \ + 2>&1 | tee .build.log + + - name: "Run aggregate-no-fork and verify all modules are present" + run: | + mvn -B -ntp -Dstyle.color=never -Drelease -DskipTests -Dmaven.javadoc.failOnError=false \ + javadoc:aggregate-no-fork \ + 2>&1 | tee .aggregate-no-fork.log + + module_artifact_ids=( + "sdk-parent" + "core" + "orchestration" + "document-grounding" + "prompt-registry" + "openai" + "sap-rpt" + ) + + for module_artifact_id in "${module_artifact_ids[@]}"; do + if ! grep -qE "^\[INFO\] --- javadoc:[^:]+:aggregate-no-fork .* @ ${module_artifact_id} ---$" .aggregate-no-fork.log; then + echo "Missing aggregate-no-fork execution line for module artifact: ${module_artifact_id}" >&2 + exit 1 + fi + done + + # Print compact status block + awk ' + /^\[INFO\]$/ { print; next } + /^\[INFO\] -+< / { print; next } + /^\[INFO\] Building / { print; next } + /^\[INFO\] from / { print; next } + /^\[INFO\] -+\[ jar \]-+$/ { print; next } + /^\[INFO\] --- javadoc:[^:]+:aggregate-no-fork .* ---$/ { print; next } + ' .aggregate-no-fork.log + + - name: "Re-run Javadoc with delomboked sources" + run: | + options_file="target/site/apidocs/options" + packages_file="target/site/apidocs/packages" + patched_options_file="target/site/apidocs/options.delombok" + + if [[ ! -f "$options_file" || ! -f "$packages_file" ]]; then + echo "Missing aggregate javadoc argument files in target/site/apidocs" >&2 + exit 1 + fi + + module_paths=( + "core" + "orchestration" + "core-services/document-grounding" + "core-services/prompt-registry" + "foundation-models/openai" + "foundation-models/sap-rpt" + ) + + delombok_paths=() + for module_path in "${module_paths[@]}"; do + delombok_dir="$module_path/target/delombok" + if [[ ! -d "$delombok_dir" ]]; then + echo "Missing delombok sources for $module_path at $delombok_dir" >&2 + exit 1 + fi + delombok_paths+=("$delombok_dir") + done + + # Build colon-separated sourcepath + delombok_sourcepath="" + first=1 + for p in "${delombok_paths[@]}"; do + if (( first )); then delombok_sourcepath="$p"; first=0 + else delombok_sourcepath+="$p"; fi + done + + # Patch options file: replace the argument after -sourcepath with delombok paths + awk -v sp="$delombok_sourcepath" \ + 'BEGIN{replace_next=0} + {if(replace_next==1){print "\047" sp "\047"; replace_next=0; next} + print; + if($0=="-sourcepath"){replace_next=1}}' \ + "$options_file" > "$patched_options_file" + + javadoc @"$patched_options_file" @"$packages_file" 2>&1 | tee .delombok-javadoc.log + + - name: "Assemble local-javadocs output directory" + run: | + out_dir="target/local-javadocs" + rm -rf "$out_dir" + mkdir -p "$out_dir" + + aggregate_dir="target/site/apidocs" + if [[ ! -f "$aggregate_dir/index.html" ]]; then + echo "Missing aggregate javadocs at $aggregate_dir" >&2 + exit 1 + fi + cp -R "$aggregate_dir" "$out_dir/aggregate" + + module_paths=( + "core" + "orchestration" + "core-services/document-grounding" + "core-services/prompt-registry" + "foundation-models/openai" + "foundation-models/sap-rpt" + ) + + module_names=( + "AI Core client" + "Orchestration client" + "Document Grounding Client" + "Prompt Registry client" + "OpenAI client" + "SAP RPT Model Client" + ) + + index_file="$out_dir/index.html" + cat > "$index_file" <<'HTML' + + + + + Local Javadocs + + +

Local Javadocs

+

Aggregate API docs

+
    + HTML + + for i in "${!module_paths[@]}"; do + module_path="${module_paths[$i]}" + module_name="${module_names[$i]}" + module_id="${module_path//\//-}" + module_dir="$out_dir/$module_id" + mkdir -p "$module_dir" + + jar_path=("$module_path"/target/*-javadoc.jar) + if [[ ${#jar_path[@]} -eq 0 ]]; then + echo "Missing javadoc jar for $module_path" >&2 + exit 1 + fi + + unzip -q "${jar_path[0]}" -d "$module_dir" + printf '
  • %s
  • \n' "$module_id" "$module_name" >> "$index_file" + done + + cat >> "$index_file" <<'HTML' +
+ + + HTML + + echo "Local javadocs assembled at: $out_dir/index.html" + + - name: "Upload Javadocs artifact" + uses: actions/upload-artifact@v4 + with: + name: local-javadocs + path: target/local-javadocs/ + retention-days: 7 diff --git a/.github/workflows/continuous-integration.yaml b/.github/workflows/continuous-integration.yaml index 742b2acc9..602be9d66 100644 --- a/.github/workflows/continuous-integration.yaml +++ b/.github/workflows/continuous-integration.yaml @@ -66,10 +66,6 @@ jobs: MVN_ARGS="${{ env.MVN_MULTI_THREADED_ARGS }} clean install -Dgenerate -DskipTests -DskipFormatting" mvn $MVN_ARGS - - name: "Build Local Javadocs" - run: | - bash scripts/build-local-javadocs.sh - - name: "Verify Local Changes" run: | CHANGED_FILES="$(git --no-pager diff --name-only)" @@ -96,3 +92,7 @@ jobs: { "text": "🚨 Main Build Failed! 😬 Please inspect & fix by clicking " } + + build-local-javadocs: + needs: continuous-integration + uses: ./.github/workflows/build-local-javadocs.yaml diff --git a/scripts/build-local-javadocs.sh b/scripts/build-local-javadocs.sh deleted file mode 100755 index 1cef83c22..000000000 --- a/scripts/build-local-javadocs.sh +++ /dev/null @@ -1,175 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail -shopt -s nullglob - -join_by() { - local sep="$1" - shift - local out="" - local first=1 - for item in "$@"; do - if (( first )); then - out="$item" - first=0 - else - out+="$sep$item" - fi - done - printf '%s' "$out" -} - -run_logged() { - local log_file="$1" - shift - - if ! "$@" >"$log_file" 2>&1; then - echo "Command failed: $*" >&2 - echo "See log: $log_file" >&2 - tail -n 40 "$log_file" >&2 || true - exit 1 - fi -} - -print_compact_aggregate_output() { - local aggregate_log="$1" - awk ' - /^\[INFO\]$/ { print; next } - /^\[INFO\] -+< / { print; next } - /^\[INFO\] Building / { print; next } - /^\[INFO\] from / { print; next } - /^\[INFO\] -+\[ jar \]-+$/ { print; next } - /^\[INFO\] --- javadoc:[^:]+:aggregate-no-fork .* ---$/ { print; next } - ' "$aggregate_log" -} - -repo_root="$(cd "$(dirname "$0")/.." && pwd)" -cd "$repo_root" - -module_paths=( - "core" - "orchestration" - "core-services/document-grounding" - "core-services/prompt-registry" - "foundation-models/openai" - "foundation-models/sap-rpt" -) - -module_names=( - "AI Core client" - "Orchestration client" - "Document Grounding Client" - "Prompt Registry client" - "OpenAI client" - "SAP RPT Model Client" -) - -module_artifact_ids=( - "sdk-parent" - "core" - "orchestration" - "document-grounding" - "prompt-registry" - "openai" - "sap-rpt" -) - -out_dir="$repo_root/target/local-javadocs" -logs_dir="$repo_root/.local-javadocs-logs" - -mkdir -p "$logs_dir" - -build_log="$logs_dir/build.log" -aggregate_log="$logs_dir/aggregate-no-fork.log" -delombok_javadoc_log="$logs_dir/delombok-javadoc.log" - -# Generate everything in one Maven run. -run_logged "$build_log" mvn -B -ntp -Dstyle.color=never -Drelease -DskipTests -Dmaven.javadoc.failOnError=false clean package site - -# Run aggregate-no-fork once in isolation so we can print a short, stable status block. -run_logged "$aggregate_log" mvn -B -ntp -Dstyle.color=never -Drelease -DskipTests -Dmaven.javadoc.failOnError=false javadoc:aggregate-no-fork - -for module_artifact_id in "${module_artifact_ids[@]}"; do - if ! grep -qE "^\[INFO\] --- javadoc:[^:]+:aggregate-no-fork .* @ ${module_artifact_id} ---$" "$aggregate_log"; then - echo "Missing aggregate-no-fork execution line for module artifact: ${module_artifact_id}" >&2 - echo "See log: $aggregate_log" >&2 - exit 1 - fi -done - -print_compact_aggregate_output "$aggregate_log" - -options_file="$repo_root/target/site/apidocs/options" -packages_file="$repo_root/target/site/apidocs/packages" -patched_options_file="$repo_root/target/site/apidocs/options.delombok" - -if [[ ! -f "$options_file" || ! -f "$packages_file" ]]; then - echo "Missing aggregate javadoc argument files in $repo_root/target/site/apidocs" >&2 - exit 1 -fi - -delombok_paths=() -for module_path in "${module_paths[@]}"; do - delombok_dir="$repo_root/$module_path/target/delombok" - if [[ ! -d "$delombok_dir" ]]; then - echo "Missing delombok sources for $module_path at $delombok_dir" >&2 - exit 1 - fi - delombok_paths+=("$delombok_dir") -done - -delombok_sourcepath="$(join_by : "${delombok_paths[@]}")" - -# Re-run javadoc using delomboked sources to avoid Lombok annotation parser errors. -awk -v sp="$delombok_sourcepath" 'BEGIN{replace_next=0} {if(replace_next==1){print "\047" sp "\047"; replace_next=0; next} print; if($0=="-sourcepath"){replace_next=1}}' "$options_file" > "$patched_options_file" -run_logged "$delombok_javadoc_log" javadoc @"$patched_options_file" @"$packages_file" - -# Javadoc jars were already built by the Maven command above. - -rm -rf "$out_dir" -mkdir -p "$out_dir" - -aggregate_dir="$repo_root/target/site/apidocs" -if [[ ! -f "$aggregate_dir/index.html" ]]; then - echo "Missing aggregate javadocs at $aggregate_dir" >&2 - exit 1 -fi -cp -R "$aggregate_dir" "$out_dir/aggregate" - -index_file="$out_dir/index.html" -cat > "$index_file" <<'HTML' - - - - - Local Javadocs - - -

Local Javadocs

-

Aggregate API docs

-
    -HTML - -for i in "${!module_paths[@]}"; do - module_path="${module_paths[$i]}" - module_name="${module_names[$i]}" - module_id="${module_path//\//-}" - module_dir="$out_dir/$module_id" - mkdir -p "$module_dir" - - jar_path=("$repo_root/$module_path"/target/*-javadoc.jar) - if [[ ${#jar_path[@]} -eq 0 ]]; then - echo "Missing javadoc jar for $module_path" >&2 - exit 1 - fi - - unzip -q "${jar_path[0]}" -d "$module_dir" - printf '
  • %s
  • \n' "$module_id" "$module_name" >> "$index_file" -done - -cat >> "$index_file" <<'HTML' -
- - -HTML - -echo "Local javadocs are available at: $out_dir/index.html" \ No newline at end of file From beb1cdbf6f28250890c792ea387fe5b108b389c9 Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Thu, 23 Apr 2026 16:17:30 +0200 Subject: [PATCH 05/33] Approach 2- fix --- .github/workflows/build-local-javadocs.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-local-javadocs.yaml b/.github/workflows/build-local-javadocs.yaml index 0fad5c579..b042cb057 100644 --- a/.github/workflows/build-local-javadocs.yaml +++ b/.github/workflows/build-local-javadocs.yaml @@ -23,8 +23,8 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 1 - ref: ${{ github.event.pull_request.head.ref }} - repository: ${{ github.event.pull_request.head.repo.full_name }} + ref: ${{ github.event.pull_request.head.ref || github.sha }} + repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} - name: "Setup Java" uses: actions/setup-java@v5 From 35ef33ffabb49cd419cc6b322f40014af42eb351 Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Thu, 23 Apr 2026 16:50:55 +0200 Subject: [PATCH 06/33] Approach 2- fix-2 --- .github/workflows/build-local-javadocs.yaml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-local-javadocs.yaml b/.github/workflows/build-local-javadocs.yaml index b042cb057..b3b76d3ba 100644 --- a/.github/workflows/build-local-javadocs.yaml +++ b/.github/workflows/build-local-javadocs.yaml @@ -17,6 +17,9 @@ jobs: build-local-javadocs: runs-on: ubuntu-latest + defaults: + run: + shell: bash -euo pipefail {0} steps: - name: "Checkout repository" @@ -42,8 +45,7 @@ jobs: - name: "Build SDK and generate Javadoc site" run: | mvn -B -ntp -Dstyle.color=never -Drelease -DskipTests -Dmaven.javadoc.failOnError=false \ - clean package site \ - 2>&1 | tee .build.log + clean package site - name: "Run aggregate-no-fork and verify all modules are present" run: | @@ -124,7 +126,7 @@ jobs: if($0=="-sourcepath"){replace_next=1}}' \ "$options_file" > "$patched_options_file" - javadoc @"$patched_options_file" @"$packages_file" 2>&1 | tee .delombok-javadoc.log + javadoc @"$patched_options_file" @"$packages_file" - name: "Assemble local-javadocs output directory" run: | From 7e9bea08b44f194fac5e2139ffbe8835b0ad1cd2 Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Thu, 23 Apr 2026 17:13:59 +0200 Subject: [PATCH 07/33] Approach 2- fix-3 --- .github/workflows/build-local-javadocs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-local-javadocs.yaml b/.github/workflows/build-local-javadocs.yaml index b3b76d3ba..03f956be1 100644 --- a/.github/workflows/build-local-javadocs.yaml +++ b/.github/workflows/build-local-javadocs.yaml @@ -115,7 +115,7 @@ jobs: first=1 for p in "${delombok_paths[@]}"; do if (( first )); then delombok_sourcepath="$p"; first=0 - else delombok_sourcepath+="$p"; fi + else delombok_sourcepath+=":$p"; fi done # Patch options file: replace the argument after -sourcepath with delombok paths From 9e46505327c9bfa73439a704fbc2bab2efa25d64 Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Thu, 23 Apr 2026 18:02:01 +0200 Subject: [PATCH 08/33] Approach 2- fix-4 --- .github/workflows/build-local-javadocs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-local-javadocs.yaml b/.github/workflows/build-local-javadocs.yaml index 03f956be1..1b33b3cc6 100644 --- a/.github/workflows/build-local-javadocs.yaml +++ b/.github/workflows/build-local-javadocs.yaml @@ -199,7 +199,7 @@ jobs: echo "Local javadocs assembled at: $out_dir/index.html" - name: "Upload Javadocs artifact" - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v4.6.2 with: name: local-javadocs path: target/local-javadocs/ From 07708dc02ad48dc8d5545e08393486399aabcf0d Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Thu, 23 Apr 2026 18:13:55 +0200 Subject: [PATCH 09/33] Approach 2- fix-5 --- .github/workflows/build-local-javadocs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-local-javadocs.yaml b/.github/workflows/build-local-javadocs.yaml index 1b33b3cc6..be517a685 100644 --- a/.github/workflows/build-local-javadocs.yaml +++ b/.github/workflows/build-local-javadocs.yaml @@ -199,7 +199,7 @@ jobs: echo "Local javadocs assembled at: $out_dir/index.html" - name: "Upload Javadocs artifact" - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@v6 with: name: local-javadocs path: target/local-javadocs/ From f9266a5b60e00ba5a4b87cc525bcbdb95200b85b Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Fri, 24 Apr 2026 12:46:54 +0200 Subject: [PATCH 10/33] doing the call inside prepare-release.yaml --- .github/workflows/continuous-integration.yaml | 4 ---- ...build-local-javadocs.yaml => javadoc.yaml} | 0 .github/workflows/prepare-release.yaml | 21 +++++++++++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) rename .github/workflows/{build-local-javadocs.yaml => javadoc.yaml} (100%) diff --git a/.github/workflows/continuous-integration.yaml b/.github/workflows/continuous-integration.yaml index 602be9d66..9aead6955 100644 --- a/.github/workflows/continuous-integration.yaml +++ b/.github/workflows/continuous-integration.yaml @@ -92,7 +92,3 @@ jobs: { "text": "🚨 Main Build Failed! 😬 Please inspect & fix by clicking " } - - build-local-javadocs: - needs: continuous-integration - uses: ./.github/workflows/build-local-javadocs.yaml diff --git a/.github/workflows/build-local-javadocs.yaml b/.github/workflows/javadoc.yaml similarity index 100% rename from .github/workflows/build-local-javadocs.yaml rename to .github/workflows/javadoc.yaml diff --git a/.github/workflows/prepare-release.yaml b/.github/workflows/prepare-release.yaml index 72a7c46e2..54af8982b 100644 --- a/.github/workflows/prepare-release.yaml +++ b/.github/workflows/prepare-release.yaml @@ -149,6 +149,26 @@ jobs: env: GH_TOKEN: ${{ github.token }} + create-javadoc-aggregated-pr: + needs: [ create-release ] + name: "Create Aggregated JavaDoc PR on Documentation Portal" + runs-on: ubuntu-latest + permissions: + actions: write # needed to trigger the ci-build workflow + statuses: write # needed to update the commit status + steps: + - name: "Checkout repository" + uses: actions/checkout@v6 + with: + ref: ${{ needs.create-release.outputs.release-name }} + - name: "Trigger workflow (ignore failures)" + uses: ./.github/actions/trigger-workflow + continue-on-error: true + with: + workflow: javadoc.yaml + workflow-ref: main + parameters: -f branch=${{ needs.create-release.outputs.release-name }} + create-release-notes-pr: name: 'Create Release Notes PR' needs: [bump-version, run-ci] @@ -284,6 +304,7 @@ jobs: PR_URL=$(gh pr create --title "feat: Release ${{ needs.bump-version.outputs.release-version }}" --body "## TODOs - [ ] Review the changes in [the release commit]($COMMIT_URL) - [ ] Review **and approve** the [Release Notes PR](${{ needs.create-release-notes-pr.outputs.pr-url }}) + - [ ] Review **and approve** the [JavaDoc PR](https://github.com/SAP/ai-sdk/pulls?q=is%3Aopen+is%3Apr+author%3Abot-sdk-js+Update+JavaDocs) - [ ] Add release notes to the [Draft Release](${{ needs.create-release.outputs.release-url }}) and improve formatting - [ ] Review **and approve** this PR - [ ] Trigger the [Perform Release Workflow](${{ github.event.repository.html_url }}/actions/workflows/perform-release.yaml) From d5cb9a12a0459f99f60c19483d08320919edfcc3 Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Fri, 24 Apr 2026 13:00:15 +0200 Subject: [PATCH 11/33] doing the call inside prepare-release.yaml --- .github/workflows/javadoc.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/javadoc.yaml b/.github/workflows/javadoc.yaml index be517a685..41b74b7db 100644 --- a/.github/workflows/javadoc.yaml +++ b/.github/workflows/javadoc.yaml @@ -9,13 +9,12 @@ on: env: JAVA_VERSION: 21 - # keep the following two variables in sync with our 'cache-maven-dependencies.yaml' workflow MAVEN_CACHE_KEY: maven-dependencies MAVEN_CACHE_DIR: ~/.m2 jobs: - build-local-javadocs: + build: runs-on: ubuntu-latest defaults: run: From d8d41cab164d4d95e8cca418faaf463a6d1b6a63 Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Fri, 24 Apr 2026 14:31:46 +0200 Subject: [PATCH 12/33] trial 3 --- .github/workflows/javadoc.yaml | 12 +++++------- .github/workflows/prepare-release.yaml | 20 ++++---------------- 2 files changed, 9 insertions(+), 23 deletions(-) diff --git a/.github/workflows/javadoc.yaml b/.github/workflows/javadoc.yaml index 41b74b7db..26a46512f 100644 --- a/.github/workflows/javadoc.yaml +++ b/.github/workflows/javadoc.yaml @@ -1,11 +1,10 @@ name: "Build Local Javadocs" on: - pull_request: - branches: [ "*" ] - push: - branches: [ "main" ] - workflow_dispatch: # triggered by the prepare-release workflow workflow_call: + inputs: + branch: + required: true + type: string env: JAVA_VERSION: 21 @@ -25,8 +24,7 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 1 - ref: ${{ github.event.pull_request.head.ref || github.sha }} - repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} + ref: ${{ inputs.branch }} - name: "Setup Java" uses: actions/setup-java@v5 diff --git a/.github/workflows/prepare-release.yaml b/.github/workflows/prepare-release.yaml index 54af8982b..bbeb707da 100644 --- a/.github/workflows/prepare-release.yaml +++ b/.github/workflows/prepare-release.yaml @@ -152,22 +152,10 @@ jobs: create-javadoc-aggregated-pr: needs: [ create-release ] name: "Create Aggregated JavaDoc PR on Documentation Portal" - runs-on: ubuntu-latest - permissions: - actions: write # needed to trigger the ci-build workflow - statuses: write # needed to update the commit status - steps: - - name: "Checkout repository" - uses: actions/checkout@v6 - with: - ref: ${{ needs.create-release.outputs.release-name }} - - name: "Trigger workflow (ignore failures)" - uses: ./.github/actions/trigger-workflow - continue-on-error: true - with: - workflow: javadoc.yaml - workflow-ref: main - parameters: -f branch=${{ needs.create-release.outputs.release-name }} + uses: ./.github/workflows/javadoc.yaml + with: + branch: ${{ needs.create-release.outputs.release-name }} + secrets: inherit create-release-notes-pr: name: 'Create Release Notes PR' From 970794212e2b970454ced3830c731c9ddbfc2352 Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Tue, 28 Apr 2026 14:07:40 +0200 Subject: [PATCH 13/33] revert prepare-release integration --- .github/workflows/prepare-release.yaml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/prepare-release.yaml b/.github/workflows/prepare-release.yaml index bbeb707da..e412577d9 100644 --- a/.github/workflows/prepare-release.yaml +++ b/.github/workflows/prepare-release.yaml @@ -149,14 +149,6 @@ jobs: env: GH_TOKEN: ${{ github.token }} - create-javadoc-aggregated-pr: - needs: [ create-release ] - name: "Create Aggregated JavaDoc PR on Documentation Portal" - uses: ./.github/workflows/javadoc.yaml - with: - branch: ${{ needs.create-release.outputs.release-name }} - secrets: inherit - create-release-notes-pr: name: 'Create Release Notes PR' needs: [bump-version, run-ci] From b636e0cbad91fbaa5c2600c930d9a303fe448de0 Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Tue, 28 Apr 2026 15:52:03 +0200 Subject: [PATCH 14/33] testing in CI workflow --- .github/workflows/continuous-integration.yaml | 5 + .github/workflows/javadoc.yaml | 144 +++++++++--------- 2 files changed, 73 insertions(+), 76 deletions(-) diff --git a/.github/workflows/continuous-integration.yaml b/.github/workflows/continuous-integration.yaml index 9aead6955..3f708b500 100644 --- a/.github/workflows/continuous-integration.yaml +++ b/.github/workflows/continuous-integration.yaml @@ -92,3 +92,8 @@ jobs: { "text": "🚨 Main Build Failed! 😬 Please inspect & fix by clicking " } + + javadoc: + uses: ./.github/workflows/javadoc.yaml + with: + branch: ${{ github.event.pull_request.head.ref || github.ref_name }} diff --git a/.github/workflows/javadoc.yaml b/.github/workflows/javadoc.yaml index 26a46512f..5019a3905 100644 --- a/.github/workflows/javadoc.yaml +++ b/.github/workflows/javadoc.yaml @@ -39,54 +39,28 @@ jobs: key: ${{ env.MAVEN_CACHE_KEY }} path: ${{ env.MAVEN_CACHE_DIR }} - - name: "Build SDK and generate Javadoc site" + - name: "Build SDK and generate aggregate options file" run: | mvn -B -ntp -Dstyle.color=never -Drelease -DskipTests -Dmaven.javadoc.failOnError=false \ - clean package site + clean package - - name: "Run aggregate-no-fork and verify all modules are present" - run: | - mvn -B -ntp -Dstyle.color=never -Drelease -DskipTests -Dmaven.javadoc.failOnError=false \ - javadoc:aggregate-no-fork \ - 2>&1 | tee .aggregate-no-fork.log - - module_artifact_ids=( - "sdk-parent" - "core" - "orchestration" - "document-grounding" - "prompt-registry" - "openai" - "sap-rpt" - ) - - for module_artifact_id in "${module_artifact_ids[@]}"; do - if ! grep -qE "^\[INFO\] --- javadoc:[^:]+:aggregate-no-fork .* @ ${module_artifact_id} ---$" .aggregate-no-fork.log; then - echo "Missing aggregate-no-fork execution line for module artifact: ${module_artifact_id}" >&2 - exit 1 - fi - done - - # Print compact status block - awk ' - /^\[INFO\]$/ { print; next } - /^\[INFO\] -+< / { print; next } - /^\[INFO\] Building / { print; next } - /^\[INFO\] from / { print; next } - /^\[INFO\] -+\[ jar \]-+$/ { print; next } - /^\[INFO\] --- javadoc:[^:]+:aggregate-no-fork .* ---$/ { print; next } - ' .aggregate-no-fork.log - - - name: "Re-run Javadoc with delomboked sources" - run: | - options_file="target/site/apidocs/options" - packages_file="target/site/apidocs/packages" - patched_options_file="target/site/apidocs/options.delombok" + # aggregate-no-fork across full reactor writes options/packages to target/reports/apidocs + # Lombok errors on child modules are expected (failOnError=false); the root options file + # is written first and survives regardless, giving us the combined classpath and flags. + mvn -B -ntp -Dstyle.color=never -Drelease -Dmaven.javadoc.failOnError=false \ + javadoc:aggregate-no-fork - if [[ ! -f "$options_file" || ! -f "$packages_file" ]]; then - echo "Missing aggregate javadoc argument files in target/site/apidocs" >&2 + if [[ ! -f target/reports/apidocs/options || ! -f target/reports/apidocs/packages ]]; then + echo "Missing aggregate javadoc argument files in target/reports/apidocs" >&2 exit 1 fi + echo "Aggregate options/packages files generated" + + - name: "Generate per-module and combined Javadocs from delomboked sources" + run: | + JAVADOC="$JAVA_HOME/bin/javadoc" + OPTIONS="target/reports/apidocs/options" + ALL_PACKAGES="target/reports/apidocs/packages" module_paths=( "core" @@ -97,33 +71,53 @@ jobs: "foundation-models/sap-rpt" ) - delombok_paths=() + patch_and_run() { + local sourcepath="$1" + local destdir="$2" + local packages_file="$3" + local patched="${OPTIONS}.patched" + + awk -v sp="$sourcepath" -v dd="$destdir" ' + BEGIN { skip_next=0 } + { + if (skip_next) { skip_next=0; next } + if ($0 == "-sourcepath") { print; print "\047" sp "\047"; skip_next=1; next } + if ($0 == "-d") { print; print "\047" dd "\047"; skip_next=1; next } + print + } + ' "$OPTIONS" > "$patched" + + grep -qF "$sourcepath" "$patched" || { echo "ERROR: sourcepath patch failed for $destdir" >&2; exit 1; } + mkdir -p "$destdir" + "$JAVADOC" @"$patched" @"$packages_file" + rm -f "$patched" + } + + # Per-module: derive packages list from that module's delombok sources only for module_path in "${module_paths[@]}"; do delombok_dir="$module_path/target/delombok" if [[ ! -d "$delombok_dir" ]]; then - echo "Missing delombok sources for $module_path at $delombok_dir" >&2 + echo "Missing delombok sources for $module_path" >&2 exit 1 fi - delombok_paths+=("$delombok_dir") + pkg_file="$module_path/target/javadoc-packages" + find "$delombok_dir" -name "*.java" \ + | xargs grep -l "^package " \ + | xargs grep "^package " \ + | awk '{print $2}' | tr -d ';' | sort -u > "$pkg_file" + echo "Generating javadoc for $module_path ..." + patch_and_run "$delombok_dir" "$module_path/target/javadoc-delombok" "$pkg_file" done - # Build colon-separated sourcepath - delombok_sourcepath="" - first=1 - for p in "${delombok_paths[@]}"; do - if (( first )); then delombok_sourcepath="$p"; first=0 - else delombok_sourcepath+=":$p"; fi + # Combined (parent): all modules' delombok dirs + original packages file + combined_sourcepath="" + for module_path in "${module_paths[@]}"; do + [[ -z "$combined_sourcepath" ]] \ + && combined_sourcepath="$module_path/target/delombok" \ + || combined_sourcepath+=":$module_path/target/delombok" done - - # Patch options file: replace the argument after -sourcepath with delombok paths - awk -v sp="$delombok_sourcepath" \ - 'BEGIN{replace_next=0} - {if(replace_next==1){print "\047" sp "\047"; replace_next=0; next} - print; - if($0=="-sourcepath"){replace_next=1}}' \ - "$options_file" > "$patched_options_file" - - javadoc @"$patched_options_file" @"$packages_file" + echo "Generating combined javadoc for sdk-parent ..." + patch_and_run "$combined_sourcepath" "target/javadoc-delombok" "$ALL_PACKAGES" - name: "Assemble local-javadocs output directory" run: | @@ -131,13 +125,6 @@ jobs: rm -rf "$out_dir" mkdir -p "$out_dir" - aggregate_dir="target/site/apidocs" - if [[ ! -f "$aggregate_dir/index.html" ]]; then - echo "Missing aggregate javadocs at $aggregate_dir" >&2 - exit 1 - fi - cp -R "$aggregate_dir" "$out_dir/aggregate" - module_paths=( "core" "orchestration" @@ -156,6 +143,13 @@ jobs: "SAP RPT Model Client" ) + # Combined (parent) javadoc + if [[ ! -f "target/javadoc-delombok/index.html" ]]; then + echo "Missing combined javadocs at target/javadoc-delombok" >&2 + exit 1 + fi + cp -R "target/javadoc-delombok" "$out_dir/aggregate" + index_file="$out_dir/index.html" cat > "$index_file" <<'HTML' @@ -166,7 +160,7 @@ jobs:

Local Javadocs

-

Aggregate API docs

+

Aggregate API docs (all modules)

    HTML @@ -174,16 +168,14 @@ jobs: module_path="${module_paths[$i]}" module_name="${module_names[$i]}" module_id="${module_path//\//-}" - module_dir="$out_dir/$module_id" - mkdir -p "$module_dir" - jar_path=("$module_path"/target/*-javadoc.jar) - if [[ ${#jar_path[@]} -eq 0 ]]; then - echo "Missing javadoc jar for $module_path" >&2 + src_dir="$module_path/target/javadoc-delombok" + if [[ ! -f "$src_dir/index.html" ]]; then + echo "Missing javadocs for $module_path at $src_dir" >&2 exit 1 fi - unzip -q "${jar_path[0]}" -d "$module_dir" + cp -R "$src_dir" "$out_dir/$module_id" printf '
  • %s
  • \n' "$module_id" "$module_name" >> "$index_file" done @@ -196,7 +188,7 @@ jobs: echo "Local javadocs assembled at: $out_dir/index.html" - name: "Upload Javadocs artifact" - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: local-javadocs path: target/local-javadocs/ From 183ec128c3feb5d9dff3a7c5a40175cf07058f5d Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Tue, 28 Apr 2026 15:59:04 +0200 Subject: [PATCH 15/33] testing in CI workflow-1 --- .github/workflows/javadoc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/javadoc.yaml b/.github/workflows/javadoc.yaml index 5019a3905..cacf183d8 100644 --- a/.github/workflows/javadoc.yaml +++ b/.github/workflows/javadoc.yaml @@ -42,7 +42,7 @@ jobs: - name: "Build SDK and generate aggregate options file" run: | mvn -B -ntp -Dstyle.color=never -Drelease -DskipTests -Dmaven.javadoc.failOnError=false \ - clean package + clean install # aggregate-no-fork across full reactor writes options/packages to target/reports/apidocs # Lombok errors on child modules are expected (failOnError=false); the root options file From aef90cba28d04937d31861ca45fcb78643fbd60c Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Tue, 28 Apr 2026 16:02:18 +0200 Subject: [PATCH 16/33] testing in CI workflow-2 --- .github/workflows/javadoc.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/javadoc.yaml b/.github/workflows/javadoc.yaml index cacf183d8..90b24e75a 100644 --- a/.github/workflows/javadoc.yaml +++ b/.github/workflows/javadoc.yaml @@ -41,13 +41,13 @@ jobs: - name: "Build SDK and generate aggregate options file" run: | - mvn -B -ntp -Dstyle.color=never -Drelease -DskipTests -Dmaven.javadoc.failOnError=false \ + mvn -B -ntp -Dstyle.color=never -DskipTests -Dmaven.javadoc.failOnError=false \ clean install # aggregate-no-fork across full reactor writes options/packages to target/reports/apidocs # Lombok errors on child modules are expected (failOnError=false); the root options file # is written first and survives regardless, giving us the combined classpath and flags. - mvn -B -ntp -Dstyle.color=never -Drelease -Dmaven.javadoc.failOnError=false \ + mvn -B -ntp -Dstyle.color=never -Dmaven.javadoc.failOnError=false \ javadoc:aggregate-no-fork if [[ ! -f target/reports/apidocs/options || ! -f target/reports/apidocs/packages ]]; then From 8f0fb3d6eb71252d83bc773762650d23959309b1 Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Tue, 28 Apr 2026 16:16:54 +0200 Subject: [PATCH 17/33] testing in CI workflow-3 --- .github/workflows/javadoc.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/javadoc.yaml b/.github/workflows/javadoc.yaml index 90b24e75a..34695f122 100644 --- a/.github/workflows/javadoc.yaml +++ b/.github/workflows/javadoc.yaml @@ -41,13 +41,13 @@ jobs: - name: "Build SDK and generate aggregate options file" run: | - mvn -B -ntp -Dstyle.color=never -DskipTests -Dmaven.javadoc.failOnError=false \ + mvn -B -ntp -Dstyle.color=never -Drelease -DskipTests -Dmaven.javadoc.failOnError=false -Dgpg.skip=true \ clean install # aggregate-no-fork across full reactor writes options/packages to target/reports/apidocs # Lombok errors on child modules are expected (failOnError=false); the root options file # is written first and survives regardless, giving us the combined classpath and flags. - mvn -B -ntp -Dstyle.color=never -Dmaven.javadoc.failOnError=false \ + mvn -B -ntp -Dstyle.color=never -Drelease -Dmaven.javadoc.failOnError=false -Dgpg.skip=true \ javadoc:aggregate-no-fork if [[ ! -f target/reports/apidocs/options || ! -f target/reports/apidocs/packages ]]; then From 5b3fa58a7bed64a0ed71a66b17554665db58798c Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Tue, 28 Apr 2026 16:30:17 +0200 Subject: [PATCH 18/33] revert --- .github/workflows/continuous-integration.yaml | 5 ----- .github/workflows/prepare-release.yaml | 1 - 2 files changed, 6 deletions(-) diff --git a/.github/workflows/continuous-integration.yaml b/.github/workflows/continuous-integration.yaml index 3f708b500..9aead6955 100644 --- a/.github/workflows/continuous-integration.yaml +++ b/.github/workflows/continuous-integration.yaml @@ -92,8 +92,3 @@ jobs: { "text": "🚨 Main Build Failed! 😬 Please inspect & fix by clicking " } - - javadoc: - uses: ./.github/workflows/javadoc.yaml - with: - branch: ${{ github.event.pull_request.head.ref || github.ref_name }} diff --git a/.github/workflows/prepare-release.yaml b/.github/workflows/prepare-release.yaml index e412577d9..72a7c46e2 100644 --- a/.github/workflows/prepare-release.yaml +++ b/.github/workflows/prepare-release.yaml @@ -284,7 +284,6 @@ jobs: PR_URL=$(gh pr create --title "feat: Release ${{ needs.bump-version.outputs.release-version }}" --body "## TODOs - [ ] Review the changes in [the release commit]($COMMIT_URL) - [ ] Review **and approve** the [Release Notes PR](${{ needs.create-release-notes-pr.outputs.pr-url }}) - - [ ] Review **and approve** the [JavaDoc PR](https://github.com/SAP/ai-sdk/pulls?q=is%3Aopen+is%3Apr+author%3Abot-sdk-js+Update+JavaDocs) - [ ] Add release notes to the [Draft Release](${{ needs.create-release.outputs.release-url }}) and improve formatting - [ ] Review **and approve** this PR - [ ] Trigger the [Perform Release Workflow](${{ github.event.repository.html_url }}/actions/workflows/perform-release.yaml) From 5893a2196ba3e2f02099fdb8f56e3032a067bb45 Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Tue, 28 Apr 2026 16:36:11 +0200 Subject: [PATCH 19/33] reverting pom --- .github/workflows/continuous-integration.yaml | 5 ++ pom.xml | 46 +------------------ 2 files changed, 6 insertions(+), 45 deletions(-) diff --git a/.github/workflows/continuous-integration.yaml b/.github/workflows/continuous-integration.yaml index 9aead6955..3f708b500 100644 --- a/.github/workflows/continuous-integration.yaml +++ b/.github/workflows/continuous-integration.yaml @@ -92,3 +92,8 @@ jobs: { "text": "🚨 Main Build Failed! 😬 Please inspect & fix by clicking " } + + javadoc: + uses: ./.github/workflows/javadoc.yaml + with: + branch: ${{ github.event.pull_request.head.ref || github.ref_name }} diff --git a/pom.xml b/pom.xml index 5e1bd3685..20cd886a6 100644 --- a/pom.xml +++ b/pom.xml @@ -80,7 +80,6 @@ 3.4.0 false - 3.4.5 false false @@ -860,15 +859,8 @@ https://gitbox.apache.org/repos/asf?p=maven-pmd-plugin.git;a=blob_plain;f=src/ma true -Xdoclint:none protected - false + ${project.basedir}/target/delombok - - - org.projectlombok - lombok - 1.18.44 - - javadoc-jar @@ -997,42 +989,6 @@ https://gitbox.apache.org/repos/asf?p=maven-pmd-plugin.git;a=blob_plain;f=src/ma - - - - org.apache.maven.plugins - maven-project-info-reports-plugin - ${maven-project-info-reports-plugin.version} - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.12.0 - false - - true - -Xdoclint:none - protected - false - - - org.projectlombok - lombok - 1.18.44 - - - - - - aggregate-no-fork - - aggregate-no-fork - - - - - - From d0fc5b74bd61f5d60af64b1e2030745a78794580 Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Tue, 28 Apr 2026 16:52:26 +0200 Subject: [PATCH 20/33] 2nd approach --- .github/workflows/javadoc.yaml | 89 +++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/.github/workflows/javadoc.yaml b/.github/workflows/javadoc.yaml index 34695f122..3cb304226 100644 --- a/.github/workflows/javadoc.yaml +++ b/.github/workflows/javadoc.yaml @@ -39,28 +39,14 @@ jobs: key: ${{ env.MAVEN_CACHE_KEY }} path: ${{ env.MAVEN_CACHE_DIR }} - - name: "Build SDK and generate aggregate options file" + - name: "Build SDK" run: | - mvn -B -ntp -Dstyle.color=never -Drelease -DskipTests -Dmaven.javadoc.failOnError=false -Dgpg.skip=true \ + mvn -B -ntp -Dstyle.color=never -Drelease -DskipTests -Dgpg.skip=true \ clean install - # aggregate-no-fork across full reactor writes options/packages to target/reports/apidocs - # Lombok errors on child modules are expected (failOnError=false); the root options file - # is written first and survives regardless, giving us the combined classpath and flags. - mvn -B -ntp -Dstyle.color=never -Drelease -Dmaven.javadoc.failOnError=false -Dgpg.skip=true \ - javadoc:aggregate-no-fork - - if [[ ! -f target/reports/apidocs/options || ! -f target/reports/apidocs/packages ]]; then - echo "Missing aggregate javadoc argument files in target/reports/apidocs" >&2 - exit 1 - fi - echo "Aggregate options/packages files generated" - - - name: "Generate per-module and combined Javadocs from delomboked sources" + - name: "Generate Javadocs from delomboked sources" run: | JAVADOC="$JAVA_HOME/bin/javadoc" - OPTIONS="target/reports/apidocs/options" - ALL_PACKAGES="target/reports/apidocs/packages" module_paths=( "core" @@ -71,29 +57,47 @@ jobs: "foundation-models/sap-rpt" ) - patch_and_run() { + # Build classpath from all module jars + dependencies + classpath="" + for module_path in "${module_paths[@]}"; do + cp_file="$module_path/target/cp.txt" + mvn -B -ntp -f "$module_path/pom.xml" \ + dependency:build-classpath -Dmdep.outputFile=target/cp.txt -Dmdep.includeScope=compile \ + -Dgpg.skip=true -q + module_jar=$(find "$module_path/target" -maxdepth 1 -name "*.jar" ! -name "*sources*" ! -name "*javadoc*" | head -1) + if [[ -n "$module_jar" ]]; then + [[ -z "$classpath" ]] && classpath="$module_jar" || classpath+=":$module_jar" + fi + if [[ -f "$cp_file" ]]; then + cp_content=$(cat "$cp_file") + [[ -n "$cp_content" ]] && classpath+=":$cp_content" + fi + done + + run_javadoc() { local sourcepath="$1" local destdir="$2" - local packages_file="$3" - local patched="${OPTIONS}.patched" - - awk -v sp="$sourcepath" -v dd="$destdir" ' - BEGIN { skip_next=0 } - { - if (skip_next) { skip_next=0; next } - if ($0 == "-sourcepath") { print; print "\047" sp "\047"; skip_next=1; next } - if ($0 == "-d") { print; print "\047" dd "\047"; skip_next=1; next } - print - } - ' "$OPTIONS" > "$patched" - - grep -qF "$sourcepath" "$patched" || { echo "ERROR: sourcepath patch failed for $destdir" >&2; exit 1; } + local pkg_file="$3" + + if [[ ! -s "$pkg_file" ]]; then + echo "No packages found for $destdir, skipping" >&2 + return + fi + mkdir -p "$destdir" - "$JAVADOC" @"$patched" @"$packages_file" - rm -f "$patched" + "$JAVADOC" \ + -sourcepath "$sourcepath" \ + -d "$destdir" \ + -classpath "$classpath" \ + -quiet \ + -Xdoclint:none \ + -encoding UTF-8 \ + -charset UTF-8 \ + -docencoding UTF-8 \ + @"$pkg_file" } - # Per-module: derive packages list from that module's delombok sources only + # Per-module javadocs for module_path in "${module_paths[@]}"; do delombok_dir="$module_path/target/delombok" if [[ ! -d "$delombok_dir" ]]; then @@ -106,18 +110,23 @@ jobs: | xargs grep "^package " \ | awk '{print $2}' | tr -d ';' | sort -u > "$pkg_file" echo "Generating javadoc for $module_path ..." - patch_and_run "$delombok_dir" "$module_path/target/javadoc-delombok" "$pkg_file" + run_javadoc "$delombok_dir" "$module_path/target/javadoc-delombok" "$pkg_file" done - # Combined (parent): all modules' delombok dirs + original packages file + # Combined javadoc (all modules) combined_sourcepath="" + combined_pkg_file="target/javadoc-all-packages" + > "$combined_pkg_file" for module_path in "${module_paths[@]}"; do + delombok_dir="$module_path/target/delombok" [[ -z "$combined_sourcepath" ]] \ - && combined_sourcepath="$module_path/target/delombok" \ - || combined_sourcepath+=":$module_path/target/delombok" + && combined_sourcepath="$delombok_dir" \ + || combined_sourcepath+=":$delombok_dir" + cat "$module_path/target/javadoc-packages" >> "$combined_pkg_file" done + sort -u "$combined_pkg_file" -o "$combined_pkg_file" echo "Generating combined javadoc for sdk-parent ..." - patch_and_run "$combined_sourcepath" "target/javadoc-delombok" "$ALL_PACKAGES" + run_javadoc "$combined_sourcepath" "target/javadoc-delombok" "$combined_pkg_file" - name: "Assemble local-javadocs output directory" run: | From f771d38263902fb5eeb1801426edf2ba12b1839f Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Tue, 28 Apr 2026 17:01:10 +0200 Subject: [PATCH 21/33] reverted CI --- .github/workflows/continuous-integration.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/continuous-integration.yaml b/.github/workflows/continuous-integration.yaml index 3f708b500..9aead6955 100644 --- a/.github/workflows/continuous-integration.yaml +++ b/.github/workflows/continuous-integration.yaml @@ -92,8 +92,3 @@ jobs: { "text": "🚨 Main Build Failed! 😬 Please inspect & fix by clicking " } - - javadoc: - uses: ./.github/workflows/javadoc.yaml - with: - branch: ${{ github.event.pull_request.head.ref || github.ref_name }} From 0bd22fb5949354bac76a01d2d385a035dff39f75 Mon Sep 17 00:00:00 2001 From: Nourhan Islam Shata <163640161+n-o-u-r-h-a-n@users.noreply.github.com> Date: Thu, 30 Apr 2026 14:12:37 +0200 Subject: [PATCH 22/33] Update .github/workflows/javadoc.yaml Co-authored-by: Jonas-Isr --- .github/workflows/javadoc.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/javadoc.yaml b/.github/workflows/javadoc.yaml index 3cb304226..bc2f7656e 100644 --- a/.github/workflows/javadoc.yaml +++ b/.github/workflows/javadoc.yaml @@ -40,9 +40,9 @@ jobs: path: ${{ env.MAVEN_CACHE_DIR }} - name: "Build SDK" - run: | - mvn -B -ntp -Dstyle.color=never -Drelease -DskipTests -Dgpg.skip=true \ - clean install + run: > + mvn -B -ntp -Dstyle.color=never -Drelease -DskipTests -Dgpg.skip=true + clean install - name: "Generate Javadocs from delomboked sources" run: | From 75eb668d2cd05504e26eda24574a16890b9c1798 Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Thu, 30 Apr 2026 15:01:55 +0200 Subject: [PATCH 23/33] fix minor comments --- .github/workflows/javadoc.yaml | 55 +++++++++++++++------------------- 1 file changed, 24 insertions(+), 31 deletions(-) diff --git a/.github/workflows/javadoc.yaml b/.github/workflows/javadoc.yaml index 3cb304226..a5e78eb92 100644 --- a/.github/workflows/javadoc.yaml +++ b/.github/workflows/javadoc.yaml @@ -10,6 +10,20 @@ env: JAVA_VERSION: 21 MAVEN_CACHE_KEY: maven-dependencies MAVEN_CACHE_DIR: ~/.m2 + MODULE_PATHS: | + core + orchestration + core-services/document-grounding + core-services/prompt-registry + foundation-models/openai + foundation-models/sap-rpt + MODULE_NAMES: | + AI Core client + Orchestration client + Document Grounding Client + Prompt Registry client + OpenAI client + SAP RPT Model Client jobs: @@ -48,14 +62,7 @@ jobs: run: | JAVADOC="$JAVA_HOME/bin/javadoc" - module_paths=( - "core" - "orchestration" - "core-services/document-grounding" - "core-services/prompt-registry" - "foundation-models/openai" - "foundation-models/sap-rpt" - ) + mapfile -t module_paths <<< "$MODULE_PATHS" # Build classpath from all module jars + dependencies classpath="" @@ -75,9 +82,10 @@ jobs: done run_javadoc() { - local sourcepath="$1" - local destdir="$2" - local pkg_file="$3" + local javadoc="$1" + local sourcepath="$2" + local destdir="$3" + local pkg_file="$4" if [[ ! -s "$pkg_file" ]]; then echo "No packages found for $destdir, skipping" >&2 @@ -85,7 +93,7 @@ jobs: fi mkdir -p "$destdir" - "$JAVADOC" \ + "$javadoc" \ -sourcepath "$sourcepath" \ -d "$destdir" \ -classpath "$classpath" \ @@ -110,7 +118,7 @@ jobs: | xargs grep "^package " \ | awk '{print $2}' | tr -d ';' | sort -u > "$pkg_file" echo "Generating javadoc for $module_path ..." - run_javadoc "$delombok_dir" "$module_path/target/javadoc-delombok" "$pkg_file" + run_javadoc "$JAVADOC" "$delombok_dir" "$module_path/target/javadoc-delombok" "$pkg_file" done # Combined javadoc (all modules) @@ -126,7 +134,7 @@ jobs: done sort -u "$combined_pkg_file" -o "$combined_pkg_file" echo "Generating combined javadoc for sdk-parent ..." - run_javadoc "$combined_sourcepath" "target/javadoc-delombok" "$combined_pkg_file" + run_javadoc "$JAVADOC" "$combined_sourcepath" "target/javadoc-delombok" "$combined_pkg_file" - name: "Assemble local-javadocs output directory" run: | @@ -134,23 +142,8 @@ jobs: rm -rf "$out_dir" mkdir -p "$out_dir" - module_paths=( - "core" - "orchestration" - "core-services/document-grounding" - "core-services/prompt-registry" - "foundation-models/openai" - "foundation-models/sap-rpt" - ) - - module_names=( - "AI Core client" - "Orchestration client" - "Document Grounding Client" - "Prompt Registry client" - "OpenAI client" - "SAP RPT Model Client" - ) + mapfile -t module_paths <<< "$MODULE_PATHS" + mapfile -t module_names <<< "$MODULE_NAMES" # Combined (parent) javadoc if [[ ! -f "target/javadoc-delombok/index.html" ]]; then From 252bf875769781013f0d9f2707593d939e0d8a0d Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Thu, 30 Apr 2026 18:31:44 +0200 Subject: [PATCH 24/33] fix major issue --- .github/workflows/javadoc.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/javadoc.yaml b/.github/workflows/javadoc.yaml index 9bd585d3d..dfe864fc7 100644 --- a/.github/workflows/javadoc.yaml +++ b/.github/workflows/javadoc.yaml @@ -113,9 +113,8 @@ jobs: exit 1 fi pkg_file="$module_path/target/javadoc-packages" - find "$delombok_dir" -name "*.java" \ - | xargs grep -l "^package " \ - | xargs grep "^package " \ + find "$delombok_dir" -name "*.java" -print0 \ + | xargs -r -0 grep -h "^package " \ | awk '{print $2}' | tr -d ';' | sort -u > "$pkg_file" echo "Generating javadoc for $module_path ..." run_javadoc "$JAVADOC" "$delombok_dir" "$module_path/target/javadoc-delombok" "$pkg_file" From 4dfafcbee3ee7f21b4f4f514bd594cf5428e430b Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Thu, 30 Apr 2026 19:21:45 +0200 Subject: [PATCH 25/33] additional fixes --- .github/workflows/javadoc.yaml | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/javadoc.yaml b/.github/workflows/javadoc.yaml index dfe864fc7..71e4d605d 100644 --- a/.github/workflows/javadoc.yaml +++ b/.github/workflows/javadoc.yaml @@ -62,14 +62,14 @@ jobs: run: | JAVADOC="$JAVA_HOME/bin/javadoc" - mapfile -t module_paths <<< "$MODULE_PATHS" + readarray -t module_paths < <(printf '%s' "$MODULE_PATHS") # Build classpath from all module jars + dependencies classpath="" for module_path in "${module_paths[@]}"; do cp_file="$module_path/target/cp.txt" mvn -B -ntp -f "$module_path/pom.xml" \ - dependency:build-classpath -Dmdep.outputFile=target/cp.txt -Dmdep.includeScope=compile \ + dependency:build-classpath -Dmdep.outputFile=target/cp.txt -Dmdep.includeScope=provided \ -Dgpg.skip=true -q module_jar=$(find "$module_path/target" -maxdepth 1 -name "*.jar" ! -name "*sources*" ! -name "*javadoc*" | head -1) if [[ -n "$module_jar" ]]; then @@ -77,7 +77,9 @@ jobs: fi if [[ -f "$cp_file" ]]; then cp_content=$(cat "$cp_file") - [[ -n "$cp_content" ]] && classpath+=":$cp_content" + if [[ -n "$cp_content" ]]; then + [[ -z "$classpath" ]] && classpath="$cp_content" || classpath+=":$cp_content" + fi fi done @@ -86,6 +88,7 @@ jobs: local sourcepath="$2" local destdir="$3" local pkg_file="$4" + local cp="$5" if [[ ! -s "$pkg_file" ]]; then echo "No packages found for $destdir, skipping" >&2 @@ -96,7 +99,7 @@ jobs: "$javadoc" \ -sourcepath "$sourcepath" \ -d "$destdir" \ - -classpath "$classpath" \ + -classpath "$cp" \ -quiet \ -Xdoclint:none \ -encoding UTF-8 \ @@ -117,7 +120,7 @@ jobs: | xargs -r -0 grep -h "^package " \ | awk '{print $2}' | tr -d ';' | sort -u > "$pkg_file" echo "Generating javadoc for $module_path ..." - run_javadoc "$JAVADOC" "$delombok_dir" "$module_path/target/javadoc-delombok" "$pkg_file" + run_javadoc "$JAVADOC" "$delombok_dir" "$module_path/target/javadoc-delombok" "$pkg_file" "$classpath" done # Combined javadoc (all modules) @@ -133,7 +136,7 @@ jobs: done sort -u "$combined_pkg_file" -o "$combined_pkg_file" echo "Generating combined javadoc for sdk-parent ..." - run_javadoc "$JAVADOC" "$combined_sourcepath" "target/javadoc-delombok" "$combined_pkg_file" + run_javadoc "$JAVADOC" "$combined_sourcepath" "target/javadoc-delombok" "$combined_pkg_file" "$classpath" - name: "Assemble local-javadocs output directory" run: | @@ -141,8 +144,8 @@ jobs: rm -rf "$out_dir" mkdir -p "$out_dir" - mapfile -t module_paths <<< "$MODULE_PATHS" - mapfile -t module_names <<< "$MODULE_NAMES" + readarray -t module_paths < <(printf '%s' "$MODULE_PATHS") + readarray -t module_names < <(printf '%s' "$MODULE_NAMES") # Combined (parent) javadoc if [[ ! -f "target/javadoc-delombok/index.html" ]]; then From 8bbf9305f01b15b2084ec7d6960ed9074b70f1f5 Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Thu, 30 Apr 2026 19:47:57 +0200 Subject: [PATCH 26/33] adding comments --- .github/workflows/javadoc.yaml | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/.github/workflows/javadoc.yaml b/.github/workflows/javadoc.yaml index 71e4d605d..8ebe666d6 100644 --- a/.github/workflows/javadoc.yaml +++ b/.github/workflows/javadoc.yaml @@ -62,19 +62,29 @@ jobs: run: | JAVADOC="$JAVA_HOME/bin/javadoc" + # Reconstruct the module list from the top-level env var. + # printf '%s' prevents <<< from adding an extra newline, which would produce a spurious empty element. readarray -t module_paths < <(printf '%s' "$MODULE_PATHS") - # Build classpath from all module jars + dependencies + # Build a classpath from all module JARs and their dependencies so javadoc can resolve cross-module type references. classpath="" for module_path in "${module_paths[@]}"; do cp_file="$module_path/target/cp.txt" + + # Write all compile- and provided-scope dependency JARs to cp.txt. + # provided-scope types (e.g. SAP Cloud SDK interfaces) must be on the classpath for javadoc to resolve them. mvn -B -ntp -f "$module_path/pom.xml" \ dependency:build-classpath -Dmdep.outputFile=target/cp.txt -Dmdep.includeScope=provided \ -Dgpg.skip=true -q + + # Add the module's own compiled JAR to the classpath. + # Exclude *-sources.jar and *-javadoc.jar produced by the release profile. module_jar=$(find "$module_path/target" -maxdepth 1 -name "*.jar" ! -name "*sources*" ! -name "*javadoc*" | head -1) if [[ -n "$module_jar" ]]; then [[ -z "$classpath" ]] && classpath="$module_jar" || classpath+=":$module_jar" fi + + # Append the dependency JARs from cp.txt to the classpath. if [[ -f "$cp_file" ]]; then cp_content=$(cat "$cp_file") if [[ -n "$cp_content" ]]; then @@ -83,6 +93,7 @@ jobs: fi done + # Runs the javadoc tool for a given source tree and writes HTML to destdir. run_javadoc() { local javadoc="$1" local sourcepath="$2" @@ -90,6 +101,7 @@ jobs: local pkg_file="$4" local cp="$5" + # Skip if no packages were found for this module. if [[ ! -s "$pkg_file" ]]; then echo "No packages found for $destdir, skipping" >&2 return @@ -108,13 +120,16 @@ jobs: @"$pkg_file" } - # Per-module javadocs + # Generate per-module javadocs from delomboked sources (Lombok annotations expanded to plain Java). for module_path in "${module_paths[@]}"; do delombok_dir="$module_path/target/delombok" if [[ ! -d "$delombok_dir" ]]; then echo "Missing delombok sources for $module_path" >&2 exit 1 fi + + # Extract unique package names from the module's Java files. + # -print0/-0: null-delimited to handle spaces in paths; -r: skip if no files; -h: omit filenames from output. pkg_file="$module_path/target/javadoc-packages" find "$delombok_dir" -name "*.java" -print0 \ | xargs -r -0 grep -h "^package " \ @@ -123,17 +138,20 @@ jobs: run_javadoc "$JAVADOC" "$delombok_dir" "$module_path/target/javadoc-delombok" "$pkg_file" "$classpath" done - # Combined javadoc (all modules) + # Generate a combined javadoc across all modules with a unified package index. combined_sourcepath="" combined_pkg_file="target/javadoc-all-packages" > "$combined_pkg_file" for module_path in "${module_paths[@]}"; do delombok_dir="$module_path/target/delombok" + # Colon-join all delombok dirs into a single sourcepath for javadoc. [[ -z "$combined_sourcepath" ]] \ && combined_sourcepath="$delombok_dir" \ || combined_sourcepath+=":$delombok_dir" + # Accumulate package names from all modules into one file. cat "$module_path/target/javadoc-packages" >> "$combined_pkg_file" done + # Deduplicate packages shared across modules. sort -u "$combined_pkg_file" -o "$combined_pkg_file" echo "Generating combined javadoc for sdk-parent ..." run_javadoc "$JAVADOC" "$combined_sourcepath" "target/javadoc-delombok" "$combined_pkg_file" "$classpath" @@ -144,16 +162,19 @@ jobs: rm -rf "$out_dir" mkdir -p "$out_dir" + # Reconstruct the module lists from the top-level env vars. + # printf '%s' prevents <<< from adding an extra newline, which would produce a spurious empty element. readarray -t module_paths < <(printf '%s' "$MODULE_PATHS") readarray -t module_names < <(printf '%s' "$MODULE_NAMES") - # Combined (parent) javadoc + # Copy the combined javadoc into the 'aggregate' subdirectory. if [[ ! -f "target/javadoc-delombok/index.html" ]]; then echo "Missing combined javadocs at target/javadoc-delombok" >&2 exit 1 fi cp -R "target/javadoc-delombok" "$out_dir/aggregate" + # Write an HTML index linking to the aggregate docs and each per-module doc. index_file="$out_dir/index.html" cat > "$index_file" <<'HTML' @@ -168,9 +189,11 @@ jobs:
      HTML + # Iterate over modules by index to pair each path with its display name. for i in "${!module_paths[@]}"; do module_path="${module_paths[$i]}" module_name="${module_names[$i]}" + # Replace '/' with '-' to use the module path as a flat directory name. module_id="${module_path//\//-}" src_dir="$module_path/target/javadoc-delombok" @@ -179,6 +202,7 @@ jobs: exit 1 fi + # Copy the module's javadoc into the output dir and add an index entry. cp -R "$src_dir" "$out_dir/$module_id" printf '
    • %s
    • \n' "$module_id" "$module_name" >> "$index_file" done From b5ec6ad331a62c01a0580722b458159268ca3015 Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Tue, 5 May 2026 16:52:40 +0200 Subject: [PATCH 27/33] automating the javadocs --- .github/workflows/javadoc.yaml | 71 ++++++++++++++++++++++++-- .github/workflows/perform-release.yaml | 21 ++++++++ .github/workflows/prepare-release.yaml | 21 ++++++++ 3 files changed, 110 insertions(+), 3 deletions(-) diff --git a/.github/workflows/javadoc.yaml b/.github/workflows/javadoc.yaml index 8ebe666d6..51cb7e5d5 100644 --- a/.github/workflows/javadoc.yaml +++ b/.github/workflows/javadoc.yaml @@ -1,15 +1,17 @@ -name: "Build Local Javadocs" +name: JavaDoc to Documentation Portal on: - workflow_call: + workflow_dispatch: inputs: branch: + description: 'Branch/Commit/Tag for JavaDoc' required: true - type: string + default: 'main' env: JAVA_VERSION: 21 MAVEN_CACHE_KEY: maven-dependencies MAVEN_CACHE_DIR: ~/.m2 + DOCS_REPO: SAP/ai-sdk MODULE_PATHS: | core orchestration @@ -221,3 +223,66 @@ jobs: name: local-javadocs path: target/local-javadocs/ retention-days: 7 + + - name: "Determine Version" + id: determine-version + run: | + VERSION="${{ inputs.branch }}" + VERSION="${VERSION#rel/}" + MAJOR_VERSION=$(echo "$VERSION" | cut -d '.' -f 1) + echo "CURRENT_VERSION=$VERSION" >> $GITHUB_OUTPUT + echo "MAJOR_VERSION=$MAJOR_VERSION" >> $GITHUB_OUTPUT + + - name: "Generate GitHub App token" + id: app-token + uses: actions/create-github-app-token@v3 + with: + client-id: ${{ secrets.SAP_AI_SDK_BOT_CLIENT_ID }} + private-key: ${{ secrets.SAP_AI_SDK_BOT_PRIVATE_KEY }} + owner: SAP + repositories: ai-sdk + permission-contents: write + permission-pull-requests: write + + - name: "Prepare Git" + run: | + git config --global user.email "cloudsdk@sap.com" + git config --global user.name "SAP Cloud SDK Bot" + + - name: "Checkout Docs Repository" + uses: actions/checkout@v6 + with: + repository: ${{ env.DOCS_REPO }} + path: .ai-sdk-docs + token: ${{ steps.app-token.outputs.token }} + + - name: "Create JavaDoc PR" + id: create-javadoc-pr + run: | + TARGET_DIR=.ai-sdk-docs/static/java-api/v${{ steps.determine-version.outputs.MAJOR_VERSION }} + + rm -rf "$TARGET_DIR" + mkdir -p "$TARGET_DIR" + cp -R target/local-javadocs/aggregate/. "$TARGET_DIR" + + cd .ai-sdk-docs + git add -A . + + CHANGED_FILES="$(git status -s)" + if [[ -z "$CHANGED_FILES" ]]; then + echo "[DEBUG] No changes to API docs detected, skipping Pull Request creation." + echo "CREATE_PR=false" >> $GITHUB_OUTPUT + exit 0 + fi + + BRANCH_NAME=java/release-docs-${{ steps.determine-version.outputs.CURRENT_VERSION }} + git switch --create "$BRANCH_NAME" + git commit -m "chore: Update JavaDocs for release ${{ steps.determine-version.outputs.CURRENT_VERSION }}" + git push origin "$BRANCH_NAME" + + PR_TITLE="Java: Update JavaDocs for release ${{ steps.determine-version.outputs.CURRENT_VERSION }}" + PR_BODY="Replace the contents of v${{ steps.determine-version.outputs.MAJOR_VERSION }} API docs with the latest release of the SDK." + PR_URL=$(gh pr create --title "$PR_TITLE" --body "$PR_BODY" --repo "${{ env.DOCS_REPO }}") + echo "PR: $PR_URL" >> $GITHUB_STEP_SUMMARY + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} diff --git a/.github/workflows/perform-release.yaml b/.github/workflows/perform-release.yaml index d3dee5df4..90259985d 100644 --- a/.github/workflows/perform-release.yaml +++ b/.github/workflows/perform-release.yaml @@ -29,6 +29,7 @@ jobs: outputs: code-branch: ${{ steps.determine-branch-names.outputs.CODE_BRANCH_NAME }} release-notes-branch: ${{ steps.determine-branch-names.outputs.RELEASE_NOTES_BRANCH_NAME }} + javadoc-branch: ${{ steps.determine-branch-names.outputs.JAVADOC_BRANCH_NAME }} release-tag: ${{ steps.determine-branch-names.outputs.RELEASE_TAG }} release-commit: ${{ steps.determine-branch-names.outputs.RELEASE_COMMIT }} runs-on: ubuntu-latest @@ -41,12 +42,14 @@ jobs: RELEASE_TAG=rel/$RELEASE_VERSION RELEASE_COMMIT=$(gh release view $RELEASE_TAG --repo ${{github.repository}} --json targetCommitish --jq '.targetCommitish') RELEASE_NOTES_BRANCH_NAME=java/release-notes-$RELEASE_VERSION + JAVADOC_BRANCH_NAME=java/release-docs-$RELEASE_VERSION echo "CODE_BRANCH_NAME=$CODE_BRANCH_NAME" >> $GITHUB_OUTPUT echo "RELEASE_VERSION=$RELEASE_VERSION" >> $GITHUB_OUTPUT echo "RELEASE_TAG=$RELEASE_TAG" >> $GITHUB_OUTPUT echo "RELEASE_COMMIT=$RELEASE_COMMIT" >> $GITHUB_OUTPUT echo "RELEASE_NOTES_BRANCH_NAME=$RELEASE_NOTES_BRANCH_NAME" >> $GITHUB_OUTPUT + echo "JAVADOC_BRANCH_NAME=$JAVADOC_BRANCH_NAME" >> $GITHUB_OUTPUT echo -e "[DEBUG] Current GITHUB_OUTPUT:\n$(cat $GITHUB_OUTPUT)" env: @@ -95,6 +98,18 @@ jobs: \"Build Cloud SDK Documentation\": [\"dependabot\"] } + - name: 'Check Whether JavaDoc PR Can Be Merged' + if: ${{ inputs.skip-pr-merge != 'true' }} + uses: ./.github/actions/pr-is-mergeable + with: + pr-ref: ${{ steps.determine-branch-names.outputs.JAVADOC_BRANCH_NAME }} + repo: ${{ env.DOCS_REPO }} + token: ${{ steps.app-token.outputs.token }} + excluded-check-runs: | + { + \"Build Cloud SDK Documentation\": [\"dependabot\"] + } + release: name: 'Release' needs: [prerequisites] @@ -163,3 +178,9 @@ jobs: run: gh pr merge --squash "${{ needs.prerequisites.outputs.release-notes-branch }}" --delete-branch --repo "${{ env.DOCS_REPO }}" env: GH_TOKEN: ${{ steps.app-token.outputs.token }} + + - name: 'Merge JavaDoc PR' + if: ${{ inputs.skip-pr-merge != 'true' }} + run: gh pr merge --squash "${{ needs.prerequisites.outputs.javadoc-branch }}" --delete-branch --repo "${{ env.DOCS_REPO }}" + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} diff --git a/.github/workflows/prepare-release.yaml b/.github/workflows/prepare-release.yaml index 72a7c46e2..255ee4677 100644 --- a/.github/workflows/prepare-release.yaml +++ b/.github/workflows/prepare-release.yaml @@ -149,6 +149,26 @@ jobs: env: GH_TOKEN: ${{ github.token }} + create-javadoc-aggregated-pr: + needs: [create-release] + name: 'Create Aggregated JavaDoc PR on Documentation Portal' + runs-on: ubuntu-latest + permissions: + actions: write # needed to trigger the javadoc workflow + statuses: write # needed to update the commit status + steps: + - name: 'Checkout repository' + uses: actions/checkout@v6 + with: + ref: ${{ needs.create-release.outputs.release-name }} + - name: 'Trigger workflow (ignore failures)' + uses: ./.github/actions/trigger-workflow + continue-on-error: true + with: + workflow: javadoc.yaml + workflow-ref: main + parameters: -f branch=${{ needs.create-release.outputs.release-name }} + create-release-notes-pr: name: 'Create Release Notes PR' needs: [bump-version, run-ci] @@ -284,6 +304,7 @@ jobs: PR_URL=$(gh pr create --title "feat: Release ${{ needs.bump-version.outputs.release-version }}" --body "## TODOs - [ ] Review the changes in [the release commit]($COMMIT_URL) - [ ] Review **and approve** the [Release Notes PR](${{ needs.create-release-notes-pr.outputs.pr-url }}) + - [ ] Review **and approve** the [JavaDoc PR](https://github.com/SAP/ai-sdk/pulls?q=is%3Aopen+is%3Apr+Update+JavaDocs) - [ ] Add release notes to the [Draft Release](${{ needs.create-release.outputs.release-url }}) and improve formatting - [ ] Review **and approve** this PR - [ ] Trigger the [Perform Release Workflow](${{ github.event.repository.html_url }}/actions/workflows/perform-release.yaml) From 899edc6dd5e2408e30d70f45743930a8dcc29f35 Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Tue, 5 May 2026 17:23:58 +0200 Subject: [PATCH 28/33] adding permission --- .github/workflows/javadoc.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/javadoc.yaml b/.github/workflows/javadoc.yaml index 51cb7e5d5..c9249e32a 100644 --- a/.github/workflows/javadoc.yaml +++ b/.github/workflows/javadoc.yaml @@ -7,6 +7,9 @@ on: required: true default: 'main' +permissions: + contents: read + env: JAVA_VERSION: 21 MAVEN_CACHE_KEY: maven-dependencies From f3062d27bb51e3d397c391bb299999243ec26697 Mon Sep 17 00:00:00 2001 From: Nourhan Islam Shata <163640161+n-o-u-r-h-a-n@users.noreply.github.com> Date: Tue, 5 May 2026 17:24:43 +0200 Subject: [PATCH 29/33] Potential fix for pull request finding 'CodeQL / Workflow does not contain permissions' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- .github/workflows/javadoc.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/javadoc.yaml b/.github/workflows/javadoc.yaml index c9249e32a..4ad1d6ae7 100644 --- a/.github/workflows/javadoc.yaml +++ b/.github/workflows/javadoc.yaml @@ -10,6 +10,9 @@ on: permissions: contents: read +permissions: + contents: read + env: JAVA_VERSION: 21 MAVEN_CACHE_KEY: maven-dependencies From 933fe1bfc2c95a68e6afa329e930bcd32221088b Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Tue, 5 May 2026 17:32:13 +0200 Subject: [PATCH 30/33] formatting --- .github/workflows/javadoc.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/javadoc.yaml b/.github/workflows/javadoc.yaml index 4ad1d6ae7..c9249e32a 100644 --- a/.github/workflows/javadoc.yaml +++ b/.github/workflows/javadoc.yaml @@ -10,9 +10,6 @@ on: permissions: contents: read -permissions: - contents: read - env: JAVA_VERSION: 21 MAVEN_CACHE_KEY: maven-dependencies From 24806ed6f5b3043795a375d13788a4d4c54318ef Mon Sep 17 00:00:00 2001 From: Nourhan Islam Shata <163640161+n-o-u-r-h-a-n@users.noreply.github.com> Date: Wed, 6 May 2026 14:35:19 +0200 Subject: [PATCH 31/33] Update .github/workflows/javadoc.yaml Co-authored-by: Jonas-Isr --- .github/workflows/javadoc.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/javadoc.yaml b/.github/workflows/javadoc.yaml index c9249e32a..22e51f659 100644 --- a/.github/workflows/javadoc.yaml +++ b/.github/workflows/javadoc.yaml @@ -274,7 +274,6 @@ jobs: CHANGED_FILES="$(git status -s)" if [[ -z "$CHANGED_FILES" ]]; then echo "[DEBUG] No changes to API docs detected, skipping Pull Request creation." - echo "CREATE_PR=false" >> $GITHUB_OUTPUT exit 0 fi From 82ed07942d0e8a7593af27d2cb6c47c0dabed9d0 Mon Sep 17 00:00:00 2001 From: Nourhan Islam Shata <163640161+n-o-u-r-h-a-n@users.noreply.github.com> Date: Wed, 6 May 2026 14:36:31 +0200 Subject: [PATCH 32/33] Update .github/workflows/javadoc.yaml Co-authored-by: Jonas-Isr --- .github/workflows/javadoc.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/javadoc.yaml b/.github/workflows/javadoc.yaml index 22e51f659..034078215 100644 --- a/.github/workflows/javadoc.yaml +++ b/.github/workflows/javadoc.yaml @@ -277,11 +277,13 @@ jobs: exit 0 fi + echo "Committing new JavaDocs" BRANCH_NAME=java/release-docs-${{ steps.determine-version.outputs.CURRENT_VERSION }} git switch --create "$BRANCH_NAME" git commit -m "chore: Update JavaDocs for release ${{ steps.determine-version.outputs.CURRENT_VERSION }}" git push origin "$BRANCH_NAME" + echo "Creating PR" PR_TITLE="Java: Update JavaDocs for release ${{ steps.determine-version.outputs.CURRENT_VERSION }}" PR_BODY="Replace the contents of v${{ steps.determine-version.outputs.MAJOR_VERSION }} API docs with the latest release of the SDK." PR_URL=$(gh pr create --title "$PR_TITLE" --body "$PR_BODY" --repo "${{ env.DOCS_REPO }}") From 52432858669e1480ede90708b13b9f6f092216d9 Mon Sep 17 00:00:00 2001 From: Nourhan Shata Date: Wed, 6 May 2026 14:41:21 +0200 Subject: [PATCH 33/33] release notes --- docs/release_notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/release_notes.md b/docs/release_notes.md index d0ec84d77..eabb0fd9d 100644 --- a/docs/release_notes.md +++ b/docs/release_notes.md @@ -16,7 +16,7 @@ ### 📈 Improvements -- +- Aggregated JavaDocs are now published on our [documentation portal](https://sap.github.io/ai-sdk/docs/java/overview-cloud-sdk-for-ai-java). ### 🐛 Fixed Issues