Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add gitbranch and sha into spaces payload #4734

Merged
merged 36 commits into from May 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
7da2236
Add gitbranch and sha into spaces payload
mehulkar Apr 26, 2023
305be40
rm debug
mehulkar Apr 27, 2023
084a1e7
comments
mehulkar Apr 27, 2023
5f1a8ae
Merge branch 'main' into mehulkar/turbo-1049-add-git-sha-and-branch-t…
mehulkar Apr 28, 2023
8cfeb18
return struct instead of tuple
mehulkar Apr 28, 2023
213b9f5
Use branch --show-current to get branch name instead
mehulkar Apr 28, 2023
0d57d8c
ONly use stdout, ignore stderr
mehulkar Apr 28, 2023
8d1db8d
git state
mehulkar Apr 28, 2023
4de2dbf
look up env vars more simply
mehulkar Apr 28, 2023
c8553ff
rm comment
mehulkar Apr 28, 2023
0975950
Merge branch 'main' into mehulkar/turbo-1049-add-git-sha-and-branch-t…
mehulkar Apr 28, 2023
9455443
Merge branch 'main' into mehulkar/turbo-1049-add-git-sha-and-branch-t…
mehulkar May 2, 2023
ef0621b
Move gitState to run summary instead of just spaces
mehulkar May 2, 2023
da9917a
add tests, fix key, remove newline char
mehulkar May 2, 2023
1e9d30d
Set CWD when getting git info
mehulkar May 2, 2023
dd4a603
compile err
mehulkar May 2, 2023
35dda2b
Merge branch 'main' into mehulkar/turbo-1049-add-git-sha-and-branch-t…
mehulkar May 2, 2023
c1e3d68
branch names can be anything
mehulkar May 2, 2023
bffe3ce
stringify at the end
mehulkar May 2, 2023
2199840
Merge branch 'main' into mehulkar/turbo-1049-add-git-sha-and-branch-t…
mehulkar May 2, 2023
21ff859
Use scm key/struct naming for run summary, keep git fields for spaces
mehulkar May 2, 2023
f1daab1
Fix tests
mehulkar May 2, 2023
c480e15
add unit tests for git branch/sha
mehulkar May 2, 2023
ced3468
more logging on fail
mehulkar May 2, 2023
23c13ac
print byte string correctly
mehulkar May 2, 2023
cdda67c
setup git first
May 2, 2023
9363c2e
Merge branch 'main' into mehulkar/turbo-1049-add-git-sha-and-branch-t…
May 2, 2023
6e5aa1c
yes
May 2, 2023
fae2b88
only set local git user in test, so it doesn't blow up dev machines
May 3, 2023
c443620
set local without flag
May 3, 2023
29410e3
set --global git config in tests and reset after
mehulkar May 3, 2023
b37ef03
Merge branch 'main' into mehulkar/turbo-1049-add-git-sha-and-branch-t…
May 3, 2023
ae52ed8
Merge branch 'main' into mehulkar/turbo-1049-add-git-sha-and-branch-t…
May 3, 2023
467feb2
show which cmd failed
May 3, 2023
90ee2f5
Ignore errors when no global config exists
May 3, 2023
9440bbe
Merge branch 'main' into mehulkar/turbo-1049-add-git-sha-and-branch-t…
May 3, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 16 additions & 6 deletions cli/internal/ci/vendors.go
Expand Up @@ -15,6 +15,12 @@ type Vendor struct {
Env vendorEnvs
// EvalEnv is key/value map of environment variables that can be used to quickly determine the vendor
EvalEnv map[string]string

// The name of the environment variable that contains the current git sha
ShaEnvVar string

// The name of the environment variable that contains the current checked out branch
BranchEnvVar string
}

