fix(updater): build in temp directory, replace old launcher binary, and cleanup temp

This commit is contained in:
CAtlas0784 committed 2026-10-30 21:31:53 +07:00
1 parent 0ec9f62857
commit 0a97749a1c
8 files changed
+281 -98

No files matched your search

+68 -1
View File
@@ -10,6 +10,8 @@ import (
"net/http"
"net/url"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"time"
@@ -87,7 +89,72 @@ func (g *GitService) UpdateLauncherProgress(version string) (bool, string) {
}
}
return false, "could not locate valid launcher update package"
// Mode 3: Build from source inside a temporary workspace, replace binary, and delete temp
return g.BuildAndUpdateFromSource(constant.LauncherBranch)
}
func (g *GitService) BuildAndUpdateFromSource(branch string) (bool, string) {
if branch == "" {
branch = constant.LauncherBranch
}
gitExe, err := ensureGit()
if err != nil {
return false, fmt.Sprintf("git is required for source update: %v", err)
}
// 1. Create clean temporary directory
tempDir, err := os.MkdirTemp("", "g-launcher-build-*")
if err != nil {
return false, fmt.Sprintf("create temp build directory: %v", err)
}
defer os.RemoveAll(tempDir) // Guarantee temporary directory is completely deleted
// 2. Clone repository into temp directory
cloneCmd := exec.Command(gitExe, "clone", "--depth", "1", "--branch", branch, constant.LauncherRepoURL, tempDir)
cloneCmd.Env = append(os.Environ(), "GIT_TERMINAL_PROMPT=0")
if out, err := cloneCmd.CombinedOutput(); err != nil {
return false, fmt.Sprintf("clone repository to temp: %v (%s)", err, strings.TrimSpace(string(out)))
}
// 3. Build frontend inside temp
frontendDir := filepath.Join(tempDir, "frontend")
npmInstall := exec.Command("npm", "install", "--no-audit", "--no-fund")
npmInstall.Dir = frontendDir
if out, err := npmInstall.CombinedOutput(); err != nil {
return false, fmt.Sprintf("npm install in temp: %v (%s)", err, strings.TrimSpace(string(out)))
}
npmBuild := exec.Command("npm", "run", "build")
npmBuild.Dir = frontendDir
if out, err := npmBuild.CombinedOutput(); err != nil {
return false, fmt.Sprintf("npm run build in temp: %v (%s)", err, strings.TrimSpace(string(out)))
}
// 4. Build Go binary inside temp
builtExePath := filepath.Join(tempDir, "bin", "G-Launcher.exe")
if err := os.MkdirAll(filepath.Dir(builtExePath), 0755); err != nil {
return false, fmt.Sprintf("create temp bin directory: %v", err)
}
goBuild := exec.Command("go", "build", "-tags", "production", "-trimpath", "-buildvcs=false", "-ldflags=-w -s -H windowsgui", "-o", builtExePath, ".")
goBuild.Dir = tempDir
if out, err := goBuild.CombinedOutput(); err != nil {
return false, fmt.Sprintf("go build in temp: %v (%s)", err, strings.TrimSpace(string(out)))
}
// 5. Replace current running binary with newly built binary
builtFile, err := os.Open(builtExePath)
if err != nil {
return false, fmt.Sprintf("open built launcher in temp: %v", err)
}
defer builtFile.Close()
if err := selfupdate.Apply(builtFile, selfupdate.Options{}); err != nil {
return false, fmt.Sprintf("apply launcher update: %v", err)
}
return true, ""
}
func (g *GitService) applyManifestUpdate(manifest launcherManifest) (bool, string) {