fix: add proper instrumentation to git clone for debugging
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
- Log clone request with work_dir, URL, and token presence - Log workspace state (is_git_repo, existing remote) - Log all decision points (pull vs clone, clear workspace) - Detect and clear non-empty non-git directories before clone - Capture both stdout and stderr for clone failures - Include exit code in error messages
This commit is contained in:
parent
83b5d1ebb4
commit
9cca5cc41b
@ -68,50 +68,97 @@ type CloneResult struct {
|
||||
func (g *GitOperations) CloneRepo(ctx context.Context, workDir, cloneURL string) *CloneResult {
|
||||
result := &CloneResult{}
|
||||
|
||||
g.logger.Info("git clone request",
|
||||
"work_dir", workDir,
|
||||
"clone_url", g.redactToken(cloneURL),
|
||||
"has_token", g.giteaToken != "")
|
||||
|
||||
if cloneURL == "" {
|
||||
result.Error = fmt.Errorf("git clone URL is required")
|
||||
g.logger.Error("git clone failed: empty URL")
|
||||
return result
|
||||
}
|
||||
|
||||
// Check if already a git repo with the correct remote
|
||||
if g.isGitRepo(ctx, workDir) {
|
||||
isRepo := g.isGitRepo(ctx, workDir)
|
||||
g.logger.Info("workspace check", "is_git_repo", isRepo, "work_dir", workDir)
|
||||
|
||||
if isRepo {
|
||||
currentRemote, err := g.runGitOutput(ctx, workDir, "config", "--get", "remote.origin.url")
|
||||
currentRemote = strings.TrimSpace(currentRemote)
|
||||
g.logger.Info("existing repo detected",
|
||||
"current_remote", g.redactToken(currentRemote),
|
||||
"expected_remote", g.redactToken(cloneURL),
|
||||
"remote_match", currentRemote == cloneURL,
|
||||
"remote_err", err)
|
||||
|
||||
if err == nil && currentRemote == cloneURL {
|
||||
// Pull latest changes
|
||||
g.logger.Info("pulling latest changes", "work_dir", workDir)
|
||||
if err := g.runGit(ctx, workDir, "pull", "--ff-only"); err != nil {
|
||||
// Pull failed but repo exists - continue with existing state
|
||||
g.logger.Debug("git pull failed, continuing with existing state", "error", err, "work_dir", workDir)
|
||||
g.logger.Warn("git pull failed, continuing with existing state",
|
||||
"error", err,
|
||||
"work_dir", workDir)
|
||||
}
|
||||
g.logger.Info("git clone complete (existing repo)", "cloned", false)
|
||||
return result
|
||||
}
|
||||
|
||||
// Different remote - clear and re-clone
|
||||
g.logger.Info("clearing workspace for re-clone", "work_dir", workDir)
|
||||
if err := g.clearDir(ctx, workDir); err != nil {
|
||||
result.Error = fmt.Errorf("clear workspace: %w", err)
|
||||
g.logger.Error("failed to clear workspace", "error", result.Error)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
// Check if directory exists and is non-empty (would cause clone to fail)
|
||||
if !isRepo {
|
||||
checkCmd := exec.CommandContext(ctx, "sh", "-c", fmt.Sprintf("ls -A %s 2>/dev/null | head -1", workDir))
|
||||
output, _ := checkCmd.Output()
|
||||
if len(strings.TrimSpace(string(output))) > 0 {
|
||||
g.logger.Warn("workspace not empty but not a git repo, clearing",
|
||||
"work_dir", workDir,
|
||||
"first_file", strings.TrimSpace(string(output)))
|
||||
if err := g.clearDir(ctx, workDir); err != nil {
|
||||
result.Error = fmt.Errorf("clear non-empty workspace: %w", err)
|
||||
g.logger.Error("failed to clear non-empty workspace", "error", result.Error)
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Inject token for authentication
|
||||
authCloneURL := cloneURL
|
||||
if g.giteaToken != "" {
|
||||
authCloneURL = strings.Replace(cloneURL, "https://", "https://token:"+g.giteaToken+"@", 1)
|
||||
} else {
|
||||
g.logger.Warn("no gitea token configured, clone may fail for private repos")
|
||||
}
|
||||
|
||||
// Clone the repository
|
||||
g.logger.Info("executing git clone", "work_dir", workDir)
|
||||
cmd := exec.CommandContext(ctx, "git", "clone", authCloneURL, workDir)
|
||||
var stderr bytes.Buffer
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = &stderr
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
errMsg := g.redactToken(stderr.String())
|
||||
result.Error = fmt.Errorf("git clone failed: %s: %s", err, errMsg)
|
||||
stdoutMsg := g.redactToken(stdout.String())
|
||||
result.Error = fmt.Errorf("git clone exit %v: %s", err, errMsg)
|
||||
g.logger.Error("git clone failed",
|
||||
"error", err,
|
||||
"stderr", errMsg,
|
||||
"stdout", stdoutMsg,
|
||||
"work_dir", workDir)
|
||||
return result
|
||||
}
|
||||
|
||||
result.Cloned = true
|
||||
g.logger.Info("git clone complete", "cloned", true, "work_dir", workDir)
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user