Repository: nektos/act (language: go)

Issue:
SIGSEGV when having secrets not defined locally
### Bug report info

```plain text
act version:            0.2.30
GOOS:                   darwin
GOARCH:                 amd64
NumCPU:                 12
Docker host:            DOCKER_HOST environment variable is unset/empty.
Sockets found:
        /var/run/docker.sock
Config files:           
        /Users/kai7rng/.actrc:
                -P ubuntu-latest=catthehacker/ubuntu:act-latest
                -P ubuntu-22.04=catthehacker/ubuntu:act-22.04
                -P ubuntu-20.04=catthehacker/ubuntu:act-20.04
                -P ubuntu-18.04=catthehacker/ubuntu:act-18.04
Build info:
        Go version:            go1.18.4
        Module path:           command-line-arguments
        Main version:          
        Main path:             
        Main checksum:         
        Build settings:
                -compiler:            gc
                -ldflags:             -X main.version=0.2.30
                CGO_ENABLED:          1
                CGO_CFLAGS:           
                CGO_CPPFLAGS:         
                CGO_CXXFLAGS:         
                CGO_LDFLAGS:          
                GOARCH:               amd64
                GOOS:                 darwin
                GOAMD64:              v1
Docker Engine:
        Engine version:        20.10.17
        Engine runtime:        runc
        Cgroup version:        2
        Cgroup driver:         cgroupfs
        Storage driver:        overlay2
        Registry URI:          https://index.docker.io/v1/
        OS:                    Docker Desktop
        OS type:               linux
        OS version:            
        OS arch:               x86_64
        OS kernel:             5.10.104-linuxkit
        OS CPU:                6
        OS memory:             7859 MB
        Security options:
                name=seccomp,profile=default
                name=cgroupns
```


### Command used with act

```sh
act
```


### Describe issue

Not user friendly way of failing on unknown secrets.

```
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x58 pc=0x16291ea]

goroutine 38 [running]:
```

### Link to GitHub repository

_No response_

### Workflow content

```yml
Relevant is only that I have following in my .yaml:

${{ secrets.RESOURCE_USER_NAME }}
```


### Relevant log output

```sh
[ci-pipeline/documentation] [DEBUG] evaluating expression 'format('{0}', secrets.RESOURCE_USER_NAME)'
[ci-pipeline/documentation] [DEBUG] expression 'format('{0}', secrets.RESOURCE_USER_NAME)' evaluated to '%!t(string=)'
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x58 pc=0x16291ea]
```


### Additional information

_No response_


Discussion / hints:
@ikamensh 

1. are you on an M1 mac? (I see `GOARCH=amd64`)
2. did you recently install monterey v 12.5.1 ?
3. are you running act binary? or in a docker?
4. if binary, did you install from brew or download a release bin from repo?


for context I have similar problem.
My environment:
1. OSX M1 Monterey 12.5.1
2. this forces all docker containers to run linux/amd64 containers/images `DOCKER_DEFAULT_PLATFORM=linux/amd64`
3. act v 0.2.30 installed via brew


1. No, it's intel macbook pro
2. Macos version is 11.6 Big Sur
3. I did `brew install act`, I at least do nothing to run it in a docker.
Please provide the stacktrace ( you cut the most important part of the log ) and a sample workflow.

I cannot reproduce this without additional information requested by the issue template, because I don't get a dump if the secret is not defined. You also omited where in the workflow you referenced the secret there are a lot of possible locations.
Here is example yaml that causes the crash:
```yaml
name: ci-pipeline
on: ["push"]

jobs:
  py38-lin:
    runs-on: [self-hosted, Linux, docker]
    container:
      image: python:3.8-slim
      credentials:
        username: ${{ secrets.RESOURCE_USER_NAME }}
        password: ${{ secrets.BDC_ARTIFACTORY_RESOURCE_TOKEN }}
    steps:
      - name: Configure
        if: ${{ !startsWith(runner.name, 'bla') }}
        run: echo "HELLO"
```

