Open catthehacker opened 3 years ago
This is some quick ugly fix that needs to be improved still. @cplee would you mind looking at this and give some opinion how (bad) that looks or what could be done better 😸
diff --git a/cmd/root.go b/cmd/root.go
index 13867b9..8d1a3a9 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -3,9 +3,13 @@ package cmd
import (
"bufio"
"context"
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
"os"
"path/filepath"
"regexp"
+ "sort"
"strings"
"github.com/nektos/act/pkg/common"
@@ -176,8 +180,9 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str
if input.autodetectEvent && len(events) > 0 {
// set default event type to first event
// this way user dont have to specify the event.
- log.Debugf("Using detected workflow event: %s", events[0])
eventName = events[0]
+ } else if input.eventPath != "" {
+ eventName = parseEventFile(input.eventPath)
} else {
if len(args) > 0 {
eventName = args[0]
@@ -185,6 +190,10 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str
eventName = "push"
}
}
+ if res := sort.SearchStrings(model.Events, eventName); res == 0 {
+ return fmt.Errorf("event type '%s' not found in a list of acceptable events", eventName)
+ }
+ log.Debugf("Using detected workflow event: %s", eventName)
// build the plan for this run
var plan *model.Plan
@@ -359,3 +368,144 @@ func watchAndRun(ctx context.Context, fn common.Executor) error {
folderWatcher.Stop()
return err
}
+
+// parseEventFile returns proper event name based on content of event json file
+// nolint:gocyclo
+func parseEventFile(p string) string {
+ e := make(map[string]interface{})
+ eventJSONBytes, err := ioutil.ReadFile(p)
+ if err != nil {
+ log.Errorf("%v", err)
+ return ""
+ }
+
+ err = json.Unmarshal(eventJSONBytes, &e)
+ if err != nil {
+ log.Errorf("%v", err)
+ return ""
+ }
+
+ keys := make([]string, 0, len(e))
+ for k := range e {
+ keys = append(keys, k)
+ }
+ sort.Strings(keys)
+
+ // log.Debugf("json: %v", e)
+
+ if e["action"] == "revoked" {
+ return "github_app_authorization"
+ }
+ for _, k := range keys {
+ switch k {
+ case "check_run", "check_suite", "content_reference", "label", "marketplace_purchase", "milestone", "package",
+ "project_card", "project_column", "project", "release", "security_advisory":
+ return k
+ case "alert":
+ if e["ref"] != nil {
+ return "code_scanning_alert"
+ }
+ switch e["action"] {
+ case "created", "resolved", "reopened":
+ return "secret_scanning_alert"
+ }
+ return "repository_vulnerability_alert"
+ case "blocked_user":
+ return "org_block"
+ case "comment":
+ if e["pull_request"] == nil {
+ if e["issue"] != nil {
+ return "issue_comment"
+ }
+ if e["discussion"] != nil {
+ return "discussion_comment"
+ }
+ return "commit_comment"
+ }
+ case "client_payload":
+ return "repository_dispatch"
+ case "deployment":
+ if e["deployment_status"] != nil {
+ return "deployment_status"
+ }
+ return "deployment"
+ case "member":
+ if e["team"] != nil {
+ return "membership"
+ }
+ return "member"
+ case "membership":
+ return "organization"
+ case "ref":
+ if e["ref_type"] != nil {
+ if e["master_branch"] == nil {
+ return "delete"
+ }
+ return "create"
+ }
+ if e["workflow"] != nil {
+ return "workflow_dispatch"
+ }
+ return "push"
+ case "key":
+ return "deploy_key"
+ case "discussion":
+ return k
+ case "forkee":
+ return "fork"
+ case "pull_request":
+ if e["comment"] != nil {
+ return "pull_request_review_comment"
+ }
+ if e["review"] != nil {
+ return "pull_request_review"
+ }
+ return k
+ case "pages":
+ return "gollum"
+ case "hook_id":
+ if e["zen"] != nil {
+ return "ping"
+ }
+ return "meta"
+ case "issue":
+ return "issues"
+ case "installation":
+ if e["repository_selection"] != nil {
+ return "installation_repositories"
+ }
+ return "installation"
+ case "build":
+ return "page_build"
+ case "repository":
+ if e["starred_at"] != nil {
+ return "star"
+ }
+ if e["team"] != nil {
+ if e["action"] != nil {
+ return "team"
+ }
+ return "team_add"
+ }
+ if e["state"] != nil {
+ return "status"
+ }
+ if e["action"] != nil {
+ if e["action"] == "started" {
+ return "watch"
+ }
+ if e["action"] == "requested" || e["action"] == "completed" {
+ return "workflow_run"
+ }
+ return "repository"
+ }
+ if e["status"] != nil {
+ return "repository_import"
+ }
+ return "public"
+ case "sponsorship":
+ return "sponsorship"
+ }
+ }
+ return ""
+}
diff --git a/cmd/root_test.go b/cmd/root_test.go
new file mode 100644
index 0000000..356dbfb
--- /dev/null
+++ b/cmd/root_test.go
@@ -0,0 +1,35 @@
+package cmd
+
+import (
+ "errors"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strings"
+ "testing"
+
+ "github.com/nektos/act/pkg/model"
+ log "github.com/sirupsen/logrus"
+ "gotest.tools/v3/assert"
+)
+
+func TestParseEventFile(t *testing.T) {
+ log.SetLevel(log.DebugLevel)
+ for _, event := range model.Events {
+ p := filepath.Join("..", "pkg", "runner", "testdata", "event-types", strings.ReplaceAll(event, `_`, `-`))
+ log.Debugf("Path: %s", p)
+
+ _, err := os.Lstat(p)
+ if errors.Is(err, os.ErrNotExist) {
+ err = os.MkdirAll(p, 0766)
+ assert.NilError(t, err, "")
+
+ err = ioutil.WriteFile(filepath.Join(p, "event.json"), []byte{}, 0600)
+ assert.NilError(t, err, "")
+ } else {
+ eventName := parseEventFile(filepath.Join(p, "event.json"))
+ log.Debugf("event: %s, eventName: %s", event, eventName)
+ assert.Equal(t, eventName, event)
+ }
+ }
+}
diff --git a/pkg/model/planner.go b/pkg/model/planner.go
index 3c2a660..42b5f57 100644
--- a/pkg/model/planner.go
+++ b/pkg/model/planner.go
@@ -14,6 +14,17 @@ import (
log "github.com/sirupsen/logrus"
)
+// Events contains all allowed event names
+var Events = []string{
+ "check_run", "check_suite", "code_scanning_alert", "commit_comment", "content_reference", "create", "delete", "deploy_key",
+ "deployment", "deployment_status", "discussion", "discussion_comment", "fork", "github_app_authorization", "gollum", "installation",
+ "installation_repositories", "issue_comment", "issues", "label", "marketplace_purchase", "member", "membership", "meta", "milestone",
+ "organization", "org_block", "package", "page_build", "ping", "project_card", "project_column", "project", "public", "pull_request",
+ "pull_request_review", "pull_request_review_comment", "push", "release", "repository_dispatch", "repository", "repository_import",
+ "repository_vulnerability_alert", "secret_scanning_alert", "security_advisory", "sponsorship", "star", "status", "team", "team_add",
+ "watch", "workflow_dispatch", "workflow_run",
+}
+
// WorkflowPlanner contains methods for creating plans
type WorkflowPlanner interface {
PlanEvent(eventName string) *Plan
diff --git a/pkg/runner/run_context.go b/pkg/runner/run_context.go
index 612f473..bfa2e6c 100755
--- a/pkg/runner/run_context.go
+++ b/pkg/runner/run_context.go
@@ -524,32 +524,33 @@ func (rc *RunContext) getGithubContext() *githubContext {
}
}
- maybeRef := nestedMapLookup(ghc.Event, ghc.EventName, "ref")
- if maybeRef != nil {
- log.Debugf("using github ref from event: %s", maybeRef)
- ghc.Ref = maybeRef.(string)
- } else {
- ref, err := common.FindGitRef(repoPath)
- if err != nil {
- log.Warningf("unable to get git ref: %v", err)
+ switch ghc.EventName {
+ case "pull_request":
+ ghc.BaseRef = asString(nestedMapLookup(ghc.Event, "pull_request", "base", "ref"))
+ ghc.HeadRef = asString(nestedMapLookup(ghc.Event, "pull_request", "head", "ref"))
+ default:
+ maybeRef := nestedMapLookup(ghc.Event, ghc.EventName, "ref")
+ if maybeRef != nil {
+ log.Debugf("using github ref from event: %s", maybeRef)
+ ghc.Ref = maybeRef.(string)
} else {
- log.Debugf("using github ref: %s", ref)
- ghc.Ref = ref
- }
+ ref, err := common.FindGitRef(repoPath)
+ if err != nil {
+ log.Warningf("unable to get git ref: %v", err)
+ } else {
+ log.Debugf("using github ref: %s", ref)
+ ghc.Ref = ref
+ }
- // set the branch in the event data
- if rc.Config.DefaultBranch != "" {
- ghc.Event = withDefaultBranch(rc.Config.DefaultBranch, ghc.Event)
- } else {
- ghc.Event = withDefaultBranch("master", ghc.Event)
+ // set the branch in the event data
+ if rc.Config.DefaultBranch != "" {
+ ghc.Event = withDefaultBranch(rc.Config.DefaultBranch, ghc.Event)
+ } else {
+ ghc.Event = withDefaultBranch("master", ghc.Event)
+ }
}
}
- if ghc.EventName == "pull_request" {
- ghc.BaseRef = asString(nestedMapLookup(ghc.Event, "pull_request", "base", "ref"))
- ghc.HeadRef = asString(nestedMapLookup(ghc.Event, "pull_request", "head", "ref"))
- }
-
return ghc
}
diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go
index 9262b96..7a49031 100644
--- a/pkg/runner/runner.go
+++ b/pkg/runner/runner.go
@@ -100,6 +100,7 @@ func New(runnerConfig *Config) (Runner, error) {
return nil, err
}
runner.eventJSON = string(eventJSONBytes)
+ log.Debugf("Event JSON: '%s'", runner.eventJSON)
}
return runner, nil
}
diff --git a/pkg/runner/runner_test.go b/pkg/runner/runner_test.go
index 89e1061..304bafd 100644
--- a/pkg/runner/runner_test.go
+++ b/pkg/runner/runner_test.go
@@ -173,32 +173,34 @@ func TestRunEventPullRequest(t *testing.T) {
ctx := context.Background()
platforms := map[string]string{
- "ubuntu-latest": "node:12.20.1-buster-slim",
+ "ubuntu-latest": "node:12.20-buster-slim",
}
- workflowPath := "pull-request"
- eventName := "pull_request"
+ for _, event := range model.Events {
+ workflowPath := strings.ReplaceAll(event, `_`, `-`)
+ eventName := event
- workdir, err := filepath.Abs("testdata")
- assert.NilError(t, err, workflowPath)
+ workdir, err := filepath.Abs("testdata")
+ assert.NilError(t, err, workflowPath)
- runnerConfig := &Config{
- Workdir: workdir,
- EventName: eventName,
- EventPath: filepath.Join(workdir, workflowPath, "event.json"),
- Platforms: platforms,
- ReuseContainers: false,
- }
- runner, err := New(runnerConfig)
- assert.NilError(t, err, workflowPath)
+ runnerConfig := &Config{
+ Workdir: workdir,
+ EventName: eventName,
+ EventPath: filepath.Join(workdir, workflowPath, "event.json"),
+ Platforms: platforms,
+ ReuseContainers: false,
+ }
+ runner, err := New(runnerConfig)
+ assert.NilError(t, err, workflowPath)
- planner, err := model.NewWorkflowPlanner(fmt.Sprintf("testdata/%s", workflowPath), true)
- assert.NilError(t, err, workflowPath)
+ planner, err := model.NewWorkflowPlanner(filepath.Join("testdata", "event-types", workflowPath), true)
+ assert.NilError(t, err, workflowPath)
- plan := planner.PlanEvent(eventName)
+ plan := planner.PlanEvent(eventName)
- err = runner.NewPlanExecutor(plan)(ctx)
- assert.NilError(t, err, workflowPath)
+ err = runner.NewPlanExecutor(plan)(ctx)
+ assert.NilError(t, err, workflowPath)
+ }
}
func TestContainerPath(t *testing.T) {
branch: https://github.com/catthehacker/act-fork/tree/cat/fix%2Fevent-json
Issue is stale and will be closed in 14 days unless there is new activity
Might this also be fixed by #1428?
Not sure it is.
I have this simple workflow-test.yml:
on:
pull_request:
types: [ready_for_review]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Test
run: echo test
and the following event.json
:
{
"action": "opened",
"pull_request": {
"head": {
"ref": "sample-head-ref"
},
"base": {
"ref": "main"
}
}
}
And if I run:
act pull_request -W ./.github/workflows/workflow-testyml -e event.json
it runs, although it shouldn't as the type is opened
not ready_for_review
Act version
https://github.com/nektos/act/commit/8153dc92e5c34c51d02777b8274f05c399d3befc
Expected behaviour
event type should be parsed from event file
Actual behaviour
it defaults to push
Workflow and/or repository
n/a
Steps to reproduce
act
outputLog
```sh ~/go/src/github.com/nektos/act cat/fix/event-json *4 ?1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 3s cat@alpine-vm 11:53:1 ❯ act -e pkg/runner/testdata/pull-request/event.json -W pkg/runner/testdata/pull-request/main.yaml -v DEBU[0000] Loading environment from /home/cat/go/src/github.com/nektos/act/.env DEBU[0000] Loading secrets from /home/cat/go/src/github.com/nektos/act/.secrets DEBU[0000] Loading workflow '/home/cat/go/src/github.com/nektos/act/pkg/runner/testdata/pull-request/main.yaml' DEBU[0000] Reading workflow '/home/cat/go/src/github.com/nektos/act/pkg/runner/testdata/pull-request/main.yaml' DEBU[0000] Planning event: push DEBU[0000] Reading event.json from /home/cat/go/src/github.com/nektos/act/pkg/runner/testdata/pull-request/event.json ~/go/src/github.com/nektos/act cat/fix/event-json *4 ?1 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── cat@alpine-vm 12:02:5 ❯ ```