Skip to content

Commit

Permalink
fix(clone): use unique temp dir for workspace
Browse files Browse the repository at this point in the history
  • Loading branch information
CarlJi committed Sep 20, 2024
1 parent 05f2473 commit 6fdcfcc
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 56 deletions.
69 changes: 47 additions & 22 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package config

import (
"errors"
"fmt"
"os"
"path/filepath"
Expand Down Expand Up @@ -29,13 +30,15 @@ type RepoConfig struct {
}

type Refs struct {
// Org is the organization name, e.g. "qiniu"
Org string `json:"org,omitempty"`
// Repo is the repository name, e.g. "kodo"
Repo string `json:"repo,omitempty"`
// Host is the git provider, e.g. "github.com", "gitlab.com"
Host string `json:"host,omitempty"`
// CloneURL is the git clone url, e.g. "https://github.com/qiniu/kodo.git"
// Org, Repo, and Host form a set that will ultimately be combined into a CloneURL
// For example: Org="qiniu", Repo="kodo", Host="github.com"
// will generate CloneURL="https://github.com/qiniu/kodo.git"
//
// Alternatively, you can directly provide the CloneURL, which will be parsed into the corresponding Org, Repo, and Host
// Org, Repo, Host, and CloneURL are equivalent; only one set needs to be filled
Org string `json:"org,omitempty"`
Repo string `json:"repo,omitempty"`
Host string `json:"host,omitempty"`
CloneURL string `json:"cloneUrl,omitempty"`

// PathAlias is the location under $parentDir/reviewbot-code/$org-$repo-$num/
Expand Down Expand Up @@ -140,21 +143,10 @@ func NewConfig(conf string) (Config, error) {
return c, err
}

// parse cloneURL to org repo and host
re := regexp.MustCompile(`^(?:git@|https://)?([^:/]+)[:/]{1}(.*?)/(.*?)\.git$`)
for orgRepo, refConfig := range c.CustomConfig {
for k, ref := range refConfig.ExtraRefs {
if ref.CloneURL == "" {
continue
}
matches := re.FindStringSubmatch(ref.CloneURL)
if len(matches) != 4 {
return c, fmt.Errorf("failed to parse CloneURL, please check the format of %s", ref.CloneURL)
}
c.CustomConfig[orgRepo].ExtraRefs[k].Host = matches[1]
c.CustomConfig[orgRepo].ExtraRefs[k].Org = matches[2]
c.CustomConfig[orgRepo].ExtraRefs[k].Repo = matches[3]
}
// ============ validate and update the config ============

if err := c.parseCloneURLs(); err != nil {
return c, err
}

// set default value
Expand Down Expand Up @@ -329,3 +321,36 @@ func (*baseModifier) Modify(cfg *Linter) (*Linter, error) {

return &newCfg, nil
}

func (c *Config) parseCloneURLs() error {
re := regexp.MustCompile(`^(?:git@|https://)?([^:/]+)[:/]{1}(.*?)/(.*?)\.git$`)

for orgRepo, refConfig := range c.CustomConfig {
for k, ref := range refConfig.ExtraRefs {
if ref.CloneURL == "" {
continue
}

if err := c.parseAndUpdateCloneURL(re, orgRepo, k); err != nil {
return err
}
}
}

return nil
}

func (c *Config) parseAndUpdateCloneURL(re *regexp.Regexp, orgRepo string, k int) error {
ref := &c.CustomConfig[orgRepo].ExtraRefs[k]
matches := re.FindStringSubmatch(ref.CloneURL)
if len(matches) != 4 {
log.Errorf("failed to parse CloneURL, please check the format of %s", ref.CloneURL)
return errors.New("invalid CloneURL")
}

ref.Host = matches[1]
ref.Org = matches[2]
ref.Repo = matches[3]

return nil
}
28 changes: 17 additions & 11 deletions config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,22 @@ customConfig: # custom config for specific orgs or repos
golangci-lint:
enable: false

# temporary disable, will be enabled after fixing the go mod issue in kodo
qbox/kodoe-manager:
linters:
gomodcheck:
enable: false
qbox/zrs:
linters:
gomodcheck:
enable: false
extraRefs:
- org: qbox
repo: kodo
qbox/kodoe-manager:
extraRefs:
- org: qbox
repo: kodo
qbox/configcenter:
extraRefs:
- org: qbox
repo: kodo
qbox/logverse:
linters:
gomodcheck:
enable: false
extraRefs:
- org: qbox
repo: kodo

qbox/kodo:
linters:
Expand All @@ -56,6 +59,9 @@ customConfig: # custom config for specific orgs or repos
golangci-lint run --timeout=10m0s --allow-parallel-runners=true --print-issued-lines=false --out-format=line-number >> $ARTIFACT/lint.log 2>&1
qbox/kodo-ops:
extraRefs:
- org: qbox
repo: kodo
linters:
golangci-lint:
enable: true
Expand Down
45 changes: 22 additions & 23 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,13 +293,21 @@ func (s *Server) handle(ctx context.Context, event *github.PullRequestEvent) err
}
log.Infof("found %d files affected by pull request %d\n", len(pullRequestAffectedFiles), num)

defaultWorkdir, err := prepareRepoDir(org, repo, num)
defaultWorkDir, err := prepareRepoDir(org, repo, num)
if err != nil {
return fmt.Errorf("failed to prepare repo dir: %w", err)
}
defer func() {
if s.debug {
return // do not remove the repository in debug mode
}
if err := os.RemoveAll(defaultWorkDir); err != nil {
log.Errorf("failed to remove the repository , err : %v", err)
}
}()

r, err := s.gitClientFactory.ClientForWithRepoOpts(org, repo, gitv2.RepoOpts{
CopyTo: defaultWorkdir + "/" + repo,
CopyTo: defaultWorkDir + "/" + repo,
})
if err != nil {
log.Errorf("failed to create git client: %v", err)
Expand All @@ -326,26 +334,12 @@ func (s *Server) handle(ctx context.Context, event *github.PullRequestEvent) err
log.Infof("no .gitmodules file in repo %s", repo)
}

repoClients, err := s.PrepareExtraRef(org, repo, defaultWorkdir)
_, err = s.PrepareExtraRef(org, repo, defaultWorkDir)
if err != nil {
log.Errorf("failed to prepare and clone ExtraRef : %v", err)
return err
}

repoClients = append(repoClients, r)

defer func() {
if s.debug {
return // do not remove the repository in debug mode
}
for _, r := range repoClients {
err := r.Clean()
if err != nil {
log.Errorf("failed to remove the repository , err : %v", err)
}
}
}()

for name, fn := range linters.TotalPullRequestHandlers() {
linterConfig := s.config.GetLinterConfig(org, repo, name)

Expand Down Expand Up @@ -434,19 +428,24 @@ func prepareRepoDir(org, repo string, num int) (string, error) {
if err != nil {
return "", fmt.Errorf("failed to get user home dir: %w", err)
}
parentDir = filepath.Join(homeDir, "reviewbot-code", fmt.Sprintf("%s-%s-%d", org, repo, num))
parentDir = filepath.Join(homeDir, "reviewbot-code-workspace")
} else {
parentDir = filepath.Join("/tmp", "reviewbot-code", fmt.Sprintf("%s-%s-%d", org, repo, num))
parentDir = filepath.Join("/tmp", "reviewbot-code-workspace")
}

if err := os.MkdirAll(parentDir, 0o755); err != nil {
return "", fmt.Errorf("failed to create parent dir: %w", err)
}

return parentDir, nil
dir, err := os.MkdirTemp(parentDir, fmt.Sprintf("%s-%s-%d", org, repo, num))
if err != nil {
return "", fmt.Errorf("failed to create temp dir: %w", err)
}

return dir, nil
}

func (s *Server) PrepareExtraRef(org, repo, defaultWorkdir string) (repoClients []gitv2.RepoClient, err error) {
func (s *Server) PrepareExtraRef(org, repo, defaultWorkDir string) (repoClients []gitv2.RepoClient, err error) {
var repoCfg config.RepoConfig
config := s.config
if v, ok := config.CustomConfig[org]; ok {
Expand All @@ -472,9 +471,9 @@ func (s *Server) PrepareExtraRef(org, repo, defaultWorkdir string) (repoClients
log.Fatalf("failed to create git client factory: %v", err)
}

repoPath := defaultWorkdir + "/" + refConfig.Repo
repoPath := defaultWorkDir + "/" + refConfig.Repo
if refConfig.PathAlias != "" {
repoPath = defaultWorkdir + refConfig.PathAlias
repoPath = defaultWorkDir + refConfig.PathAlias
}
r, err := gitClient.ClientForWithRepoOpts(refConfig.Org, refConfig.Repo, gitv2.RepoOpts{
CopyTo: repoPath,
Expand Down

0 comments on commit 6fdcfcc

Please sign in to comment.