@@ -4,13 +4,16 @@ import (
44 "context"
55 "fmt"
66 "os"
7+ "time"
78
9+ "github.com/corecollectives/mist/github"
10+ "github.com/corecollectives/mist/models"
811 "github.com/go-git/go-git/v6"
912 "github.com/go-git/go-git/v6/plumbing"
1013 "github.com/rs/zerolog/log"
1114)
1215
13- func CloneRepo (ctx context.Context , url string , branch string , logFile * os.File , path string ) error {
16+ func CloneGitRepo (ctx context.Context , url string , branch string , logFile * os.File , path string ) error {
1417 _ , err := fmt .Fprintf (logFile , "[GIT]: Cloning into %s\n " , path )
1518 if err != nil {
1619 log .Warn ().Msg ("error logging into log file" )
@@ -30,3 +33,92 @@ func CloneRepo(ctx context.Context, url string, branch string, logFile *os.File,
3033
3134 return nil
3235}
36+
37+ func CloneRepo (ctx context.Context , appId int64 , logFile * os.File ) error {
38+ log .Info ().Int64 ("app_id" , appId ).Msg ("Starting repository clone" )
39+
40+ userId , err := models .GetUserIDByAppID (appId )
41+ if err != nil {
42+ return fmt .Errorf ("failed to get user id by app id: %w" , err )
43+ }
44+
45+ cloneURL , accessToken , shouldMigrate , err := models .GetAppCloneURL (appId , * userId )
46+ if err != nil {
47+ return fmt .Errorf ("failed to get clone URL: %w" , err )
48+ }
49+
50+ _ , _ , branch , _ , projectId , name , err := models .GetAppGitInfo (appId )
51+ if err != nil {
52+ return fmt .Errorf ("failed to fetch app: %w" , err )
53+ }
54+
55+ if shouldMigrate {
56+ log .Info ().Int64 ("app_id" , appId ).Msg ("Migrating legacy app to new git format" )
57+ // for legacy GitHub apps, we don't have a git_provider_id
58+ // we just update the git_clone_url
59+ err = models .UpdateAppGitCloneURL (appId , cloneURL , nil )
60+ if err != nil {
61+ log .Warn ().Err (err ).Int64 ("app_id" , appId ).Msg ("Failed to migrate app git info, continuing anyway" )
62+ }
63+ }
64+
65+ // construct authenticated clone URL if we have an access token
66+ repoURL := cloneURL
67+ if accessToken != "" {
68+ // insert token into the URL
69+ // for GitHub: https://x-access-token:TOKEN@github.com/user/repo.git
70+ // for GitLab: https://oauth2:TOKEN@gitlab.com/user/repo.git
71+ // for Bitbucket: https://x-token-auth:TOKEN@bitbucket.org/user/repo.git
72+ // for Gitea: https://TOKEN@gitea.com/user/repo.git
73+
74+ // simple approach: insert token after https://
75+ // if len(cloneURL) > 8 && cloneURL[:8] == "https://" {
76+ // repoURL = fmt.Sprintf("https://x-access-token:%s@%s", accessToken, cloneURL[8:])
77+ // }
78+ repoURL = github .CreateCloneUrl (accessToken , repoURL )
79+ }
80+
81+ path := fmt .Sprintf ("/var/lib/mist/projects/%d/apps/%s" , projectId , name )
82+
83+ if _ , err := os .Stat (path + "/.git" ); err == nil {
84+ log .Info ().Str ("path" , path ).Msg ("Repository already exists, removing directory" )
85+
86+ if err := os .RemoveAll (path ); err != nil {
87+ return fmt .Errorf ("failed to remove existing repository: %w" , err )
88+
89+ }
90+ }
91+
92+ if err := os .MkdirAll (path , 0o755 ); err != nil {
93+ return fmt .Errorf ("failed to create directory: %w" , err )
94+ }
95+
96+ log .Info ().Str ("clone_url" , cloneURL ).Str ("branch" , branch ).Str ("path" , path ).Msg ("Cloning repository" )
97+
98+ ctx , cancel := context .WithTimeout (ctx , 10 * time .Minute )
99+ defer cancel ()
100+
101+ // old command implementation
102+ //
103+ //
104+ // cmd := exec.CommandContext(ctx, "git", "clone", "--branch", branch, repoURL, path)
105+ // output, err := cmd.CombinedOutput()
106+ // lines := strings.Split(string(output), "\n")
107+ // for _, line := range lines {
108+ // if len(line) > 0 {
109+ // fmt.Fprintf(logFile, "[GIT] %s\n", line)
110+ // }
111+ // }
112+
113+ // new git sdk implementation
114+ err = CloneGitRepo (ctx , repoURL , branch , logFile , path )
115+ if err != nil {
116+ if ctx .Err () == context .DeadlineExceeded {
117+ return fmt .Errorf ("git clone timed out after 10 minutes" )
118+ }
119+ return fmt .Errorf ("error cloning repository: %v\n " , err )
120+ }
121+
122+ log .Info ().Int64 ("app_id" , appId ).Str ("path" , path ).Msg ("Repository cloned successfully" )
123+ return nil
124+ }
0 commit comments