From 2d1a946fb143b0f0d204a7565d82df8b75263d60 Mon Sep 17 00:00:00 2001 From: "KADOTA, Kyohei" Date: Sun, 24 Jan 2021 01:07:28 +0900 Subject: [PATCH] Throw an error if the steps has a invalid uses directive (#500) * Throw an error if the steps has a invalid uses directive * Refactor TestStepContextExecutor --- pkg/runner/step_context.go | 37 ++++++++++--------- pkg/runner/step_context_test.go | 25 +++++++++++++ .../testdata/uses-github-empty/push.yml | 7 ++++ .../testdata/uses-github-noref/push.yml | 7 ++++ pkg/runner/testdata/uses-github-path/push.yml | 7 ++++ pkg/runner/testdata/uses-github-root/push.yml | 7 ++++ 6 files changed, 73 insertions(+), 17 deletions(-) create mode 100644 pkg/runner/step_context_test.go create mode 100644 pkg/runner/testdata/uses-github-empty/push.yml create mode 100644 pkg/runner/testdata/uses-github-noref/push.yml create mode 100644 pkg/runner/testdata/uses-github-path/push.yml create mode 100644 pkg/runner/testdata/uses-github-root/push.yml diff --git a/pkg/runner/step_context.go b/pkg/runner/step_context.go index 87ba77b..8972ede 100644 --- a/pkg/runner/step_context.go +++ b/pkg/runner/step_context.go @@ -32,6 +32,12 @@ func (sc *StepContext) execJobContainer() common.Executor { } } +type formatError string + +func (e formatError) Error() string { + return fmt.Sprintf("Expected format {org}/{repo}[/path]@ref. Actual '%s' Input string was not in a correct format.", string(e)) +} + // Executor for a step context func (sc *StepContext) Executor() common.Executor { rc := sc.RunContext @@ -57,14 +63,8 @@ func (sc *StepContext) Executor() common.Executor { ) case model.StepTypeUsesActionRemote: remoteAction := newRemoteAction(step.Uses) - if remoteAction.Ref == "" { - // GitHub's document[^] describes: - // > We strongly recommend that you include the version of - // > the action you are using by specifying a Git ref, SHA, or Docker tag number. - // Actually, the workflow stops if there is the uses directive that hasn't @ref. - // [^]: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions - msg := fmt.Sprintf("Expected format {org}/{repo}[/path]@ref. Actual '%s' Input string was not in a correct format.", step.Uses) - return common.NewErrorExecutor(fmt.Errorf("%s", msg)) + if remoteAction == nil { + return common.NewErrorExecutor(formatError(step.Uses)) } if remoteAction.IsCheckout() && rc.getGithubContext().isLocalCheckout(step) { return func(ctx context.Context) error { @@ -401,19 +401,22 @@ func (ra *remoteAction) IsCheckout() bool { } func newRemoteAction(action string) *remoteAction { + // GitHub's document[^] describes: + // > We strongly recommend that you include the version of + // > the action you are using by specifying a Git ref, SHA, or Docker tag number. + // Actually, the workflow stops if there is the uses directive that hasn't @ref. + // [^]: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions r := regexp.MustCompile(`^([^/@]+)/([^/@]+)(/([^@]*))?(@(.*))?$`) matches := r.FindStringSubmatch(action) - - ra := new(remoteAction) - ra.Org = matches[1] - ra.Repo = matches[2] - if len(matches) >= 5 { - ra.Path = matches[4] + if len(matches) < 7 || matches[6] == "" { + return nil } - if len(matches) >= 7 { - ra.Ref = matches[6] + return &remoteAction{ + Org: matches[1], + Repo: matches[2], + Path: matches[4], + Ref: matches[6], } - return ra } // https://github.com/nektos/act/issues/228#issuecomment-629709055 diff --git a/pkg/runner/step_context_test.go b/pkg/runner/step_context_test.go new file mode 100644 index 0000000..fa5f722 --- /dev/null +++ b/pkg/runner/step_context_test.go @@ -0,0 +1,25 @@ +package runner + +import ( + "context" + "testing" + + "github.com/nektos/act/pkg/common" +) + +func TestStepContextExecutor(t *testing.T) { + platforms := map[string]string{ + "ubuntu-latest": "node:12.6-buster-slim", + } + tables := []TestJobFileInfo{ + {"testdata", "uses-github-empty", "push", "Expected format {org}/{repo}[/path]@ref", platforms}, + {"testdata", "uses-github-noref", "push", "Expected format {org}/{repo}[/path]@ref", platforms}, + {"testdata", "uses-github-root", "push", "", platforms}, + {"testdata", "uses-github-path", "push", "", platforms}, + } + // These tests are sufficient to only check syntax. + ctx := common.WithDryrun(context.Background(), true) + for _, table := range tables { + runTestJobFile(ctx, t, table) + } +} diff --git a/pkg/runner/testdata/uses-github-empty/push.yml b/pkg/runner/testdata/uses-github-empty/push.yml new file mode 100644 index 0000000..02074be --- /dev/null +++ b/pkg/runner/testdata/uses-github-empty/push.yml @@ -0,0 +1,7 @@ +name: uses-github-empty +on: push +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: empty diff --git a/pkg/runner/testdata/uses-github-noref/push.yml b/pkg/runner/testdata/uses-github-noref/push.yml new file mode 100644 index 0000000..be0a6fb --- /dev/null +++ b/pkg/runner/testdata/uses-github-noref/push.yml @@ -0,0 +1,7 @@ +name: uses-github-noref +on: push +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout diff --git a/pkg/runner/testdata/uses-github-path/push.yml b/pkg/runner/testdata/uses-github-path/push.yml new file mode 100644 index 0000000..1937471 --- /dev/null +++ b/pkg/runner/testdata/uses-github-path/push.yml @@ -0,0 +1,7 @@ +name: uses-github-path +on: push +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: sergioramos/yarn-actions/install@v6 diff --git a/pkg/runner/testdata/uses-github-root/push.yml b/pkg/runner/testdata/uses-github-root/push.yml new file mode 100644 index 0000000..37468ea --- /dev/null +++ b/pkg/runner/testdata/uses-github-root/push.yml @@ -0,0 +1,7 @@ +name: uses-github-root +on: push +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2