Use external temporary storage for release builds

This commit is contained in:
2026-10-06 01:00:11 +00:00
parent 4dee2841e0
commit 8b417760c6
8 changed files with 109 additions and 11 deletions

View File

@@ -5,10 +5,9 @@ import (
"fmt"
"io"
"os"
"path/filepath"
"strings"
"gitea.maximumdirect.net/eric/ReleaseKit/internal/candidate"
"gitea.maximumdirect.net/eric/ReleaseKit/internal/tempdir"
)
func CandidateCallback(spec *Spec, output io.Writer) func(context.Context, candidate.Candidate) error {
@@ -18,18 +17,11 @@ func CandidateCallback(spec *Spec, output io.Writer) func(context.Context, candi
selected := *spec
selected.Targets = append([]Target(nil), spec.Targets...)
return func(ctx context.Context, captured candidate.Candidate) error {
temporaryDir, err := os.MkdirTemp(filepath.Dir(captured.RepositoryDir), ".releasekit-candidate-build-")
temporaryDir, err := tempdir.Outside(captured.RepositoryDir, "releasekit-candidate-build-")
if err != nil {
return fmt.Errorf("create temporary candidate build output: %w", err)
}
defer os.RemoveAll(temporaryDir)
relative, err := filepath.Rel(captured.RepositoryDir, temporaryDir)
if err != nil {
return fmt.Errorf("verify temporary candidate build output: %w", err)
}
if relative == "." || relative != ".." && !strings.HasPrefix(relative, ".."+string(filepath.Separator)) {
return fmt.Errorf("temporary candidate build output %q is inside the repository", temporaryDir)
}
_, err = Build(ctx, Request{
RepositoryDir: captured.RepositoryDir,
Version: captured.Version,

View File

@@ -0,0 +1,33 @@
// Package tempdir allocates disposable storage outside a source worktree.
package tempdir
import (
"fmt"
"os"
"path/filepath"
"strings"
)
// Outside uses the system temporary directory and leaves cleanup to its caller.
func Outside(repositoryDir, pattern string) (string, error) {
directory, err := os.MkdirTemp("", pattern)
if err != nil {
return "", err
}
repository, err := filepath.Abs(repositoryDir)
if err == nil && !strings.EqualFold(filepath.VolumeName(repository), filepath.VolumeName(directory)) {
return directory, nil
}
if err == nil {
var relative string
relative, err = filepath.Rel(repository, directory)
if err == nil && (relative == "." || relative != ".." && !strings.HasPrefix(relative, ".."+string(filepath.Separator))) {
err = fmt.Errorf("temporary storage %q is inside repository %q; select an external temporary directory", directory, repository)
}
}
if err != nil {
os.RemoveAll(directory)
return "", err
}
return directory, nil
}