Fix temp directories leaked by the update-gh-pages task (#240)#722
Merged
Conversation
The `updateGitHubPages` task created the `javadoc`, `html`, and `repoTemp` temporary directories via `LazyTempPath` directly under the system temp directory, with cleanup performed only eagerly (`UpdateGitHubPages.cleanup()` and `Repository.close()`). A failed build or a killed Gradle daemon leaked them permanently. `File.deleteOnExit()` cannot help — it does not delete non-empty directories. Create every such directory under a shared base directory (`<java.io.tmpdir>/io.spine.gradle.fs`) that is registered for recursive deletion via a single JVM shutdown hook, mirroring the approach of SpineEventEngine/base-libraries#671. The eager cleanup stays the primary mechanism; the shutdown hook is the safety net. Fixes #240. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR addresses leaked temporary directories created by the updateGitHubPages pipeline by routing all LazyTempPath directories under a shared base temp directory and ensuring a JVM-shutdown cleanup safety net.
Changes:
- Introduces
SpineTempDiras a shared parent directory underjava.io.tmpdir, with recursive deletion via a JVM shutdown hook. - Updates
LazyTempPathto create its temp directories underSpineTempDir.path. - Adds unit tests covering the new temp directory layout and lazy creation behavior.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| buildSrc/src/main/kotlin/io/spine/gradle/fs/SpineTempDir.kt | Adds shared base temp directory and shutdown-hook cleanup logic. |
| buildSrc/src/main/kotlin/io/spine/gradle/fs/LazyTempPath.kt | Routes temp directory creation through SpineTempDir and updates KDoc. |
| buildSrc/src/test/kotlin/io/spine/gradle/fs/LazyTempPathSpec.kt | Verifies LazyTempPath creates directories under the shared base dir. |
| buildSrc/src/test/kotlin/io/spine/gradle/fs/SpineTempDirSpec.kt | Verifies SpineTempDir.path location and lazy directory creation. |
| .agents/tasks/fix-temp-dirs-update-gh-pages.md | Adds the task record describing the approach, plan, and verification. |
- Give each JVM its own subdirectory under the `io.spine.gradle.fs` namespace (named after the PID), and delete only that subdirectory on shutdown. The shared namespace is no longer removed, so concurrent Gradle daemons can no longer wipe each other's in-flight temporary directories. - Fail fast with a clear message if `java.io.tmpdir` is unset, instead of an opaque NPE. - Clarify the `LazyTempPath` KDoc: cleanup is guaranteed on JVM (Gradle daemon) shutdown; eager task cleanup remains the primary mechanism. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
armiol
approved these changes
Jul 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The
updateGitHubPagestask created thejavadoc,html, andrepoTemptemporarydirectories (via
LazyTempPath) directly under the system temp directory, with cleanupperformed only eagerly —
UpdateGitHubPages.cleanup()(in afinally) andRepository.close()(viause {}). When a build fails, or the Gradle daemon is killed,before that cleanup runs, the directories leak permanently.
File.deleteOnExit()cannothelp here: it does not delete non-empty directories, and these always are.
Fixes #240.
How
Group every such directory under one recognizable base directory
(
<java.io.tmpdir>/io.spine.gradle.fs) and remove that base directory recursively via asingle JVM shutdown hook — mirroring the approach of
SpineEventEngine/base#671.
SpineTempDirlazily creates the base directory and registers the shutdown hookexactly once (
by lazy, synchronized). The hook logs tostderrif the recursivedelete does not fully succeed, so a failed cleanup is visible rather than silent.
LazyTempPathnow creates its directory underSpineTempDir.path(
createTempDirectory(SpineTempDir.path, prefix)); thejavadoc/html/repoTempcall sites are unchanged.
long-lived daemon); the shutdown hook is the safety net.
The issue's note about "migrating it to Kotlin" is already satisfied — this code is Kotlin.
(The legacy
scripts/publish-documentation/publish.shcreates a differentworkspacedirectory and is out of scope.)
Tests
LazyTempPathSpec(4 tests) — directories are created on first use, under the systemtemp dir, under the
io.spine.gradle.fsbase dir, and all instances share one parent.SpineTempDirSpec(2 tests) —SpineTempDir.pathresolves to<java.io.tmpdir>/io.spine.gradle.fsand exists after access.Verification
./gradlew -p buildSrc build— green (wholebuildSrcsuite; 6/6 newfstests pass)under JDK 17. (The repo root has no
buildtask; all code lives inbuildSrc.)kotlin-engineer,spine-code-review, andreview-docs— all APPROVE.🤖 Generated with Claude Code