Generic git checkout (#1951)
This commit is contained in:
parent
81a9342b83
commit
21ffc73c4f
@ -19,6 +19,8 @@ import (
|
|||||||
"github.com/xanzy/go-gitlab"
|
"github.com/xanzy/go-gitlab"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const credentialsKey = "GIT_CREDENTIALS"
|
||||||
|
|
||||||
type Gitter interface {
|
type Gitter interface {
|
||||||
Checkout(repo, branchOrCommit string) error
|
Checkout(repo, branchOrCommit string) error
|
||||||
RepoDir() string
|
RepoDir() string
|
||||||
@ -43,15 +45,58 @@ func (g *binaryGitter) Checkout(repo, branchOrCommit string) error {
|
|||||||
return g.checkoutGithub(repo, branchOrCommit)
|
return g.checkoutGithub(repo, branchOrCommit)
|
||||||
} else if strings.Contains(repo, "gitlab") {
|
} else if strings.Contains(repo, "gitlab") {
|
||||||
err := g.checkoutGitLabPublic(repo, branchOrCommit)
|
err := g.checkoutGitLabPublic(repo, branchOrCommit)
|
||||||
if err != nil {
|
if err != nil && len(g.secrets[credentialsKey]) > 0 {
|
||||||
// If the public download fails, try getting it with tokens.
|
// If the public download fails, try getting it with tokens.
|
||||||
// Private downloads needs a token for api project listing, hence
|
// Private downloads needs a token for api project listing, hence
|
||||||
// the weird structure of this code.
|
// the weird structure of this code.
|
||||||
return g.checkoutGitLabPrivate(repo, branchOrCommit)
|
return g.checkoutGitLabPrivate(repo, branchOrCommit)
|
||||||
}
|
}
|
||||||
return nil
|
return err
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Repo host %v is not supported yet", repo)
|
if len(g.secrets[credentialsKey]) > 0 {
|
||||||
|
return g.checkoutAnyRemote(repo, branchOrCommit, true)
|
||||||
|
}
|
||||||
|
return g.checkoutAnyRemote(repo, branchOrCommit, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// This aims to be a generic checkout method. Currently only tested for bitbucket,
|
||||||
|
// see tests
|
||||||
|
func (g *binaryGitter) checkoutAnyRemote(repo, branchOrCommit string, useCredentials bool) error {
|
||||||
|
repoFolder := strings.ReplaceAll(strings.ReplaceAll(repo, "/", "-"), "https://", "")
|
||||||
|
g.folder = filepath.Join(os.TempDir(),
|
||||||
|
repoFolder+"-"+shortid.MustGenerate())
|
||||||
|
err := os.MkdirAll(g.folder, 0755)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assumes remote address format is git@gitlab.com:micro-test/monorepo-test.git
|
||||||
|
remoteAddr := fmt.Sprintf("https://%v", repo)
|
||||||
|
if useCredentials {
|
||||||
|
remoteAddr = fmt.Sprintf("https://%v@%v", g.secrets[credentialsKey], repo)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command("git", "clone", remoteAddr, "--depth=1", ".")
|
||||||
|
cmd.Dir = g.folder
|
||||||
|
outp, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Git clone failed: %v", string(outp))
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd = exec.Command("git", "fetch", "origin", branchOrCommit, "--depth=1")
|
||||||
|
cmd.Dir = g.folder
|
||||||
|
outp, err = cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Git fetch failed: %v", string(outp))
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd = exec.Command("git", "checkout", branchOrCommit)
|
||||||
|
cmd.Dir = g.folder
|
||||||
|
outp, err = cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Git checkout failed: %v", string(outp))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *binaryGitter) checkoutGithub(repo, branchOrCommit string) error {
|
func (g *binaryGitter) checkoutGithub(repo, branchOrCommit string) error {
|
||||||
@ -66,8 +111,8 @@ func (g *binaryGitter) checkoutGithub(repo, branchOrCommit string) error {
|
|||||||
}
|
}
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
req, _ := http.NewRequest("GET", url, nil)
|
req, _ := http.NewRequest("GET", url, nil)
|
||||||
if len(g.secrets["GIT_CREDENTIALS"]) > 0 {
|
if len(g.secrets[credentialsKey]) > 0 {
|
||||||
req.Header.Set("Authorization", "token "+g.secrets["GIT_CREDENTIALS"])
|
req.Header.Set("Authorization", "token "+g.secrets[credentialsKey])
|
||||||
}
|
}
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -151,7 +196,7 @@ func (g *binaryGitter) checkoutGitLabPublic(repo, branchOrCommit string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *binaryGitter) checkoutGitLabPrivate(repo, branchOrCommit string) error {
|
func (g *binaryGitter) checkoutGitLabPrivate(repo, branchOrCommit string) error {
|
||||||
git, err := gitlab.NewClient(g.secrets["GIT_CREDENTIALS"])
|
git, err := gitlab.NewClient(g.secrets[credentialsKey])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -173,7 +218,7 @@ func (g *binaryGitter) checkoutGitLabPrivate(repo, branchOrCommit string) error
|
|||||||
}
|
}
|
||||||
// Example URL:
|
// Example URL:
|
||||||
// https://gitlab.com/api/v3/projects/0000000/repository/archive?private_token=XXXXXXXXXXXXXXXXXXXX
|
// https://gitlab.com/api/v3/projects/0000000/repository/archive?private_token=XXXXXXXXXXXXXXXXXXXX
|
||||||
url := fmt.Sprintf("https://gitlab.com/api/v4/projects/%v/repository/archive?private_token=%v", projectID, g.secrets["GIT_CREDENTIALS"])
|
url := fmt.Sprintf("https://gitlab.com/api/v4/projects/%v/repository/archive?private_token=%v", projectID, g.secrets[credentialsKey])
|
||||||
|
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
req, _ := http.NewRequest("GET", url, nil)
|
req, _ := http.NewRequest("GET", url, nil)
|
||||||
|
Loading…
Reference in New Issue
Block a user