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

Introduce GIT_* environment variables to specify git metadata #188

Merged
merged 1 commit into from
Nov 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 59 additions & 31 deletions gitinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"bytes"
"fmt"
"log"
"os"
"os/exec"
Expand All @@ -24,61 +25,88 @@ type Git struct {
Branch string `json:"branch"`
}

// collectGitInfo runs several git commands to compose a Git object.
func collectGitInfo(ref string) *Git {
// collectGitInfo uses either environment variables or git commands to compose a Git metadata object.
func collectGitInfo(ref string) (*Git, error) {
gitCmds := map[string][]string{
"id": {"rev-parse", ref},
"branch": {"branch", "--format", "%(refname:short)", "--contains", ref},
"aname": {"show", "-s", "--format=%aN", ref},
"aemail": {"show", "-s", "--format=%aE", ref},
"cname": {"show", "-s", "--format=%cN", ref},
"cemail": {"show", "-s", "--format=%cE", ref},
"message": {"show", "-s", "--format=%s", ref},
}
results := map[string]string{}
gitPath, err := exec.LookPath("git")
if err != nil {
log.Printf("fail to look path of git: %v", err)
log.Print("git information is omitted")
return nil
"GIT_ID": {"rev-parse", ref},
"GIT_BRANCH": {"branch", "--format", "%(refname:short)", "--contains", ref},
"GIT_AUTHOR_NAME": {"show", "-s", "--format=%aN", ref},
"GIT_AUTHOR_EMAIL": {"show", "-s", "--format=%aE", ref},
"GIT_COMMITTER_NAME": {"show", "-s", "--format=%cN", ref},
"GIT_COMMITTER_EMAIL": {"show", "-s", "--format=%cE", ref},
"GIT_MESSAGE": {"show", "-s", "--format=%s", ref},
}

if ref != "HEAD" {
var gitPath string

if *allowGitFetch && ref != "HEAD" {
var err error
gitPath, err = exec.LookPath("git")
if err != nil {
return nil, fmt.Errorf("failed to look path of git: %v", err)
}

// make sure that the commit is in the local
// e.g. shallow cloned repository
_, _ = runCommand(gitPath, "fetch", "--depth=1", "origin", ref)
// ignore errors because we don't have enough information about the origin.
_, err = runCommand(gitPath, "fetch", "--depth=1", "origin", ref)
if err != nil {
return nil, fmt.Errorf("failed to fetch git ref %q: %v", ref, err)
}
}

for key, args := range gitCmds {
if key == "branch" {
// special case for the git branch name: load from multiple environment variables
if key == "GIT_BRANCH" {
if envBranch := loadBranchFromEnv(); envBranch != "" {
results[key] = envBranch
err := os.Setenv(key, envBranch)
if err != nil {
return nil, err
}
continue
}
}
if os.Getenv(key) != "" {
// metadata already available via environment variable
continue
}

if gitPath == "" {
var err error
gitPath, err = exec.LookPath("git")
if err != nil {
log.Printf("fail to look path of git: %v", err)
log.Print("git information is omitted")
return nil, nil
}
}

ret, err := runCommand(gitPath, args...)
if err != nil {
log.Printf(`fail to run "%s %s": %v`, gitPath, strings.Join(args, " "), err)
log.Print("git information is omitted")
return nil
return nil, nil
}

err = os.Setenv(key, ret)
if err != nil {
return nil, err
}
results[key] = ret
}

h := Head{
ID: firstLine(results["id"]),
AuthorName: firstLine(results["aname"]),
AuthorEmail: firstLine(results["aemail"]),
CommitterName: firstLine(results["cname"]),
CommitterEmail: firstLine(results["cemail"]),
Message: results["message"],
ID: os.Getenv("GIT_ID"),
AuthorName: os.Getenv("GIT_AUTHOR_NAME"),
AuthorEmail: os.Getenv("GIT_AUTHOR_EMAIL"),
CommitterName: os.Getenv("GIT_COMMITTER_NAME"),
CommitterEmail: os.Getenv("GIT_COMMITTER_EMAIL"),
Message: os.Getenv("GIT_MESSAGE"),
}
g := &Git{
Head: h,
Branch: firstLine(results["branch"]),
Branch: os.Getenv("GIT_BRANCH"),
}
return g

return g, nil
}

func runCommand(gitPath string, args ...string) (string, error) {
Expand Down
8 changes: 7 additions & 1 deletion goveralls.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ var (
ignore = flag.String("ignore", "", "Comma separated files to ignore")
insecure = flag.Bool("insecure", false, "Set insecure to skip verification of certificates")
uploadSource = flag.Bool("uploadsource", true, "Read local source and upload it to coveralls")
allowGitFetch = flag.Bool("allowgitfetch", true, "Perform a 'git fetch' when the reference is different than HEAD; used for GitHub Actions integration")
show = flag.Bool("show", false, "Show which package is being tested")
customJobID = flag.String("jobid", "", "Custom set job token")
jobNumber = flag.String("jobnumber", "", "Custom set job number")
Expand Down Expand Up @@ -412,12 +413,17 @@ func process() error {
return err
}

gitInfo, err := collectGitInfo(head)
if err != nil {
return err
}

j := Job{
RunAt: time.Now(),
RepoToken: repotoken,
ServicePullRequest: pullRequest,
Parallel: parallel,
Git: collectGitInfo(head),
Git: gitInfo,
SourceFiles: sourceFiles,
ServiceName: *service,
FlagName: *flagName,
Expand Down