build(javadoc): сборка без внешних ссылок по -PjavadocLinks=false и фолбэк на неё в CI - #4431
build(javadoc): сборка без внешних ссылок по -PjavadocLinks=false и фолбэк на неё в CI#4431nixel2007 wants to merge 3 commits into
Conversation
Сборка javadoc ходит в сеть: качает element-list с каждого сайта из -link, а плагин io.freefair.javadoc-links вдобавок ищет javadoc зависимостей в javadoc.io. Недоступность внешнего ресурса валит сборку, хотя к качеству кода отношения не имеет. * -PjavadocLinks=false собирает javadoc без внешних ссылок и без сети: плагин javadoc-links не применяется, ссылки на bsl-parser/mdclasses/antlr не добавляются. Проверки doclint при этом работают как обычно. * Сборка javadoc в CI (javadoc.yml, gh-pages.yml) повторяется при падении через .github/scripts/retry.sh. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NdJmu69RS4pKz5Jaw2mNbg
Повторять сборку с теми же ссылками бессмысленно, когда внешний ресурс лежит: в CI (javadoc.yml, gh-pages.yml) упавшая со ссылками сборка javadoc повторяется с -PjavadocLinks=false. Ошибка в самом javadoc воспроизводится и без ссылок, поэтому шаг по-прежнему падает. Скрипт .github/scripts/retry.sh больше не нужен и удалён. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NdJmu69RS4pKz5Jaw2mNbg
По `./gradlew check --dry-run` в графе только jacocoTestReport и spotless*; javadoc собирается отдельным workflow. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NdJmu69RS4pKz5Jaw2mNbg
📝 WalkthroughWalkthroughThe build adds a ChangesJavadoc link fallback
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/gh-pages.yml:
- Around line 30-38: Update the Javadoc fallback logic in
.github/workflows/gh-pages.yml lines 30-38 and .github/workflows/javadoc.yml
lines 50-58 so the retry with javadocLinks=false occurs only for confirmed
external-link-resolution failures; preserve and return the original non-zero
result for source compilation or doclint errors, preventing publication after
unrelated Javadoc failures.
In `@build.gradle.kts`:
- Around line 15-16: Make the io.freefair.javadoc-links declaration conditional
on javadocLinksEnabled so the disabled javadoc mode does not resolve the plugin
or require network access; update build.gradle.kts lines 15-16 and 32-39
accordingly, and revise CLAUDE.md lines 126-129 to document the conditional
behavior.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: b94ee007-0532-4e03-8d5c-d79046baf817
📒 Files selected for processing (4)
.github/workflows/gh-pages.yml.github/workflows/javadoc.ymlCLAUDE.mdbuild.gradle.kts
| # javadoc скачивает element-list с каждого сайта из -link (в том числе с javadoc.io, | ||
| # который периодически недоступен). Если сборка со ссылками упала, повторяем без них: | ||
| # документация опубликуется без перекрёстных ссылок на чужой javadoc. | ||
| - name: Build javadoc | ||
| run: ./gradlew --no-daemon javadoc | ||
| run: | | ||
| ./gradlew --no-daemon javadoc || { | ||
| echo "::warning::Сборка javadoc со внешними ссылками не удалась, повторяем без них" | ||
| ./gradlew --no-daemon javadoc -PjavadocLinks=false | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
Preserve the Javadoc quality gate during fallback.
Both workflows use any non-zero exit as evidence of an external-link failure. This can hide an unrelated Javadoc defect when the second build succeeds without links.
.github/workflows/gh-pages.yml#L30-L38: retry only confirmed external-link-resolution failures before publishing..github/workflows/javadoc.yml#L50-L58: return the original failure for source or doclint errors.
📍 Affects 2 files
.github/workflows/gh-pages.yml#L30-L38(this comment).github/workflows/javadoc.yml#L50-L58
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/gh-pages.yml around lines 30 - 38, Update the Javadoc
fallback logic in .github/workflows/gh-pages.yml lines 30-38 and
.github/workflows/javadoc.yml lines 50-58 so the retry with javadocLinks=false
occurs only for confirmed external-link-resolution failures; preserve and return
the original non-zero result for source compilation or doclint errors,
preventing publication after unrelated Javadoc failures.
| // Применяется условно, см. javadocLinksEnabled ниже. | ||
| id("io.freefair.javadoc-links") version "9.5.0" apply false |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== build.gradle.kts relevant lines =="
sed -n '1,70p' build.gradle.kts
echo
echo "== CLAUDE.md relevant lines =="
sed -n '118,134p' CLAUDE.md
echo
echo "== Gradle wrapper settings / plugins block =="
fd -a '.(gradle|gradle.properties)$' . | sed 's#^\./##'
for f in gradle.properties settings.gradle.kts settings.gradle; do
[ -f "$f" ] && { echo "--- $f"; sed -n '1,220p' "$f"; }
done
echo
echo "== search javadocLinks/usages =="
rg -n "javadocLinks|javadoc-links|javadoc.io|resolveJavadocLinks|external javadoc" . -SRepository: 1c-syntax/bsl-language-server
Length of output: 5380
🌐 Web query:
Gradle deprecatedPluginsSettings apply false still resolves plugins plugin repositories documentation
💡 Result:
Yes, using 'apply false' in the 'plugins {}' block still causes Gradle to resolve the plugin and add it to the build script's classpath [1][2][3]. The 'apply false' syntax tells Gradle to add the plugin to the classpath for availability without executing its 'apply' method on the current project [2][4][3]. This is a standard practice for managing plugin versions centrally in a root build script while applying them only to specific subprojects as needed [5][4]. Important Note on Precompiled Script Plugins: There is a specific, known issue regarding the use of 'apply false' within precompiled script plugins [6]. In these cases, 'apply false' is currently deprecated because it is misleading—the plugin is often still applied due to how precompiled script plugins behave [6][1]. According to Gradle documentation, this usage will result in an error starting in Gradle 10.0.0 [6]. If you are using 'apply false' in a standard build script (e.g., your root 'build.gradle' file), this remains a supported and correct way to manage dependencies without automatically applying the plugin [5][4].
Citations:
- 1: Plugins block apply plugins automatically despite "apply false" for precompiled script plugins gradle/gradle#14437
- 2: https://docs.gradle.org/9.0.0-rc-1/javadoc/org/gradle/plugin/use/PluginDependencySpec.html
- 3: https://stackoverflow.com/questions/79003183/the-purpose-of-adding-a-plugin-with-apply-false-to-the-root-project-with-versi
- 4: https://docs.gradle.org/8.2/userguide/plugins.html
- 5: https://docs.gradle.org/current/userguide/plugins_intermediate.html
- 6: https://docs.gradle.org/nightly/userguide/upgrading_version_9.html
🌐 Web query:
Gradle buildSrc plugin resolve behavior apply false pluginRepositories plugin resolution
💡 Result:
The plugins { id(...) apply false } syntax is primarily used in the root project's plugins block to manage plugin versions across a multi-project build without applying them immediately to the root project itself [1][2]. This allows subprojects to apply the plugins as needed (without specifying a version) [1][2]. Regarding its behavior and resolution within buildSrc and plugin repositories, the following points are critical: 1. buildSrc Isolation and Nature: buildSrc is a special directory that Gradle treats as an included build, compiled before the main build scripts [3][4]. Because of its specialized role, it behaves differently than standard included builds [3]. It is always present on the classpath of all build scripts, which can lead to interference if dependencies or plugins are declared there [3][5]. 2. Plugin Resolution: When you declare a plugin in a plugins { ... } block, Gradle uses the pluginManagement block (defined in settings.gradle) to resolve it [1][6]. The apply false modifier only affects the lifecycle of the plugin application in the current project; it does not change how the plugin is resolved or where the resolution configuration is pulled from [1][2]. 3. Repository Configuration: pluginManagement configuration (including repositories) in your main settings.gradle file does not automatically propagate to buildSrc [3][7]. buildSrc is an independent build and must have its own settings.gradle (or build.gradle configuration) to define where its plugins and dependencies are resolved [8][4][7]. If your plugin within buildSrc requires dependencies or other plugins, those must be resolvable via the repositories explicitly defined within the context of the buildSrc build itself [3][7]. 4. Practical Implications: - You cannot use the plugins block inside buildSrc to apply settings-level plugins, as buildSrc is evaluated after the main settings.gradle [9]. - If you experience resolution failures for plugins defined in buildSrc, ensure you have defined the necessary pluginRepositories (or repositories in build.gradle for internal dependencies) inside the buildSrc project itself, rather than relying solely on the main project's pluginManagement [3][7]. - If buildSrc behavior causes unexpected classpath pollution or resolution conflicts, the recommended alternative is to use a separate composite build (e.g., a build-logic directory) [3][5][10]. Unlike buildSrc, explicitly included builds participate in normal dependency and plugin resolution, avoiding the implicit, all-encompassing classpath behavior of buildSrc [3][5].
Citations:
- 1: https://docs.gradle.org/current/userguide/plugins_intermediate.html
- 2: https://docs.gradle.org/8.4/userguide/plugins.html
- 3: https://discuss.gradle.org/t/different-behaivor-between-buildsrc-and-include-build-build-logic/47705
- 4: https://docs.gradle.org/current/userguide/sharing_build_logic_between_subprojects.html
- 5: https://discuss.gradle.org/t/buildsrc-dependency-declarations-running-interference/50923
- 6: https://docs.gradle.org/2.14/userguide/plugins.html
- 7: buildSrc plugin cannot use more than one repository gradle/gradle#29610
- 8: https://stackoverflow.com/questions/78396405/where-can-i-define-a-repository-function-so-that-i-can-use-it-in-my-entire-gradl
- 9: https://discuss.gradle.org/t/applying-buildsrc-plugin-to-settings/51227
- 10: https://docs.gradle.org/9.4.0/userguide/pre_compiled_script_plugin_advanced.html
Make the no-network javadoc mode conditional.
apply false still resolves io.freefair.javadoc-links from gradlePluginPortal(), so ./gradlew javadoc -PjavadocLinks=false can still require network access. Move the plugin declaration behind the same javadocLinksEnabled check, and update the build comments and CLAUDE.md to match this behavior.
📍 Affects 2 files
build.gradle.kts#L15-L16(this comment)build.gradle.kts#L32-L39CLAUDE.md#L126-L129
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@build.gradle.kts` around lines 15 - 16, Make the io.freefair.javadoc-links
declaration conditional on javadocLinksEnabled so the disabled javadoc mode does
not resolve the plugin or require network access; update build.gradle.kts lines
15-16 and 32-39 accordingly, and revise CLAUDE.md lines 126-129 to document the
conditional behavior.
|



Описание
Сборка javadoc периодически падает из-за недоступности внешних ресурсов, хотя к качеству кода это отношения не имеет.
Основной источник — не наши три
-link, а плагинio.freefair.javadoc-links: задачаresolveJavadocLinksищет javadoc всех зависимостей в javadoc.io (сейчас это 105 ссылок) и добавляет ссылку на Java SE API. На каждую сборку javadoc приходится сотня обращений к внешним сайтам, и падение выглядит так:Что сделано:
-PjavadocLinks=false— сборка javadoc вообще без внешних ссылок и без сети. Реализовано не вычисткой ссылок, а неприменением плагина (apply false+ условныйapply), поэтому разом уходят и javadoc.io, и ссылка на Java SE, и сама сетевая задача; наши ссылки на bsl-parser/mdclasses/antlr закрыты тем же условием. Проверки doclint при этом работают как обычно — теряются только перекрёстные ссылки на чужой javadoc.javadoc.yml,gh-pages.yml): если сборка со ссылками упала, шаг повторяет её с этим флагом. Повторять с теми же ссылками смысла нет — когда внешний ресурс лежит, он лежит и на второй попытке.Проверка при этом не превращается в фикцию: ошибка в самом javadoc воспроизводится и без ссылок, поэтому шаг остаётся красным. Зелёным он становится только там, где виновата недоступность внешнего сайта, и в лог пишется
::warning::.Заодно поправлена строка в
CLAUDE.md: там утверждалось, что./gradlew checkгоняет javadoc, а поcheck --dry-runв графе толькоjacocoTestReportиspotless*— javadoc собирается отдельным workflow.Что проверено
./gradlew javadoc -PjavadocLinks=false— BUILD SUCCESSFUL, вjavadoc.optionsноль-link, задачиresolveJavadocLinksв графе нет.javadoc.optionsи те же 105 строк вjavadoc-links.options.bash -eна трёх исходах: ссылки живы → одна сборка; ссылки лежат → вторая проходит, шаг зелёный; ошибка в javadoc → падает и без ссылок, шаг красный.Полный прогон
./gradlew javadocсо ссылками в моём окружении зелёным получить не удалось: javadoc.io оттуда стабильно отдаёт 522/404. Это ровно тот сценарий, ради которого делался фолбэк, но означает, что «счастливый путь» проверен только по составу опций, а не сквозным прогоном.Связанные задачи
Closes
Чеклист
Общие
gradlew precommit) — не запускал: задача относится к диагностикам, их ресурсы и документация не менялисьДля диагностик
Дополнительно
Флаг работает и локально:
./gradlew javadoc -PjavadocLinks=false— быстрый способ прогнать doclint, когда сеть недоступна или внешние сайты лежат.🤖 Generated with Claude Code
https://claude.ai/code/session_01NdJmu69RS4pKz5Jaw2mNbg
Generated by Claude Code
Summary by CodeRabbit
Bug Fixes
Documentation