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
This commit is contained in:
KADOTA, Kyohei 2021-01-24 01:07:28 +09:00 committed by GitHub
parent e37b42a333
commit 2d1a946fb1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 73 additions and 17 deletions

View file

@ -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

View file

@ -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)
}
}

View file

@ -0,0 +1,7 @@
name: uses-github-empty
on: push
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: empty

View file

@ -0,0 +1,7 @@
name: uses-github-noref
on: push
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout

View file

@ -0,0 +1,7 @@
name: uses-github-path
on: push
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: sergioramos/yarn-actions/install@v6

View file

@ -0,0 +1,7 @@
name: uses-github-root
on: push
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2