Keep recovery handoffs available after publication cancellation

This commit is contained in:
2026-11-03 00:12:30 +00:00
parent cd08a2892a
commit dfaa652098
9 changed files with 284 additions and 68 deletions

View File

@@ -8,6 +8,8 @@ import (
"io"
"os"
"path/filepath"
"strconv"
"strings"
"golang.org/x/mod/modfile"
@@ -17,6 +19,30 @@ import (
const releaseKitModule = "go.maximumdirect.net/releasekit"
const releaseKitCommand = releaseKitModule + "/cmd/releasekit"
// TemporaryExecutable recognizes executables in Go's temporary build layout,
// <work parent>/go-build<nonce>/b<action>/exe/<name>. Those paths disappear when
// the Go driver finishes and cannot provide a later native-command fallback.
func TemporaryExecutable(path string) bool {
exeDir := filepath.Dir(path)
if filepath.Base(exeDir) != "exe" {
return false
}
actionDir := filepath.Dir(exeDir)
action, ok := strings.CutPrefix(filepath.Base(actionDir), "b")
if !ok || action == "" {
return false
}
if _, err := strconv.ParseUint(action, 10, 64); err != nil {
return false
}
nonce, ok := strings.CutPrefix(filepath.Base(filepath.Dir(actionDir)), "go-build")
if !ok || nonce == "" {
return false
}
_, err := strconv.ParseUint(nonce, 10, 64)
return err == nil
}
// RecoveryTool returns module-selected Go arguments for a later invocation.
// An empty result means this module does not select ReleaseKit. API-only modules
// receive a private module root that outlives launcher-owned bootstraps.

View File

@@ -0,0 +1,22 @@
package gotool
import (
"path/filepath"
"testing"
)
func TestRecoveryFallbackExecutableLifetime(t *testing.T) {
for _, test := range []struct {
path string
temporary bool
}{
{filepath.Join("tmp", "go-build123456", "b001", "exe", "releasekit"), true},
{filepath.Join("cache", "go-build", "hash-d", "releasekit"), false},
{filepath.Join("tmp", "tools", "releasekit"), false},
{filepath.Join("workspace", "go-build-project", "b001", "exe", "releasekit"), false},
} {
if got := TemporaryExecutable(test.path); got != test.temporary {
t.Errorf("temporary executable %q = %t, want %t", test.path, got, test.temporary)
}
}
}