Here is the stack trace:
```
DEBU[0000] Loading environment from /Users/kai7rng/PycharmProjects/try_act/.env 
DEBU[0000] Loading secrets from /Users/kai7rng/PycharmProjects/try_act/.secrets 
DEBU[0000] Loading workflows from '/Users/kai7rng/PycharmProjects/try_act/.github/workflows' 
DEBU[0000] Loading workflows recursively                
DEBU[0000] Found workflow 'ci.yaml' in '/Users/kai7rng/PycharmProjects/try_act/.github/workflows/ci.yaml' 
DEBU[0000] Reading workflow '/Users/kai7rng/PycharmProjects/try_act/.github/workflows/ci.yaml' 
DEBU[0000] Planning event: push                         
DEBU[0000] Loading slug from git directory '/Users/kai7rng/PycharmProjects/try_act/.git' 
DEBU[0000] Loading revision from git directory '/Users/kai7rng/PycharmProjects/try_act/.git' 
DEBU[0000] Found revision: cf976886cf529d70aae21c5238c6c33a4b217f28 
DEBU[0000] HEAD points to 'cf976886cf529d70aae21c5238c6c33a4b217f28' 
DEBU[0000] using github ref: refs/heads/feature/boom    
DEBU[0000] Found revision: cf976886cf529d70aae21c5238c6c33a4b217f28 
[ci-pipeline/py38-lin] [DEBUG] evaluating expression 'success()'
[ci-pipeline/py38-lin] [DEBUG] expression 'success()' evaluated to 'true'
[ci-pipeline/py38-lin] [DEBUG] Loading slug from git directory '/Users/kai7rng/PycharmProjects/try_act/.git'
[ci-pipeline/py38-lin] [DEBUG] Loading revision from git directory '/Users/kai7rng/PycharmProjects/try_act/.git'
[ci-pipeline/py38-lin] [DEBUG] Found revision: cf976886cf529d70aae21c5238c6c33a4b217f28
[ci-pipeline/py38-lin] [DEBUG] HEAD points to 'cf976886cf529d70aae21c5238c6c33a4b217f28'
[ci-pipeline/py38-lin] [DEBUG] using github ref: refs/heads/feature/boom
[ci-pipeline/py38-lin] [DEBUG] Found revision: cf976886cf529d70aae21c5238c6c33a4b217f28
[ci-pipeline/py38-lin] [DEBUG] expression '${{ secrets.RESOURCE_USER_NAME }}' rewritten to 'format('{0}', secrets.RESOURCE_USER_NAME)'
[ci-pipeline/py38-lin] [DEBUG] evaluating expression 'format('{0}', secrets.RESOURCE_USER_NAME)'
[ci-pipeline/py38-lin] [DEBUG] expression 'format('{0}', secrets.RESOURCE_USER_NAME)' evaluated to '%!t(string=)'
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x58 pc=0x16291ea]

goroutine 32 [running]:
github.com/nektos/act/pkg/runner.useStepLogger.func1({0x18b7a98?, 0xc0004c0a80?})
        /private/tmp/act-20220801-4014-thiodr/act-0.2.30/pkg/runner/job_executor.go:136 +0x26a
github.com/nektos/act/pkg/common.Executor.Finally.func1({0x18b7a98, 0xc0004c0a80})
        /private/tmp/act-20220801-4014-thiodr/act-0.2.30/pkg/common/executor.go:175 +0x34
github.com/nektos/act/pkg/runner.newJobExecutor.func5({0x18b7a98, 0xc0004c0a80})
        /private/tmp/act-20220801-4014-thiodr/act-0.2.30/pkg/runner/job_executor.go:116 +0xb1
github.com/nektos/act/pkg/common.Executor.Finally.func1({0x18b7a98, 0xc0004c0a80})
        /private/tmp/act-20220801-4014-thiodr/act-0.2.30/pkg/common/executor.go:176 +0x52
github.com/nektos/act/pkg/common.Executor.Finally.func1({0x18b7a98, 0xc0004c0a80})
        /private/tmp/act-20220801-4014-thiodr/act-0.2.30/pkg/common/executor.go:175 +0x34
github.com/nektos/act/pkg/common.Executor.Finally.func1({0x18b7a98, 0xc0004c0a80})
        /private/tmp/act-20220801-4014-thiodr/act-0.2.30/pkg/common/executor.go:175 +0x34
github.com/nektos/act/pkg/runner.(*RunContext).Executor.func1({0x18b7a98, 0xc0004c0a80})
        /private/tmp/act-20220801-4014-thiodr/act-0.2.30/pkg/runner/run_context.go:286 +0x7e
github.com/nektos/act/pkg/common.Executor.Finally.func1({0x18b7a98, 0xc0004c0a80})
        /private/tmp/act-20220801-4014-thiodr/act-0.2.30/pkg/common/executor.go:175 +0x34
github.com/nektos/act/pkg/runner.(*runnerImpl).NewPlanExecutor.func1.1({0x18b7a98, 0xc0004888a0})
        /private/tmp/act-20220801-4014-thiodr/act-0.2.30/pkg/runner/runner.go:195 +0x362
github.com/nektos/act/pkg/common.NewParallelExecutor.func1.1(0x0?, 0x0?)
        /private/tmp/act-20220801-4014-thiodr/act-0.2.30/pkg/common/executor.go:100 +0x5c
created by github.com/nektos/act/pkg/common.NewParallelExecutor.func1
        /private/tmp/act-20220801-4014-thiodr/act-0.2.30/pkg/common/executor.go:98 +0x89
```
Thank you for the additional information I see, the secrets are used as job container credentials. Using them in steps doesn't cause a crash.

