Repository navigation
Delete build sources when builds finish and expire old builds - #545
Open
sjmiller609 wants to merge 1 commit into
Open
sjmiller609 wants to merge 1 commit into
sjmiller609 wants to merge 1 commit into
Conversation
sjmiller609
marked this pull request as ready for review
November 5, 2026 19:17
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 24b30b4. Configure here.
| // updateBuildComplete updates the build with final results | ||
| func (m *manager) updateBuildComplete(id string, status string, digest *string, errMsg *string, provenance *BuildProvenance, durationMS *int64) { | ||
| defer m.removeSource(id) | ||
|
|
There was a problem hiding this comment.
Source deleted before status persists
Low Severity
updateBuildComplete always removes source/ via defer, including when writeMetadata fails and the on-disk status stays queued or building. Startup recovery then treats the build as pending, cannot reopen the source, and fails it instead of retrying.
Reviewed by Cursor Bugbot for commit 24b30b4. Configure here.
This branch has not been deployed
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.


Summary
Build source tarballs were written world-readable (0644) under
builds/<id>/source/and never deleted. Build directories in general were never cleaned up. Sources can carry build-time secrets, so this left them on disk indefinitely.source/is created 0700 andsource.tar.gz0600.source/is removed when it reaches a terminal status (updateBuildComplete,CancelBuild). Nothing reads it after that.Startlaunches a goroutine, so startup isn't blocked. It runs immediately and then every 10 minutes:source/for every finished build, which also cleans up sources retained on existing hosts;builds/<id>/once itsmetadata.jsonhas been unchanged forbuild.retention.build.retention, default2h, must be positive. It only needs to cover clients reading a build's status and logs right after it finishes.hypeman build list/GET /builds/{id}only return builds within the retention window.Testing
go test -race ./lib/builds/andgo test ./cmd/api/config/pass.Note
Medium Risk
Changes secret-bearing artifact lifecycle and disk cleanup timing; misconfigured retention or GC bugs could delete sources/logs clients still expect, though queued/running builds are explicitly protected.
Overview
Build source tarballs were left on disk with loose permissions even though they can contain secrets. This PR tightens storage (
source/at0700,source.tar.gzat0600) and drops each build'ssource/as soon as the job is terminal (success/fail viaupdateBuildComplete, or cancel).A background GC starts with the build manager (immediate pass, then every 10 minutes): it strips
source/from any already-finished build (including leftovers on upgraded hosts), and removes the entirebuilds/{id}/tree oncemetadata.jsonhas been unchanged longer thanbuild.retention(default2h, validated in config). Queued and in-progress builds are never collected so restart recovery can still use their sources.Config examples and
lib/buildsdocs describe the new knob;Retentionis wired fromcmd/api/configinto the build manager. Tests cover permissions, source removal on complete/cancel, and GC behavior for pending vs recent vs expired builds.Reviewed by Cursor Bugbot for commit 24b30b4. Bugbot is set up for automated code reviews on this repo. Configure here.