diff --git a/.github/ISSUE_TEMPLATE/issue_template.md b/.github/ISSUE_TEMPLATE/issue_template.md index b616c67a..2472da07 100644 --- a/.github/ISSUE_TEMPLATE/issue_template.md +++ b/.github/ISSUE_TEMPLATE/issue_template.md @@ -1,20 +1,23 @@ --- name: Issue about: Use this template for reporting a bug/issue. -title: "Issue: " +title: "Issue: " labels: kind/bug assignees: '' --- ## Act version - + ```none @@ -22,14 +25,23 @@ assignees: '' ## Expected behaviour - + ## Actual behaviour - + ## Workflow and/or repository + - ## `act` output - +
Log ```none - +PASTE YOUR LOG HERE ```
diff --git a/.github/linters/.golangci.yml b/.github/linters/.golangci.yml new file mode 120000 index 00000000..d531ead6 --- /dev/null +++ b/.github/linters/.golangci.yml @@ -0,0 +1 @@ +../../.golangci.yml \ No newline at end of file diff --git a/.github/linters/.markdown-lint.yml b/.github/linters/.markdown-lint.yml new file mode 100644 index 00000000..bb91f2f0 --- /dev/null +++ b/.github/linters/.markdown-lint.yml @@ -0,0 +1,11 @@ +# Default state for all rules +default: true + +# MD013/line-length - Line length +MD013: false + +# MD033/no-inline-html - Inline HTML +MD033: false + +# MD041/first-line-heading/first-line-h1 - First line in a file should be a top-level heading +MD041: false diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index fc52d97d..851fb7b6 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -7,6 +7,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + fetch-depth: 0 - uses: actions/setup-go@v1 with: go-version: 1.16 @@ -14,7 +16,19 @@ jobs: env: CGO_ENABLED: 0 with: - version: v1.32.2 + version: v1.39.0 + - uses: github/super-linter@v3 + env: + DEFAULT_BRANCH: master + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + FILTER_REGEX_EXCLUDE: .*testdata/* + VALIDATE_ALL_CODEBASE: ${{ github.event_name != 'pull_request' }} # lint only new changes when pull_request + VALIDATE_BASH: false + VALIDATE_DOCKERFILE: false + VALIDATE_DOCKERFILE_HADOLINT: false + VALIDATE_GO: false # it's broken, see commit message + VALIDATE_JSCPD: false + VALIDATE_SHELL_SHFMT: false test: name: Test on Linux diff --git a/.golangci.yml b/.golangci.yml index 1ffb0438..38fd4510 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -6,19 +6,22 @@ linters-settings: # minimal code complexity to report, 30 by default (but we recommend 10-20) mi-complexity: 15 gocritic: - disabled-checks: + disabled-checks: - ifElseChain linters: enable: - - megacheck - - govet - - golint - - gocyclo - - gosec - - unconvert - - dupl - - nakedret - - prealloc - - scopelint - - gocritic + - megacheck + - govet + - golint + - gocyclo + - gosec + - unconvert + - dupl + - nakedret + - prealloc + - exportloopref + - gocritic + - goimports + - whitespace + - misspell diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..0edc2fb4 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "go.lintTool": "golangci-lint", + "go.lintFlags": [ + "--fix" + ] +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 97d82a31..85258cbc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,7 +21,7 @@ If you've identified a bug in `act`, please [submit an issue](#issue) to our Git All feature requests should start with [submitting an issue](#issue) documenting the user story and acceptance criteria. Again, feel free to submit a [Pull Request](#pr) with a proposed implementation of the feature. -## Ready to Contribute! +## Ready to Contribute ### Create an issue diff --git a/Makefile b/Makefile index 8f3c3ae3..0da1a08f 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,17 @@ MINOR_VERSION = $(word 2, $(subst ., ,$(VERSION))) PATCH_VERSION = $(word 3, $(subst ., ,$(word 1,$(subst -, , $(VERSION))))) NEW_VERSION ?= $(MAJOR_VERSION).$(MINOR_VERSION).$(shell echo $$(( $(PATCH_VERSION) + 1)) ) +fix = false +ifeq (true,$(fix)) + FIX = --fix +endif + ACT ?= go run main.go -export GITHUB_TOKEN := $(shell cat ~/.config/github/token) + +HAS_TOKEN = $(if $(test -e ~/.config/github/token),true,false) +ifeq (true,$(HAS_TOKEN)) + export GITHUB_TOKEN := $(shell cat ~/.config/github/token) +endif .PHONY: build build: @@ -22,6 +31,42 @@ test: go test ./... $(ACT) +.PHONY: lint-go +lint-go: + golangci-lint run $(FIX) + +.PHONY: lint-js +lint-js: + standard $(FIX) + +.PHONY: lint-md +lint-md: + markdownlint . $(FIX) + +.PHONY: lint-rest +lint-rest: + docker run --rm -it \ + -e 'RUN_LOCAL=true' \ + -e 'FILTER_REGEX_EXCLUDE=.*testdata/*' \ + -e 'VALIDATE_BASH=false' \ + -e 'VALIDATE_DOCKERFILE=false' \ + -e 'VALIDATE_DOCKERFILE_HADOLINT=false' \ + -e 'VALIDATE_GO=false' \ + -e 'VALIDATE_JSCPD=false' \ + -e 'VALIDATE_SHELL_SHFMT=false' \ + -v $(PWD):/tmp/lint \ + github/super-linter + +.PHONY: lint +lint: lint-go lint-rest + +.PHONY: lint-fix +lint-fix: lint-md lint-go + +.PHONY: fix +fix: + make lint-fix fix=true + .PHONY: install install: build @cp dist/local/act $(PREFIX)/bin/act diff --git a/README.md b/README.md index 72ca97aa..757fe0a3 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,7 @@ -![](https://github.com/nektos/act/wiki/img/logo-150.png) +![act-logo](https://github.com/nektos/act/wiki/img/logo-150.png) # Overview [![push](https://github.com/nektos/act/workflows/push/badge.svg?branch=master&event=push)](https://github.com/nektos/act/actions) [![Join the chat at https://gitter.im/nektos/act](https://badges.gitter.im/nektos/act.svg)](https://gitter.im/nektos/act?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Go Report Card](https://goreportcard.com/badge/github.com/nektos/act)](https://goreportcard.com/report/github.com/nektos/act) [![awesome-runners](https://img.shields.io/badge/listed%20on-awesome--runners-blue.svg)](https://github.com/jonico/awesome-runners) - > "Think globally, `act` locally" Run your [GitHub Actions](https://developer.github.com/actions/) locally! Why would you want to do this? Two reasons: @@ -21,6 +20,7 @@ Let's see it in action with a [sample repo](https://github.com/cplee/github-acti # Installation ## Necessary prerequisites for running `act` + `act` depends on `docker` to run workflows. If you are using macOS, please be sure to follow the steps outlined in [Docker Docs for how to install Docker Desktop for Mac](https://docs.docker.com/docker-for-mac/install/). @@ -48,14 +48,15 @@ curl https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash If you are running Windows, download the [latest release](https://github.com/nektos/act/releases/latest) and add the binary into your PATH. If you are using [Chocolatey](https://chocolatey.org/) then run: -[![](https://img.shields.io/chocolatey/v/act-cli)](https://community.chocolatey.org/packages/act-cli) +[![choco-shield](https://img.shields.io/chocolatey/v/act-cli)](https://community.chocolatey.org/packages/act-cli) + ```shell choco install act-cli ``` If you are using [Scoop](https://scoop.sh/) then run: -[![](https://img.shields.io/scoop/v/act)](https://github.com/ScoopInstaller/Main/blob/master/bucket/act.json) +[![scoop-shield](https://img.shields.io/scoop/v/act)](https://github.com/ScoopInstaller/Main/blob/master/bucket/act.json) ```shell scoop install act @@ -63,7 +64,7 @@ scoop install act If you are running Arch Linux, you can install the [act](https://aur.archlinux.org/packages/act/) package with your favorite package manager: -[![](https://img.shields.io/aur/version/act)](https://aur.archlinux.org/packages/act/) +[![aur-shield](https://img.shields.io/aur/version/act)](https://aur.archlinux.org/packages/act/) ```shell yay -S act @@ -315,7 +316,7 @@ Want to contribute to act? Awesome! Check out the [contributing guidelines](CONT ## Building from source -- Install Go tools 1.16+ - (https://golang.org/doc/install) +- Install Go tools 1.16+ - () - Clone this repo `git clone git@github.com:nektos/act.git` - Run unit tests with `make test` - Build and install: `make install` diff --git a/cmd/graph.go b/cmd/graph.go index 4f8895ef..b38487be 100644 --- a/cmd/graph.go +++ b/cmd/graph.go @@ -8,7 +8,6 @@ import ( ) func drawGraph(plan *model.Plan) error { - drawings := make([]*common.Drawing, 0) jobPen := common.NewPen(common.StyleSingleLine, 96) diff --git a/pkg/common/file.go b/pkg/common/file.go index 268b2726..0894f0c9 100644 --- a/pkg/common/file.go +++ b/pkg/common/file.go @@ -28,7 +28,6 @@ func CopyFile(source string, dest string) (err error) { if err != nil { _ = os.Chmod(dest, sourceinfo.Mode()) } - } return @@ -36,7 +35,6 @@ func CopyFile(source string, dest string) (err error) { // CopyDir recursive copy of directory func CopyDir(source string, dest string) (err error) { - // get properties of source dir sourceinfo, err := os.Stat(source) if err != nil { @@ -55,7 +53,6 @@ func CopyDir(source string, dest string) (err error) { objects, err := directory.Readdir(-1) for _, obj := range objects { - sourcefilepointer := source + "/" + obj.Name() destinationfilepointer := dest + "/" + obj.Name() @@ -73,7 +70,6 @@ func CopyDir(source string, dest string) (err error) { fmt.Println(err) } } - } return err } diff --git a/pkg/common/git.go b/pkg/common/git.go index 2cfecf87..24220916 100644 --- a/pkg/common/git.go +++ b/pkg/common/git.go @@ -301,7 +301,6 @@ func NewGitCloneExecutor(input NewGitCloneExecutorInput) Executor { // Repos on disk point to commit hashes, and need to checkout input.Ref before // we try and pull down any changes if hash.String() != input.Ref { - // Run git fetch to make sure we have the latest sha err := r.Fetch(&git.FetchOptions{}) if err != nil && !errors.Is(err, git.NoErrAlreadyUpToDate) { diff --git a/pkg/common/git_test.go b/pkg/common/git_test.go index 0edb4507..1567c24c 100644 --- a/pkg/common/git_test.go +++ b/pkg/common/git_test.go @@ -40,7 +40,6 @@ func TestFindGitSlug(t *testing.T) { assert.Equal(tt.provider, provider) assert.Equal(tt.slug, slug) } - } func testDir(t *testing.T) string { diff --git a/pkg/container/docker_build.go b/pkg/container/docker_build.go index f9107790..95d15e21 100644 --- a/pkg/container/docker_build.go +++ b/pkg/container/docker_build.go @@ -63,7 +63,6 @@ func NewDockerBuildExecutor(input NewDockerBuildExecutorInput) common.Executor { } return nil } - } func createBuildContext(contextDir string, relDockerfile string) (io.ReadCloser, error) { log.Debugf("Creating archive for build context dir '%s' with relative dockerfile '%s'", contextDir, relDockerfile) diff --git a/pkg/container/docker_pull.go b/pkg/container/docker_pull.go index ee8e0dbe..9ae49abf 100644 --- a/pkg/container/docker_pull.go +++ b/pkg/container/docker_pull.go @@ -62,9 +62,7 @@ func NewDockerPullExecutor(input NewDockerPullExecutorInput) common.Executor { return err } return nil - } - } func cleanImage(image string) string { diff --git a/pkg/container/docker_run.go b/pkg/container/docker_run.go index 1374c381..371d8b66 100644 --- a/pkg/container/docker_run.go +++ b/pkg/container/docker_run.go @@ -151,7 +151,6 @@ func (cr *containerReference) UpdateFromGithubEnv(env *map[string]string) common } func (cr *containerReference) Exec(command []string, env map[string]string) common.Executor { - return common.NewPipelineExecutor( cr.connect(), cr.find(), diff --git a/pkg/model/workflow.go b/pkg/model/workflow.go index 8fe9354d..50221b08 100644 --- a/pkg/model/workflow.go +++ b/pkg/model/workflow.go @@ -23,7 +23,6 @@ type Workflow struct { // On events for the workflow func (w *Workflow) On() []string { - switch w.RawOn.Kind { case yaml.ScalarNode: var val string @@ -109,7 +108,6 @@ func (j *Job) Container() *ContainerSpec { // Needs list for Job func (j *Job) Needs() []string { - switch j.RawNeeds.Kind { case yaml.ScalarNode: var val string @@ -131,7 +129,6 @@ func (j *Job) Needs() []string { // RunsOn list for Job func (j *Job) RunsOn() []string { - switch j.RawRunsOn.Kind { case yaml.ScalarNode: var val string @@ -183,7 +180,6 @@ func (j *Job) GetMatrixes() []map[string]interface{} { log.Debugf("Adding include '%v'", include) matrixes = append(matrixes, include) } - } else { matrixes = append(matrixes, make(map[string]interface{})) } @@ -313,12 +309,12 @@ func (s *Step) Type() StepType { } func (s *Step) Validate() error { - if s.Type() != StepTypeRun { - return fmt.Errorf("(StepID: %s): Unexpected value 'uses'", s.String()) - } else if s.Shell == "" { - return fmt.Errorf("(StepID: %s): Required property is missing: 'shell'", s.String()) - } - return nil + if s.Type() != StepTypeRun { + return fmt.Errorf("(StepID: %s): Unexpected value 'uses'", s.String()) + } else if s.Shell == "" { + return fmt.Errorf("(StepID: %s): Required property is missing: 'shell'", s.String()) + } + return nil } // ReadWorkflow returns a list of jobs for a given workflow file reader diff --git a/pkg/runner/expression_test.go b/pkg/runner/expression_test.go index d0795f4d..55ddff5e 100644 --- a/pkg/runner/expression_test.go +++ b/pkg/runner/expression_test.go @@ -199,7 +199,6 @@ func updateTestExpressionWorkflow(t *testing.T, tables []struct { in string out string }, rc *RunContext) { - var envs string keys := make([]string, 0, len(rc.Env)) for k := range rc.Env { @@ -242,7 +241,6 @@ jobs: if err != nil { t.Fatal(err) } - } func TestRewrite(t *testing.T) { diff --git a/pkg/runner/logger.go b/pkg/runner/logger.go index ff3384cc..41356627 100644 --- a/pkg/runner/logger.go +++ b/pkg/runner/logger.go @@ -109,7 +109,6 @@ func (f *stepLogFormatter) print(b *bytes.Buffer, entry *logrus.Entry) { } func (f *stepLogFormatter) isColored(entry *logrus.Entry) bool { - isColored := checkIfTerminal(entry.Logger.Out) if force, ok := os.LookupEnv("CLICOLOR_FORCE"); ok && force != "0" { diff --git a/pkg/runner/res/trampoline.js b/pkg/runner/res/trampoline.js index 8f45c662..e9a87322 100644 --- a/pkg/runner/res/trampoline.js +++ b/pkg/runner/res/trampoline.js @@ -1,14 +1,14 @@ const { spawnSync } = require('child_process') -const spawnArguments={ - cwd: process.env['INPUT_CWD'], +const spawnArguments = { + cwd: process.env.INPUT_CWD, stdio: [ process.stdin, process.stdout, - process.stderr, + process.stderr ] } -const child=spawnSync( +const child = spawnSync( '/bin/sh', - [ '-c' ].concat(process.env['INPUT_COMMAND']), + ['-c'].concat(process.env.INPUT_COMMAND), spawnArguments) process.exit(child.status) diff --git a/pkg/runner/run_context.go b/pkg/runner/run_context.go index fcd86f60..116acf79 100755 --- a/pkg/runner/run_context.go +++ b/pkg/runner/run_context.go @@ -336,7 +336,6 @@ func (rc *RunContext) EvalBool(expr string) (bool, error) { !strings.Contains(part, "!")) && // but it's not negated interpolatedPart == "false" && // and the interpolated string is false (isString || previousOrNextPartIsAnOperator(i, parts)) { // and it's of type string or has an logical operator before or after - interpolatedPart = fmt.Sprintf("'%s'", interpolatedPart) // then we have to quote the false expression } diff --git a/pkg/runner/run_context_test.go b/pkg/runner/run_context_test.go index 440619ec..78a94975 100644 --- a/pkg/runner/run_context_test.go +++ b/pkg/runner/run_context_test.go @@ -157,7 +157,6 @@ func updateTestIfWorkflow(t *testing.T, tables []struct { out bool wantErr bool }, rc *RunContext) { - var envs string keys := make([]string, 0, len(rc.Env)) for k := range rc.Env { diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index 912e2deb..388aa984 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -33,7 +33,7 @@ type Config struct { Privileged bool // use privileged mode UsernsMode string // user namespace to use ContainerArchitecture string // Desired OS/architecture platform for running containers - UseGitIgnore bool // controls if paths in .gitignore should not be copied into container, default true + UseGitIgnore bool // controls if paths in .gitignore should not be copied into container, default true } type runnerImpl struct { diff --git a/pkg/runner/step_context.go b/pkg/runner/step_context.go index 730d5eda..0ce3e821 100755 --- a/pkg/runner/step_context.go +++ b/pkg/runner/step_context.go @@ -539,7 +539,6 @@ func (sc *StepContext) runAction(actionDir string, actionPath string) common.Exe // Interpolate the outer inputs into the composite step with items exprEval := sc.NewExpressionEvaluator() for k, v := range stepContext.Step.With { - if strings.Contains(v, "inputs") { stepContext.Step.With[k] = exprEval.Interpolate(v) }