Skip to content

fix: improve cloning by fetching PRs using pull/PR_NUMBER/head #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions db.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand Down Expand Up @@ -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 {
Expand Down
10 changes: 5 additions & 5 deletions handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -78,18 +78,18 @@ 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)
_, _ = db.Exec("UPDATE deployments SET status = ?, error = ? WHERE uuid = ?", "failed", err.Error(), newUUID)
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
Expand Down
54 changes: 36 additions & 18 deletions repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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
}