From 08d4ffd06b43bdf7b27e7a91db6d871857f0661c Mon Sep 17 00:00:00 2001 From: Matthew Rose Date: Sat, 4 Dec 2021 20:57:18 +1000 Subject: [PATCH] fix: implement parsing for locally referenced actions in 'uses' Signed-off-by: Matthew Rose --- pkg/parser/parser.go | 43 ++++++++++++++++++++++++++++++----- pkg/parser/parser_test.go | 2 +- pkg/parser/testdata/uses.yaml | 3 +++ pkg/types/external_action.go | 21 ++++++++++++----- 4 files changed, 56 insertions(+), 13 deletions(-) diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index 9d75a51..7fc4af3 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -23,6 +23,7 @@ package parser import ( "io/ioutil" + "path/filepath" "regexp" "github.com/mitchellh/mapstructure" @@ -107,6 +108,37 @@ func parseOutputs(action *types.CompositeAction, data map[interface{}]interface{ return nil } +func tryMatchRemoteUses(text string) ([][]string, bool) { + regex := *regexp.MustCompile(`(.+)\/(.+)@(.+)`) + + res := regex.FindAllStringSubmatch(text, -1) + if res != nil { + return res, true + } + + return res, false +} + +func parseUses(ext *types.ExternalAction, uses string) error { + if remote, ok := tryMatchRemoteUses(uses); ok { + ext.Creator = remote[0][1] + ext.Name = remote[0][2] + ext.Version = remote[0][3] + ext.Local = false + + return nil + } + + // If remote regex doesn't match, assume its a local reference to an action + logrus.Debug("Matching local action reference") + + ext.Local = true + ext.LocalPath = &uses + ext.Name = filepath.Base(uses) + + return nil +} + func parseExternalActions(action *types.CompositeAction, data map[interface{}]interface{}) error { runs, ok := data["runs"].(map[string]interface{}) if !ok { @@ -139,13 +171,12 @@ func parseExternalActions(action *types.CompositeAction, data map[interface{}]in ext.StepID = stepID } - regex := *regexp.MustCompile(`(.+)\/(.+)@(.+)`) - res := regex.FindAllStringSubmatch(step["uses"].(string), -1) + err := parseUses(&ext, step["uses"].(string)) + if err != nil { + return errors.Wrap(err, "couldn't parse the value in the 'uses' field") + } - // There should only be one match - ext.Creator = res[0][1] - ext.Name = res[0][2] - ext.Version = res[0][3] + logrus.Debug(ext) action.AddExternalAction(ext) } diff --git a/pkg/parser/parser_test.go b/pkg/parser/parser_test.go index 0197fc2..7e8225c 100644 --- a/pkg/parser/parser_test.go +++ b/pkg/parser/parser_test.go @@ -71,7 +71,7 @@ func TestParseUses(t *testing.T) { t.Fatal(err) } - assert.Len(t, action.Uses, 3) + assert.Len(t, action.Uses, 4) } func TestInvalidFiles(t *testing.T) { diff --git a/pkg/parser/testdata/uses.yaml b/pkg/parser/testdata/uses.yaml index 3a48b7b..04be079 100644 --- a/pkg/parser/testdata/uses.yaml +++ b/pkg/parser/testdata/uses.yaml @@ -21,3 +21,6 @@ runs: uses: actions/cache@v2.1.6 with: path: ./ + - name: Local + id: cache-test + uses: ./.github/actions/test-action-dir diff --git a/pkg/types/external_action.go b/pkg/types/external_action.go index ce2cc67..5ce791d 100644 --- a/pkg/types/external_action.go +++ b/pkg/types/external_action.go @@ -25,13 +25,22 @@ import "fmt" // ExternalAction represents a single external action that is used by the composite action. type ExternalAction struct { - Creator string - Name string - Version string - StepName string - StepID string + Creator string + Name string + Version string + StepName string + StepID string + Local bool + LocalPath *string } func (e ExternalAction) GetLink() string { - return fmt.Sprintf("https://github.com/%s/%s/tree/%s", e.Creator, e.Name, e.Version) + switch e.Local { + case true: + return *e.LocalPath + case false: + return fmt.Sprintf("https://github.com/%s/%s/tree/%s", e.Creator, e.Name, e.Version) + default: + return "" + } }