Skip to content

Commit fc2689c

Browse files
committed
Shuffles files and starts tests
1 parent b30d4f1 commit fc2689c

File tree

8 files changed

+476
-84
lines changed

8 files changed

+476
-84
lines changed

tools/flakeguard/cmd/aggregate_results.go

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"github.com/briandowns/spinner"
1010
"github.com/rs/zerolog/log"
11+
"github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard/git"
1112
"github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard/reports"
1213
"github.com/spf13/cobra"
1314
)
@@ -25,16 +26,46 @@ var AggregateResultsCmd = &cobra.Command{
2526
codeOwnersPath, _ := cmd.Flags().GetString("codeowners-path")
2627
repoPath, _ := cmd.Flags().GetString("repo-path")
2728
repoURL, _ := cmd.Flags().GetString("repo-url")
28-
branchName, _ := cmd.Flags().GetString("branch-name")
29+
currentBranch, _ := cmd.Flags().GetString("current-branch")
30+
defaultBranch, _ := cmd.Flags().GetString("default-branch")
2931
headSHA, _ := cmd.Flags().GetString("head-sha")
3032
baseSHA, _ := cmd.Flags().GetString("base-sha")
33+
baseBranch, _ := cmd.Flags().GetString("base-branch")
3134
githubWorkflowName, _ := cmd.Flags().GetString("github-workflow-name")
3235
githubWorkflowRunURL, _ := cmd.Flags().GetString("github-workflow-run-url")
3336
reportID, _ := cmd.Flags().GetString("report-id")
3437
splunkURL, _ := cmd.Flags().GetString("splunk-url")
3538
splunkToken, _ := cmd.Flags().GetString("splunk-token")
3639
splunkEvent, _ := cmd.Flags().GetString("splunk-event")
3740

41+
userGitData := &git.Data{
42+
RepoPath: repoPath,
43+
RepoURL: repoURL,
44+
CurrentBranch: currentBranch,
45+
DefaultBranch: defaultBranch,
46+
HeadSHA: headSHA,
47+
}
48+
49+
gitData, err := git.InferData(userGitData)
50+
if err != nil {
51+
log.Error().Err(err).Msg("Error getting git data")
52+
os.Exit(ErrorExitCode)
53+
}
54+
55+
userGitHubData := &git.HubActionsData{
56+
IsOnGitHubActions: githubWorkflowName != "" && githubWorkflowRunURL != "",
57+
EventName: splunkEvent,
58+
BaseSHA: baseSHA,
59+
BaseBranch: baseBranch,
60+
WorkflowName: githubWorkflowName,
61+
WorkflowRunURL: githubWorkflowRunURL,
62+
}
63+
gitHubData, err := git.InferGitHubData(userGitHubData)
64+
if err != nil {
65+
log.Error().Err(err).Msg("Error getting GitHub data")
66+
os.Exit(ErrorExitCode)
67+
}
68+
3869
initialDirSize, err := getDirSize(resultsPath)
3970
if err != nil {
4071
log.Error().Err(err).Str("path", resultsPath).Msg("Error getting initial directory size")
@@ -58,12 +89,8 @@ var AggregateResultsCmd = &cobra.Command{
5889
resultsPath,
5990
reports.WithReportID(reportID),
6091
reports.WithSplunk(splunkURL, splunkToken, splunkEvent),
61-
reports.WithBranchName(branchName),
62-
reports.WithBaseSha(baseSHA),
63-
reports.WithHeadSha(headSHA),
64-
reports.WithRepoURL(repoURL),
65-
reports.WithGitHubWorkflowName(githubWorkflowName),
66-
reports.WithGitHubWorkflowRunURL(githubWorkflowRunURL),
92+
reports.WithGitData(gitData),
93+
reports.WithGitHubData(gitHubData),
6794
)
6895
if err != nil {
6996
s.Stop()
@@ -184,14 +211,16 @@ func init() {
184211
AggregateResultsCmd.Flags().StringP("codeowners-path", "", "", "Path to the CODEOWNERS file")
185212
AggregateResultsCmd.Flags().StringP("repo-path", "", ".", "The path to the root of the repository/project")
186213
AggregateResultsCmd.Flags().String("repo-url", "", "The repository URL")
187-
AggregateResultsCmd.Flags().String("branch-name", "", "Branch name for the test report")
188-
AggregateResultsCmd.Flags().String("head-sha", "", "Head commit SHA for the test report")
189-
AggregateResultsCmd.Flags().String("base-sha", "", "Base commit SHA for the test report")
190-
AggregateResultsCmd.Flags().String("github-workflow-name", "", "GitHub workflow name for the test report")
191-
AggregateResultsCmd.Flags().String("github-workflow-run-url", "", "GitHub workflow run URL for the test report")
192-
AggregateResultsCmd.Flags().String("report-id", "", "Optional identifier for the test report. Will be generated if not provided")
193-
AggregateResultsCmd.Flags().String("splunk-url", "", "Optional url to simultaneously send the test results to splunk")
194-
AggregateResultsCmd.Flags().String("splunk-token", "", "Optional Splunk HEC token to simultaneously send the test results to splunk")
214+
AggregateResultsCmd.Flags().String("current-branch", "", "Branch name for the test report (will be inferred using 'git' if not provided)")
215+
AggregateResultsCmd.Flags().String("default-branch", "", "Name of the default branch of the repo (will be inferred using 'git' if not provided)")
216+
AggregateResultsCmd.Flags().String("base-branch", "", "Base branch used during a PR merge (will be inferred using 'git' if not provided)")
217+
AggregateResultsCmd.Flags().String("head-sha", "", "Head commit SHA for the test report (will be inferred using 'git' if not provided)")
218+
AggregateResultsCmd.Flags().String("base-sha", "", "Base sha used during a PR merge (will be inferred using 'git' if not provided)")
219+
AggregateResultsCmd.Flags().String("github-workflow-name", "", "GitHub workflow name for the test report (will be inferred from github data if not provided)")
220+
AggregateResultsCmd.Flags().String("github-workflow-run-url", "", "GitHub workflow run URL for the test report (will be inferred from github data if not provided)")
221+
AggregateResultsCmd.Flags().String("report-id", "", "Optional identifier for the test report (will be generated if not provided)")
222+
AggregateResultsCmd.Flags().String("splunk-url", "", "Optional url to send the test results to splunk")
223+
AggregateResultsCmd.Flags().String("splunk-token", "", "Optional Splunk HEC token to send the test results to splunk")
195224
AggregateResultsCmd.Flags().String("splunk-event", "manual", "Optional Splunk event to send as the triggering event for the test results")
196225

197226
if err := AggregateResultsCmd.MarkFlagRequired("results-path"); err != nil {

tools/flakeguard/git/git.go

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package git
22

3+
// TODO: I found this a little too late, but we can probably make good use of https://github.com/go-git/go-git
4+
35
import (
46
"bytes"
57
"fmt"
@@ -9,6 +11,8 @@ import (
911
"strings"
1012
"syscall"
1113

14+
"dario.cat/mergo"
15+
"github.com/rs/zerolog/log"
1216
"github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard/utils"
1317
)
1418

@@ -186,3 +190,240 @@ func shouldExclude(excludes []string, item string) bool {
186190
}
187191
return false
188192
}
193+
194+
// Data holds standard git data we're interested in
195+
type Data struct {
196+
RepoPath string
197+
RepoURL string
198+
CurrentBranch string
199+
DefaultBranch string
200+
HeadSHA string
201+
userOverride bool
202+
}
203+
204+
// empty checks if the struct is empty with default values
205+
func (g *Data) empty() bool {
206+
return g.RepoPath == "" && g.CurrentBranch == "" && g.DefaultBranch == "" && g.HeadSHA == "" && g.RepoURL == ""
207+
}
208+
209+
// log prints out the inferred git data
210+
func (g *Data) log() {
211+
var (
212+
inferredAny bool
213+
logMsg = log.Debug()
214+
)
215+
216+
if g.RepoPath != "" {
217+
logMsg = logMsg.Str("repo path", g.RepoPath)
218+
inferredAny = true
219+
}
220+
if g.CurrentBranch != "" {
221+
logMsg = logMsg.Str("current branch", g.CurrentBranch)
222+
inferredAny = true
223+
}
224+
if g.DefaultBranch != "" {
225+
logMsg = logMsg.Str("default branch", g.DefaultBranch)
226+
inferredAny = true
227+
}
228+
if g.HeadSHA != "" {
229+
logMsg = logMsg.Str("head SHA", g.HeadSHA)
230+
inferredAny = true
231+
}
232+
if g.RepoURL != "" {
233+
logMsg = logMsg.Str("repo URL", g.RepoURL)
234+
inferredAny = true
235+
}
236+
if inferredAny {
237+
msg := "Inferred git data"
238+
if g.userOverride {
239+
msg += " with user provided overrides"
240+
}
241+
logMsg.Msg(msg)
242+
} else {
243+
log.Warn().Msg("No git data inferred")
244+
}
245+
}
246+
247+
// InferData uses 'git' to find out relevant git data about the repo we're in.
248+
// User provided data will override inferred data.
249+
func InferData(userProvidedData *Data) (*Data, error) {
250+
_, err := exec.LookPath("git")
251+
if err != nil {
252+
return nil, fmt.Errorf("git not installed: %w", err)
253+
}
254+
255+
cmd := exec.Command("git", "rev-parse", "--is-inside-work-tree")
256+
combinedOut, err := cmd.CombinedOutput()
257+
if err != nil {
258+
return nil, fmt.Errorf("not inside a git repository: %s: %w", combinedOut, err)
259+
}
260+
261+
var (
262+
stdOut strings.Builder
263+
stdErr strings.Builder
264+
gitData = &Data{}
265+
)
266+
defer gitData.log()
267+
268+
cmd = exec.Command("git", "rev-parse", "--show-toplevel")
269+
cmd.Stdout = &stdOut
270+
cmd.Stderr = &stdErr
271+
err = cmd.Run()
272+
if err != nil {
273+
return nil, fmt.Errorf("error getting repo path: %s: %w", stdErr.String(), err)
274+
}
275+
gitData.RepoPath = strings.TrimSpace(stdOut.String())
276+
277+
stdOut.Reset()
278+
stdErr.Reset()
279+
cmd = exec.Command("git", "rev-parse", "--abbrev-ref", "HEAD")
280+
cmd.Stdout = &stdOut
281+
cmd.Stderr = &stdErr
282+
err = cmd.Run()
283+
if err != nil {
284+
return nil, fmt.Errorf("error getting branch name: %s: %w", stdErr.String(), err)
285+
}
286+
gitData.CurrentBranch = strings.TrimSpace(stdOut.String())
287+
288+
stdOut.Reset()
289+
stdErr.Reset()
290+
cmd = exec.Command("git", "symbolic-ref", "refs/remotes/origin/HEAD")
291+
cmd.Stdout = &stdOut
292+
cmd.Stderr = &stdErr
293+
err = cmd.Run()
294+
if err != nil {
295+
return nil, fmt.Errorf("error getting default branch name: %s: %w", stdErr.String(), err)
296+
}
297+
gitData.DefaultBranch = strings.TrimSpace(strings.TrimPrefix(stdOut.String(), "refs/heads/"))
298+
299+
stdOut.Reset()
300+
stdErr.Reset()
301+
cmd = exec.Command("git", "rev-parse", "HEAD")
302+
cmd.Stdout = &stdOut
303+
cmd.Stderr = &stdErr
304+
err = cmd.Run()
305+
if err != nil {
306+
return nil, fmt.Errorf("error getting head SHA: %s: %w", stdErr.String(), err)
307+
}
308+
gitData.HeadSHA = strings.TrimSpace(stdOut.String())
309+
310+
stdOut.Reset()
311+
stdErr.Reset()
312+
cmd = exec.Command("git", "config", "--get", "remote.origin.url")
313+
cmd.Stdout = &stdOut
314+
cmd.Stderr = &stdErr
315+
err = cmd.Run()
316+
if err != nil {
317+
return nil, fmt.Errorf("error getting repo URL: %s: %w", stdErr.String(), err)
318+
}
319+
gitData.RepoURL = strings.TrimSpace(stdOut.String())
320+
321+
if userProvidedData != nil && !userProvidedData.empty() {
322+
gitData.userOverride = true
323+
if err = mergo.Merge(&gitData, userProvidedData, mergo.WithOverride); err != nil {
324+
return nil, fmt.Errorf("error merging user provided GitHub data: %w", err)
325+
}
326+
}
327+
return gitData, nil
328+
}
329+
330+
// HubActionsData holds GitHub Actions specific data we're interested in
331+
type HubActionsData struct {
332+
IsOnGitHubActions bool
333+
EventName string
334+
BaseSHA string
335+
BaseBranch string
336+
WorkflowName string
337+
WorkflowRunURL string
338+
userOverride bool
339+
}
340+
341+
// empty checks if the struct is empty with default values
342+
func (g *HubActionsData) empty() bool {
343+
return g.EventName == "" && g.BaseSHA == "" && g.BaseBranch == "" && g.WorkflowName == "" && g.WorkflowRunURL == ""
344+
}
345+
346+
// log prints out the inferred GitHub data
347+
func (g *HubActionsData) log() {
348+
if !g.IsOnGitHubActions {
349+
log.Debug().Msg("Not running on GitHub Actions")
350+
return
351+
}
352+
logMsg := log.Debug()
353+
if g.EventName != "" {
354+
logMsg = logMsg.Str("event name", g.EventName)
355+
}
356+
if g.BaseSHA != "" {
357+
logMsg = logMsg.Str("base SHA", g.BaseSHA)
358+
}
359+
if g.BaseBranch != "" {
360+
logMsg = logMsg.Str("base branch", g.BaseBranch)
361+
}
362+
if g.WorkflowName != "" {
363+
logMsg = logMsg.Str("workflow name", g.WorkflowName)
364+
}
365+
if g.WorkflowRunURL != "" {
366+
logMsg = logMsg.Str("workflow run URL", g.WorkflowRunURL)
367+
}
368+
msg := "Inferred GitHub Actions data"
369+
if g.userOverride {
370+
msg += " with user provided overrides"
371+
}
372+
logMsg.Msg(msg)
373+
}
374+
375+
// InferGitHubData checks if the code is running on GitHub Actions and infers some data from it.
376+
// User provided data will override inferred data.
377+
// GitHub runners have a lot of data exposed though environment variables.
378+
// https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables#default-environment-variables
379+
func InferGitHubData(userProvidedData *HubActionsData) (*HubActionsData, error) {
380+
const (
381+
isOnGitHubActions = "GITHUB_ACTIONS"
382+
eventName = "GITHUB_EVENT_NAME"
383+
baseRef = "GITHUB_BASE_REF"
384+
workflowName = "GITHUB_WORKFLOW"
385+
serverURL = "GITHUB_SERVER_URL"
386+
repo = "GITHUB_REPOSITORY"
387+
runID = "GITHUB_RUN_ID"
388+
prEventName = "pull_request"
389+
prTargetName = "pull_request_target"
390+
)
391+
var gitHubData = &HubActionsData{}
392+
defer gitHubData.log()
393+
394+
gitHubData.IsOnGitHubActions = os.Getenv(isOnGitHubActions) == "true"
395+
if !gitHubData.IsOnGitHubActions {
396+
return gitHubData, nil
397+
}
398+
gitHubData.EventName = strings.TrimSpace(os.Getenv(eventName))
399+
gitHubData.WorkflowName = strings.TrimSpace(os.Getenv(workflowName))
400+
gitHubData.WorkflowRunURL = fmt.Sprintf("%s/%s/actions/runs/%s", os.Getenv(serverURL), os.Getenv(repo), os.Getenv(runID))
401+
402+
// If we're not in a PR event, we don't need to infer any more data
403+
if gitHubData.EventName != prEventName && gitHubData.EventName != prTargetName {
404+
return gitHubData, nil
405+
}
406+
407+
gitHubData.BaseBranch = strings.TrimSpace(os.Getenv(baseRef))
408+
409+
var (
410+
stdOut strings.Builder
411+
stdErr strings.Builder
412+
)
413+
cmd := exec.Command("git", "rev-parse", fmt.Sprintf("origin/%s", gitHubData.BaseBranch)) //nolint:gosec
414+
cmd.Stdout = &stdOut
415+
cmd.Stderr = &stdErr
416+
err := cmd.Run()
417+
if err != nil {
418+
return nil, fmt.Errorf("error getting base SHA: %s: %w", stdErr.String(), err)
419+
}
420+
gitHubData.BaseSHA = strings.TrimSpace(stdOut.String())
421+
422+
if userProvidedData != nil && !userProvidedData.empty() {
423+
gitHubData.userOverride = true
424+
if err = mergo.Merge(&gitHubData, userProvidedData, mergo.WithOverride); err != nil {
425+
return nil, fmt.Errorf("error merging user provided GitHub data: %w", err)
426+
}
427+
}
428+
return gitHubData, nil
429+
}

0 commit comments

Comments
 (0)