Skip to content
This repository was archived by the owner on Jun 2, 2023. It is now read-only.

Commit 4436155

Browse files
committed
make new repo analysis under experiment
1 parent 472ac50 commit 4436155

File tree

17 files changed

+614
-94
lines changed

17 files changed

+614
-94
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ Configurate via `.env` file. Dev `.env` may be like this:
5050
REDIS_URL="redis://localhost:6379"
5151
API_URL="https://api.dev.golangci.com"
5252
WEB_ROOT="https://dev.golangci.com"
53-
USE_CONTAINER_EXECUTOR=1
53+
USE_CONTAINER_EXECUTOR_PERCENT=100
54+
USE_NEW_REPO_ANALYSIS_PERCENT=100
5455
ORCHESTRATOR_ADDR="http://127.0.0.1:8001"
5556
ORCHESTRATOR_TOKEN=secret_token
5657
```

app/analyze/analyzequeue/consume.go

+17-2
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,32 @@ package analyzequeue
22

33
import (
44
"fmt"
5-
"log"
65

6+
"github.com/golangci/golangci-shared/pkg/apperrors"
7+
"github.com/golangci/golangci-shared/pkg/config"
8+
"github.com/golangci/golangci-shared/pkg/logutil"
79
"github.com/golangci/golangci-worker/app/analyze/analyzequeue/consumers"
10+
"github.com/golangci/golangci-worker/app/analyze/processors"
11+
"github.com/golangci/golangci-worker/app/lib/experiments"
812
"github.com/golangci/golangci-worker/app/lib/queue"
913
)
1014

1115
func RegisterTasks() {
16+
log := logutil.NewStderrLog("repo analysis")
17+
log.SetLevel(logutil.LogLevelInfo)
18+
cfg := config.NewEnvConfig(log)
19+
et := apperrors.GetTracker(cfg, log, "worker")
20+
21+
trackedLog := apperrors.WrapLogWithTracker(log, nil, et)
22+
ec := experiments.NewChecker(cfg, trackedLog)
23+
24+
rpf := processors.NewRepoProcessorFactory(&processors.StaticRepoConfig{}, trackedLog)
25+
repoAnalyzer := consumers.NewAnalyzeRepo(ec, rpf)
26+
1227
server := queue.GetServer()
1328
err := server.RegisterTasks(map[string]interface{}{
1429
"analyzeV2": consumers.NewAnalyzePR().Consume,
15-
"analyzeRepo": consumers.NewAnalyzeRepo().Consume,
30+
"analyzeRepo": repoAnalyzer.Consume,
1631
})
1732
if err != nil {
1833
log.Fatalf("Can't register queue tasks: %s", err)

app/analyze/analyzequeue/consumers/analyze_repo.go

+37-6
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,32 @@ package consumers
22

33
import (
44
"context"
5-
"errors"
65
"fmt"
76
"os"
7+
"strings"
88
"time"
99

1010
"github.com/golangci/golangci-worker/app/analytics"
1111
"github.com/golangci/golangci-worker/app/analyze/processors"
12+
"github.com/golangci/golangci-worker/app/lib/experiments"
13+
"github.com/golangci/golangci-worker/app/lib/github"
14+
"github.com/pkg/errors"
1215
)
1316

1417
type AnalyzeRepo struct {
1518
baseConsumer
19+
20+
ec *experiments.Checker
21+
rpf *processors.RepoProcessorFactory
1622
}
1723

18-
func NewAnalyzeRepo() *AnalyzeRepo {
24+
func NewAnalyzeRepo(ec *experiments.Checker, rpf *processors.RepoProcessorFactory) *AnalyzeRepo {
1925
return &AnalyzeRepo{
2026
baseConsumer: baseConsumer{
2127
eventName: analytics.EventRepoAnalyzed,
2228
},
29+
ec: ec,
30+
rpf: rpf,
2331
}
2432
}
2533

@@ -36,7 +44,7 @@ func (c AnalyzeRepo) Consume(ctx context.Context, repoName, analysisGUID, branch
3644
return errors.New("repo analysis is disabled")
3745
}
3846

39-
_ = c.wrapConsuming(ctx, func() error {
47+
return c.wrapConsuming(ctx, func() error {
4048
var cancel context.CancelFunc
4149
// If you change timeout value don't forget to change it
4250
// in golangci-api stale analyzes checker
@@ -45,12 +53,35 @@ func (c AnalyzeRepo) Consume(ctx context.Context, repoName, analysisGUID, branch
4553

4654
return c.analyzeRepo(ctx, repoName, analysisGUID, branch)
4755
})
48-
49-
// Don't return error to machinery: we will retry this task ourself from golangci-api
50-
return nil
5156
}
5257

5358
func (c AnalyzeRepo) analyzeRepo(ctx context.Context, repoName, analysisGUID, branch string) error {
59+
parts := strings.Split(repoName, "/")
60+
repo := &github.Repo{
61+
Owner: parts[0],
62+
Name: parts[1],
63+
}
64+
if len(parts) != 2 {
65+
return fmt.Errorf("invalid repo name %s", repoName)
66+
}
67+
68+
if c.ec.IsActiveForAnalysis("use_new_repo_analysis", repo, false) {
69+
repoCtx := &processors.RepoContext{
70+
Ctx: ctx,
71+
AnalysisGUID: analysisGUID,
72+
Branch: branch,
73+
Repo: repo,
74+
}
75+
p, cleanup, err := c.rpf.BuildProcessor(repoCtx)
76+
if err != nil {
77+
return errors.Wrap(err, "failed to build repo processor")
78+
}
79+
defer cleanup()
80+
81+
p.Process(repoCtx)
82+
return nil
83+
}
84+
5485
p, err := processors.NewGithubGoRepo(ctx, processors.GithubGoRepoConfig{}, analysisGUID, repoName, branch)
5586
if err != nil {
5687
return fmt.Errorf("can't make github go repo processor: %s", err)

app/analyze/analyzequeue/consumers/base_consumer.go

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ func (c baseConsumer) wrapConsuming(ctx context.Context, f func() error) (err er
2727
defer func() {
2828
if r := recover(); r != nil {
2929
err = fmt.Errorf("panic recovered: %v, %s, source is %s", r, debug.Stack(), err)
30+
analytics.Log(ctx).Errorf("processing of %q task failed: %s", c.eventName, err)
3031
}
3132
}()
3233

app/analyze/processors/errors.go

+25
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
package processors
22

33
import (
4+
"errors"
5+
"os"
46
"strings"
57

68
"github.com/golangci/golangci-worker/app/lib/github"
79
)
810

11+
var (
12+
errNothingToAnalyze = errors.New("nothing to analyze")
13+
)
14+
915
type IgnoredError struct {
1016
Status github.Status
1117
StatusDesc string
@@ -24,3 +30,22 @@ func escapeErrorText(text string, secrets map[string]string) string {
2430

2531
return ret
2632
}
33+
34+
func buildSecrets() map[string]string {
35+
const hidden = "{hidden}"
36+
ret := map[string]string{}
37+
38+
for _, kv := range os.Environ() {
39+
parts := strings.Split(kv, "=")
40+
if len(parts) != 2 {
41+
continue
42+
}
43+
44+
v := parts[1]
45+
if len(v) >= 6 {
46+
ret[v] = hidden
47+
}
48+
}
49+
50+
return ret
51+
}

app/analyze/processors/executor.go

+20-75
Original file line numberDiff line numberDiff line change
@@ -3,80 +3,27 @@ package processors
33
import (
44
"context"
55
"fmt"
6-
"hash/fnv"
76
"os"
8-
"strconv"
9-
"strings"
107

8+
"github.com/golangci/golangci-shared/pkg/config"
119
"github.com/golangci/golangci-shared/pkg/logutil"
1210
"github.com/golangci/golangci-worker/app/lib/executors"
11+
"github.com/golangci/golangci-worker/app/lib/experiments"
1312
"github.com/golangci/golangci-worker/app/lib/github"
1413
"github.com/pkg/errors"
1514
)
1615

17-
func hash(s string) uint32 {
18-
h := fnv.New32a()
19-
_, _ = h.Write([]byte(s))
20-
return h.Sum32()
21-
}
22-
23-
func getEnabledRepoNamesForContainerExperiment() map[string]bool {
24-
repos := os.Getenv("CONTAINER_EXECUTOR_EXPERIMENT_REPOS")
25-
if repos == "" {
26-
return map[string]bool{}
27-
}
28-
29-
repoList := strings.Split(repos, ",")
30-
ret := map[string]bool{}
31-
for _, r := range repoList {
32-
ret[r] = true
33-
}
34-
35-
return ret
36-
}
37-
38-
func isContainerExecutorExperimentEnabled(repo *github.Repo) bool {
39-
enabledRepos := getEnabledRepoNamesForContainerExperiment()
40-
if enabledRepos[repo.FullName()] {
41-
return true
42-
}
43-
44-
percentStr := os.Getenv("CONTAINER_EXECUTOR_EXPERIMENT_PERCENT")
45-
if percentStr == "" {
46-
return false
16+
func makeExecutor(ctx context.Context, repo *github.Repo, forPull bool, log logutil.Log, ec *experiments.Checker) (executors.Executor, error) {
17+
if log == nil { // TODO: remove
18+
log = logutil.NewStderrLog("executor")
19+
log.SetLevel(logutil.LogLevelInfo)
4720
}
48-
49-
percent, err := strconv.Atoi(percentStr)
50-
if err != nil {
51-
return false
52-
}
53-
54-
if percent < 0 || percent > 100 {
55-
return false
56-
}
57-
58-
hash := hash(fmt.Sprintf("%s/%s", repo.Owner, repo.Name))
59-
return uint32(percent) > (hash % 100)
60-
}
61-
62-
func makeExecutor(ctx context.Context, repo *github.Repo) (executors.Executor, error) {
63-
var exec executors.Executor
64-
log := logutil.NewStderrLog("executor")
65-
log.SetLevel(logutil.LogLevelInfo)
66-
67-
var useContainerExecutor bool
68-
useCE := os.Getenv("USE_CONTAINER_EXECUTOR")
69-
if useCE != "" { //nolint:gocritic
70-
useContainerExecutor = useCE == "1"
71-
log.Infof("Container executor is enabled by env var: %t", useContainerExecutor)
72-
} else if isContainerExecutorExperimentEnabled(repo) {
73-
useContainerExecutor = true
74-
log.Infof("Container executor is enabled by experiment")
75-
} else {
76-
log.Infof("Container executor is disabled, use remote shell")
21+
if ec == nil { // TODO: remove
22+
cfg := config.NewEnvConfig(log)
23+
ec = experiments.NewChecker(cfg, log)
7724
}
7825

79-
if useContainerExecutor {
26+
if ec.IsActiveForAnalysis("use_container_executor", repo, forPull) {
8027
ce, err := executors.NewContainer(log)
8128
if err != nil {
8229
return nil, errors.Wrap(err, "can't build container executor")
@@ -85,19 +32,17 @@ func makeExecutor(ctx context.Context, repo *github.Repo) (executors.Executor, e
8532
if err = ce.Setup(ctx); err != nil {
8633
return nil, errors.Wrap(err, "failed to setup container executor")
8734
}
88-
exec = ce.WithWorkDir("/goapp")
89-
} else {
90-
s := executors.NewRemoteShell(
91-
os.Getenv("REMOTE_SHELL_USER"),
92-
os.Getenv("REMOTE_SHELL_HOST"),
93-
os.Getenv("REMOTE_SHELL_KEY_FILE_PATH"),
94-
)
95-
if err := s.SetupTempWorkDir(ctx); err != nil {
96-
return nil, fmt.Errorf("can't setup temp work dir: %s", err)
97-
}
35+
return ce.WithWorkDir("/goapp"), nil
36+
}
9837

99-
exec = s
38+
s := executors.NewRemoteShell(
39+
os.Getenv("REMOTE_SHELL_USER"),
40+
os.Getenv("REMOTE_SHELL_HOST"),
41+
os.Getenv("REMOTE_SHELL_KEY_FILE_PATH"),
42+
)
43+
if err := s.SetupTempWorkDir(ctx); err != nil {
44+
return nil, fmt.Errorf("can't setup temp work dir: %s", err)
10045
}
10146

102-
return exec, nil
47+
return s, nil
10348
}

app/analyze/processors/github_go_pr.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
"strings"
1010
"time"
1111

12-
"github.com/golangci/golangci-api/pkg/app/ensuredeps"
12+
"github.com/golangci/golangci-api/pkg/goenv/ensuredeps"
1313

1414
"github.com/golangci/golangci-worker/app/analytics"
1515
"github.com/golangci/golangci-worker/app/analyze/linters"
@@ -60,7 +60,7 @@ func newGithubGoPR(ctx context.Context, c *github.Context, cfg githubGoPRConfig,
6060

6161
if cfg.exec == nil {
6262
var err error
63-
cfg.exec, err = makeExecutor(ctx, &c.Repo)
63+
cfg.exec, err = makeExecutor(ctx, &c.Repo, true, nil, nil)
6464
if err != nil {
6565
return nil, fmt.Errorf("can't make executor: %s", err)
6666
}

app/analyze/processors/github_go_repo.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
"runtime/debug"
99
"strings"
1010

11-
"github.com/golangci/golangci-api/pkg/app/ensuredeps"
11+
"github.com/golangci/golangci-api/pkg/goenv/ensuredeps"
1212
"github.com/golangci/golangci-worker/app/analytics"
1313
"github.com/golangci/golangci-worker/app/analyze/linters"
1414
"github.com/golangci/golangci-worker/app/analyze/linters/golinters"
@@ -55,7 +55,7 @@ func NewGithubGoRepo(ctx context.Context, cfg GithubGoRepoConfig, analysisGUID,
5555

5656
if cfg.exec == nil {
5757
var err error
58-
cfg.exec, err = makeExecutor(ctx, repo)
58+
cfg.exec, err = makeExecutor(ctx, repo, true, nil, nil)
5959
if err != nil {
6060
return nil, fmt.Errorf("can't make executor: %s", err)
6161
}

0 commit comments

Comments
 (0)