diff --git a/db.go b/db.go index 5769bee..725142b 100644 --- a/db.go +++ b/db.go @@ -19,6 +19,7 @@ import ( type Deployment struct { UUID string `json:"uuid"` GitHubURL string `json:"github_url"` + // Deprecated Branch string `json:"branch"` DocsPath string `json:"docs_path"` DeployURL string `json:"deployment_url"` @@ -96,8 +97,8 @@ func restoreDeployments() { // Check if the deployment directory exists and is not empty (except for Git files) if isEmptyOrOnlyGitFiles(deploymentDir) { log.Infof("Repository not cloned or incomplete for UUID %s. Cloning now...", dep.UUID) - _, repoURL := extractPRID(dep.GitHubURL) - if out, err := cloneRepo(repoURL, dep.Branch, deploymentDir); err != nil { + prNumber, repoURL := extractPRID(dep.GitHubURL) + if out, err := cloneRepo(repoURL, prNumber, deploymentDir); err != nil { log.Infof("Failed to clone repository for UUID %s: %v", dep.UUID, out) _, err2 := db.Exec("UPDATE deployments SET status = ?, error = ? WHERE uuid = ?", "failed", err.Error(), dep.UUID) if err2 != nil { diff --git a/handler.go b/handler.go index 5f25ad7..7da16ad 100644 --- a/handler.go +++ b/handler.go @@ -53,8 +53,8 @@ func createDeploymentHandler(w http.ResponseWriter, r *http.Request) { return } - _, repoURL := extractPRID(req.GitHubURL) - if err := checkRepoExists(repoURL, req.Branch); err != nil { + prID, repoURL := extractPRID(req.GitHubURL) + if err := checkRepoExists(repoURL, prID); err != nil { http.Error(w, fmt.Sprintf("Repository check failed: %v", err), http.StatusInternalServerError) return } @@ -78,10 +78,10 @@ func createDeploymentHandler(w http.ResponseWriter, r *http.Request) { log.Errorf("Failed to encode response: %v", err) } - startProcessing(newUUID, repoURL, req, deploymentDir, port) + startProcessing(newUUID, repoURL, prID, req, deploymentDir, port) } -func startProcessing(newUUID string, repoURL string, req Deployment, deploymentDir string, port int) { +func startProcessing(newUUID string, repoURL string, prNumber string, req Deployment, deploymentDir string, port int) { go func() { if err := ensureMintlifyInstalled(); err != nil { log.Infof("Failed to install Mintlify: %v", err) @@ -89,7 +89,7 @@ func startProcessing(newUUID string, repoURL string, req Deployment, deploymentD return } - if _, err := cloneRepo(repoURL, req.Branch, deploymentDir); err != nil { + if _, err := cloneRepo(repoURL, prNumber, deploymentDir); err != nil { log.Errorln(err) _, _ = db.Exec("UPDATE deployments SET status = ?, error = ? WHERE uuid = ?", "failed", err.Error(), newUUID) return diff --git a/repo.go b/repo.go index 88f4f39..b02e11f 100644 --- a/repo.go +++ b/repo.go @@ -8,44 +8,63 @@ import ( ) // checkRepoExists checks if the repository exists and is accessible -func checkRepoExists(repoURL, branch string) error { - cmd := exec.Command("git", "ls-remote", "--heads", repoURL, branch) +func checkRepoExists(repoURL, prNumber string) error { + prRef := fmt.Sprintf("refs/pull/%s/head", prNumber) + cmd := exec.Command("git", "ls-remote", "--exit-code", repoURL, prRef) output, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("repository check failed: %v, output: %s", err, string(output)) } - // If the branch exists, the output will contain the branch reference - if len(output) == 0 { - return fmt.Errorf("branch %s not found in repository", branch) - } - + log.Info("PR exists: " + prNumber) return nil } // cloneRepo clones the repository -func cloneRepo(repoURL, branch, dir string) (string, error) { - log.Info("About to clone repo. Repo url is " + repoURL) +func cloneRepo(repoURL, prNumber, dir string) (string, error) { + log.Info("About to clone repo. Repo URL: " + repoURL) + + // Clone the repository + cmd := exec.Command("git", "clone", repoURL, dir) + if err := runCommandWithPipe(cmd); err != nil { + return "", fmt.Errorf("failed to clone repo: %w", err) + } + + // Fetch the PR branch into a temporary branch + prBranch := "pr-" + prNumber + cmd = exec.Command("git", "-C", dir, "fetch", "origin", "pull/"+prNumber+"/head:"+prBranch) + if err := runCommandWithPipe(cmd); err != nil { + return "", fmt.Errorf("failed to fetch PR branch: %w", err) + } - cmd := exec.Command("git", "clone", "--depth", "1", "--branch", branch, repoURL, dir) + // Checkout the fetched PR branch + cmd = exec.Command("git", "-C", dir, "checkout", prBranch) + if err := runCommandWithPipe(cmd); err != nil { + return "", fmt.Errorf("failed to checkout PR branch: %w", err) + } + + log.Info("Repository cloned and PR branch checked out successfully: " + prBranch) + return "", nil +} +func runCommandWithPipe(cmd *exec.Cmd) error { // Create pipes for stdout and stderr stdoutPipe, err := cmd.StdoutPipe() if err != nil { - return "", fmt.Errorf("failed to create stdout pipe: %w", err) + return fmt.Errorf("failed to create stdout pipe: %w", err) } stderrPipe, err := cmd.StderrPipe() if err != nil { - return "", fmt.Errorf("failed to create stderr pipe: %w", err) + return fmt.Errorf("failed to create stderr pipe: %w", err) } // Start the command if err := cmd.Start(); err != nil { - return "", fmt.Errorf("failed to start command: %w", err) + return fmt.Errorf("failed to start command: %w", err) } - // Create a scanner to read stdout and stderr line by line + // Create scanners to read stdout and stderr stdoutScanner := bufio.NewScanner(stdoutPipe) stderrScanner := bufio.NewScanner(stderrPipe) @@ -59,15 +78,14 @@ func cloneRepo(repoURL, branch, dir string) (string, error) { // Log stderr in real-time go func() { for stderrScanner.Scan() { - log.Info(stderrScanner.Text()) + log.Warn(stderrScanner.Text()) } }() // Wait for the command to finish if err := cmd.Wait(); err != nil { - return err.Error(), fmt.Errorf("failed to clone repo %s on branch %s: %w", repoURL, branch, err) + return fmt.Errorf("command failed: %w", err) } - log.Info("Repository cloned successfully") - return "", nil + return nil }