diff --git a/actions/runner_exec.go b/actions/runner_exec.go index f8289f55..aec5151e 100644 --- a/actions/runner_exec.go +++ b/actions/runner_exec.go @@ -199,9 +199,9 @@ func (runner *runnerImpl) applyEnvironment(env map[string]string) { if err != nil { log.Warningf("unable to get git ref: %v", err) } else { + log.Infof("using github ref: %s", ref) env["GITHUB_REF"] = ref } - } func (runner *runnerImpl) createGithubTarball() (io.Reader, error) { diff --git a/actions/runner_test.go b/actions/runner_test.go index a637074b..cd96aae2 100644 --- a/actions/runner_test.go +++ b/actions/runner_test.go @@ -49,20 +49,23 @@ func TestRunEvent(t *testing.T) { log.SetLevel(log.DebugLevel) for _, table := range tables { - runnerConfig := &RunnerConfig{ - Ctx: context.Background(), - WorkflowPath: table.workflowPath, - WorkingDir: "testdata", - EventName: table.eventName, - } - runner, err := NewRunner(runnerConfig) - assert.NilError(t, err, table.workflowPath) - - err = runner.RunEvent() - if table.errorMessage == "" { + table := table + t.Run(table.workflowPath, func(t *testing.T) { + runnerConfig := &RunnerConfig{ + Ctx: context.Background(), + WorkflowPath: table.workflowPath, + WorkingDir: "testdata", + EventName: table.eventName, + } + runner, err := NewRunner(runnerConfig) assert.NilError(t, err, table.workflowPath) - } else { - assert.ErrorContains(t, err, table.errorMessage) - } + + err = runner.RunEvent() + if table.errorMessage == "" { + assert.NilError(t, err, table.workflowPath) + } else { + assert.ErrorContains(t, err, table.errorMessage) + } + }) } } diff --git a/actions/testdata/env.workflow b/actions/testdata/env.workflow index 847d1d43..4cf7e10f 100644 --- a/actions/testdata/env.workflow +++ b/actions/testdata/env.workflow @@ -1,9 +1,17 @@ workflow "test" { on = "push" - resolves = ["test-action"] + resolves = [ + "test-action-repo", + "test-action-ref", + ] } -action "test-action" { +action "test-action-repo" { uses = "docker://alpine:3.9" runs = ["sh", "-c", "echo $GITHUB_REPOSITORY | grep '^nektos/act$'"] -} \ No newline at end of file +} + +action "test-action-ref" { + uses = "docker://alpine:3.9" + runs = ["sh", "-c", "echo $GITHUB_REF | grep '^refs/'"] +} diff --git a/common/git.go b/common/git.go index 502f2c83..03afea2a 100644 --- a/common/git.go +++ b/common/git.go @@ -1,13 +1,10 @@ package common import ( - "bufio" - "bytes" "errors" "fmt" "io/ioutil" "os" - "path" "path/filepath" "regexp" "strings" @@ -17,7 +14,6 @@ import ( log "github.com/sirupsen/logrus" git "gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-git.v4/plumbing" - yaml "gopkg.in/yaml.v2" ) var ( @@ -36,15 +32,16 @@ func FindGitRevision(file string) (shortSha string, sha string, err error) { return "", "", err } - ref, err := FindGitRef(file) + bts, err := ioutil.ReadFile(filepath.Join(gitDir, "HEAD")) if err != nil { return "", "", err } + var ref = strings.TrimSpace(strings.TrimPrefix(string(bts), "ref:")) var refBuf []byte if strings.HasPrefix(ref, "refs/") { // load commitid ref - refBuf, err = ioutil.ReadFile(fmt.Sprintf("%s/%s", gitDir, ref)) + refBuf, err = ioutil.ReadFile(filepath.Join(gitDir, ref)) if err != nil { return "", "", err } @@ -56,19 +53,6 @@ func FindGitRevision(file string) (shortSha string, sha string, err error) { return string(refBuf[:7]), strings.TrimSpace(string(refBuf)), nil } -// FindGitBranch get the current git branch -func FindGitBranch(file string) (string, error) { - ref, err := FindGitRef(file) - if err != nil { - return "", err - } - - // get branch name - branch := strings.TrimPrefix(ref, "refs/heads/") - log.Debugf("Found branch: %s", branch) - return branch, nil -} - // FindGitRef get the current git ref func FindGitRef(file string) (string, error) { gitDir, err := findGitDirectory(file) @@ -77,34 +61,46 @@ func FindGitRef(file string) (string, error) { } log.Debugf("Loading revision from git directory '%s'", gitDir) - // load HEAD ref - headFile, err := os.Open(fmt.Sprintf("%s/HEAD", gitDir)) + _, ref, err := FindGitRevision(file) if err != nil { return "", err } - defer func() { - headFile.Close() - }() - - headBuffer := new(bytes.Buffer) - _, err = headBuffer.ReadFrom(bufio.NewReader(headFile)) - if err != nil { - log.Error(err) - } - headBytes := headBuffer.Bytes() - - var ref string - head := make(map[string]string) - err = yaml.Unmarshal(headBytes, head) - if err != nil { - ref = string(headBytes) - } else { - ref = head["ref"] - } log.Debugf("HEAD points to '%s'", ref) - return strings.TrimSpace(ref), nil + // try tags first + tag, err := findGitPrettyRef(ref, gitDir, "refs/tags") + if err != nil || tag != "" { + return tag, err + } + // and then branches + return findGitPrettyRef(ref, gitDir, "refs/heads") +} + +func findGitPrettyRef(head, root, sub string) (string, error) { + var name string + var err = filepath.Walk(filepath.Join(root, sub), func(path string, info os.FileInfo, err error) error { + if err != nil { + return nil + } + if name != "" { + return nil + } + if info.IsDir() { + return nil + } + bts, err := ioutil.ReadFile(path) + if err != nil { + return err + } + var pointsTo = strings.TrimSpace(string(bts)) + if head == pointsTo { + name = strings.TrimPrefix(strings.Replace(path, root, "", 1), "/") + log.Debugf("HEAD matches %s", name) + } + return nil + }) + return name, err } // FindGithubRepo get the repo @@ -169,10 +165,10 @@ func findGitDirectory(fromFile string) (string, error) { if fi.Mode().IsDir() { dir = absPath } else { - dir = path.Dir(absPath) + dir = filepath.Dir(absPath) } - gitPath := path.Join(dir, ".git") + gitPath := filepath.Join(dir, ".git") fi, err = os.Stat(gitPath) if err == nil && fi.Mode().IsDir() { return gitPath, nil @@ -181,7 +177,6 @@ func findGitDirectory(fromFile string) (string, error) { } return findGitDirectory(filepath.Dir(dir)) - } // NewGitCloneExecutorInput the input for the NewGitCloneExecutor diff --git a/common/git_test.go b/common/git_test.go index 2dcc37a4..d1595108 100644 --- a/common/git_test.go +++ b/common/git_test.go @@ -6,10 +6,12 @@ import ( "io/ioutil" "os" "os/exec" + "path/filepath" "syscall" "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestFindGitSlug(t *testing.T) { @@ -61,6 +63,86 @@ func TestFindGitRemoteURL(t *testing.T) { assert.Equal(remoteURL, u) } +func TestGitFindRef(t *testing.T) { + basedir, err := ioutil.TempDir("", "act-test") + defer os.RemoveAll(basedir) + assert.NoError(t, err) + + for name, tt := range map[string]struct { + Prepare func(t *testing.T, dir string) + Assert func(t *testing.T, ref string, err error) + }{ + "new_repo": { + Prepare: func(t *testing.T, dir string) {}, + Assert: func(t *testing.T, ref string, err error) { + require.Error(t, err) + }, + }, + "new_repo_with_commit": { + Prepare: func(t *testing.T, dir string) { + require.NoError(t, gitCmd("-C", dir, "commit", "--allow-empty", "-m", "msg")) + }, + Assert: func(t *testing.T, ref string, err error) { + require.NoError(t, err) + require.Equal(t, "refs/heads/master", ref) + }, + }, + "current_head_is_tag": { + Prepare: func(t *testing.T, dir string) { + require.NoError(t, gitCmd("-C", dir, "commit", "--allow-empty", "-m", "commit msg")) + require.NoError(t, gitCmd("-C", dir, "tag", "v1.2.3")) + require.NoError(t, gitCmd("-C", dir, "checkout", "v1.2.3")) + }, + Assert: func(t *testing.T, ref string, err error) { + require.NoError(t, err) + require.Equal(t, "refs/tags/v1.2.3", ref) + }, + }, + "current_head_is_same_as_tag": { + Prepare: func(t *testing.T, dir string) { + require.NoError(t, gitCmd("-C", dir, "commit", "--allow-empty", "-m", "1.4.2 release")) + require.NoError(t, gitCmd("-C", dir, "tag", "v1.4.2")) + }, + Assert: func(t *testing.T, ref string, err error) { + require.NoError(t, err) + require.Equal(t, "refs/tags/v1.4.2", ref) + }, + }, + "current_head_is_not_tag": { + Prepare: func(t *testing.T, dir string) { + require.NoError(t, gitCmd("-C", dir, "commit", "--allow-empty", "-m", "msg")) + require.NoError(t, gitCmd("-C", dir, "tag", "v1.4.2")) + require.NoError(t, gitCmd("-C", dir, "commit", "--allow-empty", "-m", "msg2")) + }, + Assert: func(t *testing.T, ref string, err error) { + require.NoError(t, err) + require.Equal(t, "refs/heads/master", ref) + }, + }, + "current_head_is_another_branch": { + Prepare: func(t *testing.T, dir string) { + require.NoError(t, gitCmd("-C", dir, "checkout", "-b", "mybranch")) + require.NoError(t, gitCmd("-C", dir, "commit", "--allow-empty", "-m", "msg")) + }, + Assert: func(t *testing.T, ref string, err error) { + require.NoError(t, err) + require.Equal(t, "refs/heads/mybranch", ref) + }, + }, + } { + tt := tt + name := name + t.Run(name, func(t *testing.T) { + dir := filepath.Join(basedir, name) + require.NoError(t, os.MkdirAll(dir, 0755)) + require.NoError(t, gitCmd("-C", dir, "init")) + tt.Prepare(t, dir) + ref, err := FindGitRef(dir) + tt.Assert(t, ref, err) + }) + } +} + func gitCmd(args ...string) error { var stdout bytes.Buffer cmd := exec.Command("git", args...)