// Vendors is a list of common CI/CD vendors (from https://github.com/watson/ci-info/blob/master/vendors.json)
Expand Down Expand Up @@ -107,9 +113,11 @@ var Vendors = []Vendor{
Env: vendorEnvs{Any: []string{"EAS_BUILD"}},
},
{
Name: "GitHub Actions",
Constant: "GITHUB_ACTIONS",
Env: vendorEnvs{Any: []string{"GITHUB_ACTIONS"}},
Name: "GitHub Actions",
Constant: "GITHUB_ACTIONS",
Env: vendorEnvs{Any: []string{"GITHUB_ACTIONS"}},
ShaEnvVar: "GITHUB_SHA",
BranchEnvVar: "GITHUB_REF_NAME",
},
{
Name: "GitLab CI",
Expand Down Expand Up @@ -224,9 +232,11 @@ var Vendors = []Vendor{
Env: vendorEnvs{Any: []string{"TRAVIS"}},
},
{
Name: "Vercel",
Constant: "VERCEL",
Env: vendorEnvs{Any: []string{"NOW_BUILDER", "VERCEL"}},
Name: "Vercel",
Constant: "VERCEL",
Env: vendorEnvs{Any: []string{"NOW_BUILDER", "VERCEL"}},
ShaEnvVar: "VERCEL_GIT_COMMIT_SHA",
BranchEnvVar: "VERCEL_GIT_COMMIT_REF",
},
{
Name: "Visual Studio App Center",
Expand Down
1 change: 1 addition & 0 deletions cli/internal/runsummary/format_json.go
Expand Up @@ -63,4 +63,5 @@ type nonMonorepoRunSummary struct {
EnvMode util.EnvMode `json:"envMode"`
ExecutionSummary *executionSummary `json:"execution,omitempty"`
Tasks []*TaskSummary `json:"tasks"`
SCM *scmState `json:"scm"`
}
2 changes: 2 additions & 0 deletions cli/internal/runsummary/run_summary.go
Expand Up @@ -64,6 +64,7 @@ type RunSummary struct {
EnvMode util.EnvMode `json:"envMode"`
ExecutionSummary *executionSummary `json:"execution,omitempty"`
Tasks []*TaskSummary `json:"tasks"`
SCM *scmState `json:"scm"`
}

// NewRunSummary returns a RunSummary instance
Expand Down Expand Up @@ -105,6 +106,7 @@ func NewRunSummary(
EnvMode: globalEnvMode,
Tasks: []*TaskSummary{},
GlobalHashSummary: globalHashSummary,
SCM: getSCMState(repoRoot),
},
ui: ui,
runType: runType,
Expand Down
41 changes: 41 additions & 0 deletions cli/internal/runsummary/scm_summary.go
@@ -0,0 +1,41 @@
package runsummary

import (
"github.com/vercel/turbo/cli/internal/ci"
"github.com/vercel/turbo/cli/internal/env"
"github.com/vercel/turbo/cli/internal/scm"
"github.com/vercel/turbo/cli/internal/turbopath"
)

type scmState struct {
Type string `json:"type"`
Sha string `json:"sha"`
Branch string `json:"branch"`
}

// getSCMState returns the sha and branch when in a git repo
// Otherwise it should return empty strings right now.
// We my add handling of other scms and non-git tracking in the future.
func getSCMState(dir turbopath.AbsoluteSystemPath) *scmState {
allEnvVars := env.GetEnvMap()

state := &scmState{Type: "git"}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I thought there was even the remotest chance that we would add alternative SCM support prior to removing this code I'd be asking for an enum.

If you're feeling industrious I'd head that direction, but very non-blocking.


// If we're in CI, try to get the values we need from environment variables
if ci.IsCi() {
vendor := ci.Info()
state.Sha = allEnvVars[vendor.ShaEnvVar]
state.Branch = allEnvVars[vendor.BranchEnvVar]
}

// Otherwise fallback to using `git`
if state.Branch == "" {
state.Branch = scm.GetCurrentBranch(dir)
}

if state.Sha == "" {
state.Sha = scm.GetCurrentSha(dir)
}

return state
}
7 changes: 5 additions & 2 deletions cli/internal/runsummary/spaces.go
Expand Up @@ -26,11 +26,11 @@ type spacesRunPayload struct {
RepositoryPath string `json:"repositoryPath,omitempty"` // where the command was invoked from
Context string `json:"context,omitempty"` // the host on which this Run was executed (e.g. Github Action, Vercel, etc)
Client spacesClientSummary `json:"client"` // Details about the turbo client
GitBranch string `json:"gitBranch"`
GitSha string `json:"gitSha"`

// TODO: we need to add these in
// originationUser string
// gitBranch string
// gitSha string
}

// spacesCacheStatus is the same as TaskCacheSummary so we can convert
Expand Down Expand Up @@ -64,13 +64,16 @@ func (rsm *Meta) newSpacesRunCreatePayload() *spacesRunPayload {
if name := ci.Constant(); name != "" {
context = name
}

return &spacesRunPayload{
StartTime: startTime,
Status: "running",
Command: rsm.synthesizedCommand,
RepositoryPath: rsm.repoPath.ToString(),
Type: "TURBO",
Context: context,
GitBranch: rsm.RunSummary.SCM.Branch,
GitSha: rsm.RunSummary.SCM.Sha,
Client: spacesClientSummary{
ID: "turbo",
Name: "Turbo",
Expand Down
27 changes: 27 additions & 0 deletions cli/internal/scm/scm.go
Expand Up @@ -7,6 +7,9 @@
package scm

import (
"os/exec"
"strings"

"github.com/pkg/errors"

"github.com/vercel/turbo/cli/internal/turbopath"
Expand Down Expand Up @@ -51,3 +54,27 @@ func FromInRepo(repoRoot turbopath.AbsoluteSystemPath) (SCM, error) {
}
return newFallback(dotGitDir.Dir())
}

// GetCurrentBranch returns the current branch
func GetCurrentBranch(dir turbopath.AbsoluteSystemPath) string {
cmd := exec.Command("git", []string{"branch", "--show-current"}...)
cmd.Dir = dir.ToString()

out, err := cmd.Output()
if err != nil {
return ""
}
return strings.TrimRight(string(out), "\n")
mehulkar marked this conversation as resolved.
Show resolved Hide resolved
}

// GetCurrentSha returns the current SHA
func GetCurrentSha(dir turbopath.AbsoluteSystemPath) string {
cmd := exec.Command("git", []string{"rev-parse", "HEAD"}...)
cmd.Dir = dir.ToString()

out, err := cmd.Output()
if err != nil {
return ""
}
return strings.TrimRight(string(out), "\n")
mehulkar marked this conversation as resolved.
Show resolved Hide resolved
}
136 changes: 136 additions & 0 deletions cli/internal/scm/scm_test.go
@@ -0,0 +1,136 @@
package scm

import (
"os"
"os/exec"
"testing"

"github.com/stretchr/testify/assert"
"github.com/vercel/turbo/cli/internal/fs"
"github.com/vercel/turbo/cli/internal/turbopath"
)

func TestGetCurrentBranchMain(t *testing.T) {
targetbranch := "main"
testDir := getTestDir(t, "myrepo")
originalName, originalEmail := getOriginalConfig(testDir)

// Setup git
gitCommand(t, testDir, []string{"config", "--global", "user.email", "turbo@vercel.com"})
gitCommand(t, testDir, []string{"config", "--global", "user.name", "Turbobot"})
gitCommand(t, testDir, []string{"init"})

gitCommand(t, testDir, []string{"checkout", "-B", targetbranch})
branch := GetCurrentBranch(testDir)
assert.Equal(t, branch, targetbranch)

// cleanup
gitRm(t, testDir)
gitCommand(t, testDir, []string{"config", "--global", "user.email", originalEmail})
gitCommand(t, testDir, []string{"config", "--global", "user.name", originalName})
}

func TestGetCurrentBranchNonMain(t *testing.T) {
targetbranch := "mybranch"
testDir := getTestDir(t, "myrepo")

originalName, originalEmail := getOriginalConfig(testDir)

// Setup git
gitCommand(t, testDir, []string{"config", "--global", "user.email", "turbo@vercel.com"})
gitCommand(t, testDir, []string{"config", "--global", "user.name", "Turbobot"})
gitCommand(t, testDir, []string{"init"})
gitCommand(t, testDir, []string{"checkout", "-B", targetbranch})

branch := GetCurrentBranch(testDir)
assert.Equal(t, branch, targetbranch)

// cleanup
gitRm(t, testDir)
gitCommand(t, testDir, []string{"config", "--global", "user.email", originalEmail})
gitCommand(t, testDir, []string{"config", "--global", "user.name", originalName})
}

func TestGetCurrentSHA(t *testing.T) {
testDir := getTestDir(t, "myrepo")
originalName, originalEmail := getOriginalConfig(testDir)

// Setup git
gitCommand(t, testDir, []string{"config", "--global", "user.email", "turbo@vercel.com"})
gitCommand(t, testDir, []string{"config", "--global", "user.name", "Turbobot"})
gitCommand(t, testDir, []string{"init"})

// initial sha is blank because there are no commits
initSha := GetCurrentSha(testDir)
assert.True(t, initSha == "", "initial sha is empty")

// first commit
gitCommand(t, testDir, []string{"commit", "--allow-empty", "-am", "new commit"})
sha1 := GetCurrentSha(testDir)
assert.True(t, sha1 != "sha on commit 1 is not empty")

// second commit
gitCommand(t, testDir, []string{"commit", "--allow-empty", "-am", "new commit"})
sha2 := GetCurrentSha(testDir)
assert.True(t, sha2 != "", "sha on commit 2 is not empty")
assert.True(t, sha2 != sha1, "sha on commit 2 changes from commit 1")

// cleanup
gitRm(t, testDir)
gitCommand(t, testDir, []string{"config", "--global", "user.email", originalEmail})
gitCommand(t, testDir, []string{"config", "--global", "user.name", originalName})
}

// Helper functions
func getTestDir(t *testing.T, testName string) turbopath.AbsoluteSystemPath {
defaultCwd, err := os.Getwd()
if err != nil {
t.Errorf("failed to get cwd: %v", err)
}
cwd, err := fs.CheckedToAbsoluteSystemPath(defaultCwd)
if err != nil {
t.Fatalf("cwd is not an absolute directory %v: %v", defaultCwd, err)
}

return cwd.UntypedJoin("testdata", testName)
}

func gitRm(t *testing.T, dir turbopath.AbsoluteSystemPath) {
cmd := exec.Command("rm", []string{"-rf", ".git"}...)
cmd.Dir = dir.ToString()
if out, err := cmd.Output(); err != nil {
t.Fatalf("Failed to cleanup git dir: %s\n%v", out, err)
}
}

func getOriginalConfig(cwd turbopath.AbsoluteSystemPath) (string, string) {
// Ignore errors. If there was an error, it's likely because there was no value for these
// configs (e.g. in CI), so git is returning non-zero status code. This is ok, and we'll use the
// zero-value empty strings.
name, _ := _gitCommand(cwd, []string{"config", "--global", "user.name"})
email, _ := _gitCommand(cwd, []string{"config", "--global", "user.name"})

return name, email
}

func gitCommand(t *testing.T, cwd turbopath.AbsoluteSystemPath, args []string) string {
out, err := _gitCommand(cwd, args)

if err != nil {
t.Fatalf("Failed git command %s: %s\n%v", args, out, err)
}

return string(out)
}

func _gitCommand(cwd turbopath.AbsoluteSystemPath, args []string) (string, error) {
cmd := exec.Command("git", args...)
cmd.Dir = cwd.ToString()
out, err := cmd.CombinedOutput()

if err != nil {
return "", err
}

return string(out), nil
}
Empty file.
1 change: 1 addition & 0 deletions turborepo-tests/integration/tests/dry_json/monorepo.t
Expand Up @@ -76,6 +76,7 @@ Setup
"globalCacheInputs",
"id",
"packages",
"scm",
"tasks",
"turboVersion",
"version"
Expand Down
Expand Up @@ -82,5 +82,10 @@ Setup
"globalPassthrough": null
}
}
]
],
"scm": {
"type": "git",
"sha": "[a-z0-9]+", (re)
"branch": ".+" (re)
}
}
Expand Up @@ -76,5 +76,10 @@ Setup
"globalPassthrough": null
}
}
]
],
"scm": {
"type": "git",
"sha": "[a-z0-9]+", (re)
"branch": ".+" (re)
}
}
Expand Up @@ -143,5 +143,10 @@ Setup
"globalPassthrough": null
}
}
]
],
"scm": {
"type": "git",
"sha": "[a-z0-9]+", (re)
"branch": ".+" (re)
}
}
20 changes: 20 additions & 0 deletions turborepo-tests/integration/tests/run_summary/monorepo.t
Expand Up @@ -29,7 +29,27 @@ Setup
$ FIRST=$(/bin/ls .turbo/runs/*.json | head -n1)
$ SECOND=$(/bin/ls .turbo/runs/*.json | tail -n1)

$ cat $FIRST | jq 'keys'
[
"envMode",
"execution",
"globalCacheInputs",
"id",
"packages",
"scm",
"tasks",
"turboVersion",
"version"
]

# some top level run summary validation
$ cat $FIRST | jq '.scm'
{
"type": "git",
"sha": "[a-z0-9]+", (re)
"branch": ".+" (re)
}

$ cat $FIRST | jq '.tasks | length'
2
$ cat $FIRST | jq '.version'
Expand Down