Seems like the post executor should not run if starting the container fails. I'm looking into contributing a fix for the next monthly release of act. 

I'm not shure how the error will look like, after I found a way to suppress the inconsistent state of the crash.

Fix patch:
diff --git a/pkg/runner/job_executor.go b/pkg/runner/job_executor.go
index 8bbed6c0764..8cf87a43c75 100644
--- a/pkg/runner/job_executor.go
+++ b/pkg/runner/job_executor.go
@@ -38,8 +38,6 @@ func newJobExecutor(info jobInfo, sf stepFactory, rc *RunContext) common.Executo
 		return common.NewDebugExecutor("No steps found")
 	}
 
-	preSteps = append(preSteps, info.startContainer())
-
 	for i, stepModel := range infoSteps {
 		stepModel := stepModel
 		if stepModel == nil {
@@ -104,7 +102,7 @@ func newJobExecutor(info jobInfo, sf stepFactory, rc *RunContext) common.Executo
 	pipeline = append(pipeline, preSteps...)
 	pipeline = append(pipeline, steps...)
 
-	return common.NewPipelineExecutor(pipeline...).
+	return common.NewPipelineExecutor(info.startContainer(), common.NewPipelineExecutor(pipeline...).
 		Finally(func(ctx context.Context) error {
 			var cancel context.CancelFunc
 			if ctx.Err() == context.Canceled {
@@ -116,7 +114,7 @@ func newJobExecutor(info jobInfo, sf stepFactory, rc *RunContext) common.Executo
 			return postExecutor(ctx)
 		}).
 		Finally(info.interpolateOutputs()).
-		Finally(info.closeContainer())
+		Finally(info.closeContainer()))
 }
 
 func useStepLogger(rc *RunContext, stepModel *model.Step, stage stepStage, executor common.Executor) common.Executor {


Test patch:
diff --git a/pkg/runner/runner_test.go b/pkg/runner/runner_test.go
index c307d52a4c3..86bd5c35dce 100644
--- a/pkg/runner/runner_test.go
+++ b/pkg/runner/runner_test.go
@@ -156,6 +156,7 @@ func TestRunEvent(t *testing.T) {
 		{workdir, "checkout", "push", "", platforms},
 		{workdir, "job-container", "push", "", platforms},
 		{workdir, "job-container-non-root", "push", "", platforms},
+		{workdir, "job-container-invalid-credentials", "push", "failed to handle credentials: failed to interpolate container.credentials.password", platforms},
 		{workdir, "container-hostname", "push", "", platforms},
 		{workdir, "remote-action-docker", "push", "", platforms},
 		{workdir, "remote-action-js", "push", "", platforms},
diff --git a/pkg/runner/testdata/job-container-invalid-credentials/push.yml b/pkg/runner/testdata/job-container-invalid-credentials/push.yml
new file mode 100644
index 00000000000..79c397edc9f
--- /dev/null
+++ b/pkg/runner/testdata/job-container-invalid-credentials/push.yml
@@ -0,0 +1,13 @@
+name: job-container-invalid-credentials
+on: push
+
+jobs:
+  fail-on-invalid-credentials:
+    runs-on: ubuntu-latest
+    container:
+      image: node:16-buster-slim
+      credentials:
+        username: "user"
+        password: "" # Empty password caused a crash in jobexecutor
+    steps:
+      - run: exit 0