Repository: nektos/act (language: go)

Issue:
environment variables should be case sensitive
### Bug report info

```plain text
act version:            0.2.34
GOOS:                   darwin
GOARCH:                 arm64
NumCPU:                 10
Docker host:            DOCKER_HOST environment variable is unset/empty.
Sockets found:
	/var/run/docker.sock
	/Users/jsoref/.docker/run/docker.sock
Config files:           
	/Users/jsoref/.actrc:
		#-P ubuntu-latest=node:12.20.1-buster-slim
		#-P ubuntu-20.04=node:12.20.1-buster-slim
		#-P ubuntu-18.04=node:12.20.1-buster-slim
		-P ubuntu-latest=catthehacker/ubuntu:act-latest
		-P ubuntu-20.04=catthehacker/ubuntu:act-20.04
		-P ubuntu-18.04=catthehacker/ubuntu:act-18.04
		-P ubuntu-16.04=catthehacker/ubuntu:act-16.04
		-P self-hosted=catthehacker/ubuntu:act-latest
Build info:
	Go version:            go1.19.3
	Module path:           command-line-arguments
	Main version:          
	Main path:             
	Main checksum:         
	Build settings:
		-compiler:            gc
		-ldflags:             -X main.version=0.2.34
		CGO_ENABLED:          1
		CGO_CFLAGS:           
		CGO_CPPFLAGS:         
		CGO_CXXFLAGS:         
		CGO_LDFLAGS:          
		GOARCH:               arm64
		GOOS:                 darwin
Docker Engine:
	Engine version:        20.10.18
	Engine runtime:        runc
	Cgroup version:        1
	Cgroup driver:         cgroupfs
	Storage driver:        overlay2
	Registry URI:          https://index.docker.io/v1/
	OS:                    Alpine Linux v3.16
	OS type:               linux
	OS version:            3.16.2
	OS arch:               aarch64
	OS kernel:             5.15.64-0-virt
	OS CPU:                2
	OS memory:             7938 MB
	Security options:
		name=seccomp,profile=default
```


### Command used with act

```sh
act
```


### Describe issue

GHA makes environment variables case sensitive on Linux/macOS. (On Windows, they're case preserving which is too complicated to fit in the margins.)

### Link to GitHub repository

https://github.com/jsoref/nektos-act-env-case-sensitive

### Workflow content

```yml
on: push

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - name: env
      env:
        a: 1
        B: 2
      run:
        echo "$a $B"
```


### Relevant log output

```sh
level=warning msg= ⚠ You are using Apple M1 chip and you have not specified container architecture, you might encounter issues while running act. If so, try running it with '--container-architecture linux/amd64'. ⚠ 

time="2022-12-01T23:49:37-05:00" level=debug msg="Loading environment from /tmp/nektos-act-env-case-sensitive/.env"
time="2022-12-01T23:49:37-05:00" level=debug msg="Loading secrets from /tmp/nektos-act-env-case-sensitive/.secrets"
time="2022-12-01T23:49:37-05:00" level=debug msg="Loading workflows from '/tmp/nektos-act-env-case-sensitive/.github/workflows'"
time="2022-12-01T23:49:37-05:00" level=debug msg="Loading workflows recursively"
time="2022-12-01T23:49:37-05:00" level=debug msg="Found workflow 'test.yml' in '/tmp/nektos-act-env-case-sensitive/.github/workflows/test.yml'"
time="2022-12-01T23:49:37-05:00" level=debug msg="Reading workflow '/tmp/nektos-act-env-case-sensitive/.github/workflows/test.yml'"
time="2022-12-01T23:49:37-05:00" level=debug msg="Preparing plan with all jobs"
time="2022-12-01T23:49:37-05:00" level=debug msg="Using the only detected workflow event: push"
time="2022-12-01T23:49:37-05:00" level=debug msg="Planning jobs for event: push"
time="2022-12-01T23:49:37-05:00" level=debug msg="Loading slug from git directory '/tmp/nektos-act-env-case-sensitive/.git'"
time="2022-12-01T23:49:37-05:00" level=debug msg="Loading revision from git directory '/tmp/nektos-act-env-case-sensitive/.git'"
time="2022-12-01T23:49:37-05:00" level=debug msg="Found revision: 4bad47dbaefe882a6b5b278bad97c4bd2d939a39\n"
time="2022-12-01T23:49:37-05:00" level=debug msg="HEAD points to '4bad47dbaefe882a6b5b278bad97c4bd2d939a39'"
time="2022-12-01T23:49:37-05:00" level=debug msg="using github ref: refs/heads/main"
time="2022-12-01T23:49:37-05:00" level=debug msg="Found revision: 4bad47dbaefe882a6b5b278bad97c4bd2d939a39\n"
[test.yml/test] [DEBUG] evaluating expression 'success()'
[test.yml/test] [DEBUG] expression 'success()' evaluated to 'true'
[test.yml/test] 🚀  Start image=catthehacker/ubuntu:act-latest
[test.yml/test]   🐳  docker pull image=catthehacker/ubuntu:act-latest platform= username= forcePull=false
[test.yml/test] [DEBUG]   🐳  docker pull catthehacker/ubuntu:act-latest
[test.yml/test] [DEBUG] Image exists? true
[test.yml/test]   🐳  docker create image=catthehacker/ubuntu:act-latest platform= entrypoint=["/usr/bin/tail" "-f" "/dev/null"] cmd=[]
[test.yml/test] [DEBUG] Common container.Config ==> &{Hostname: Domainname: User: AttachStdin:false AttachStdout:false AttachStderr:false ExposedPorts:map[] Tty:false OpenStdin:false StdinOnce:false Env:[RUNNER_TOOL_CACHE=/opt/hostedtoolcache RUNNER_OS=Linux RUNNER_ARCH=arm64 RUNNER_TEMP=/tmp] Cmd:[] Healthcheck:<nil> ArgsEscaped:false Image:catthehacker/ubuntu:act-latest Volumes:map[] WorkingDir:/tmp/nektos-act-env-case-sensitive Entrypoint:[] NetworkDisabled:false MacAddress: OnBuild:[] Labels:map[] StopSignal: StopTimeout:<nil> Shell:[]}
[test.yml/test] [DEBUG] Common container.HostConfig ==> &{Binds:[/var/run/docker.sock:/var/run/docker.sock] ContainerIDFile: LogConfig:{Type: Config:map[]} NetworkMode:host PortBindings:map[] RestartPolicy:{Name: MaximumRetryCount:0} AutoRemove:false VolumeDriver: VolumesFrom:[] CapAdd:[] CapDrop:[] CgroupnsMode: DNS:[] DNSOptions:[] DNSSearch:[] ExtraHosts:[] GroupAdd:[] IpcMode: Cgroup: Links:[] OomScoreAdj:0 PidMode: Privileged:false PublishAllPorts:false ReadonlyRootfs:false SecurityOpt:[] StorageOpt:map[] Tmpfs:map[] UTSMode: UsernsMode: ShmSize:0 Sysctls:map[] Runtime: ConsoleSize:[0 0] Isolation: Resources:{CPUShares:0 Memory:0 NanoCPUs:0 CgroupParent: BlkioWeight:0 BlkioWeightDevice:[] BlkioDeviceReadBps:[] BlkioDeviceWriteBps:[] BlkioDeviceReadIOps:[] BlkioDeviceWriteIOps:[] CPUPeriod:0 CPUQuota:0 CPURealtimePeriod:0 CPURealtimeRuntime:0 CpusetCpus: CpusetMems: Devices:[] DeviceCgroupRules:[] DeviceRequests:[] KernelMemory:0 KernelMemoryTCP:0 MemoryReservation:0 MemorySwap:0 MemorySwappiness:<nil> OomKillDisable:<nil> PidsLimit:<nil> Ulimits:[] CPUCount:0 CPUPercent:0 IOMaximumIOps:0 IOMaximumBandwidth:0} Mounts:[{Type:volume Source:act-toolcache Target:/toolcache ReadOnly:false Consistency: BindOptions:<nil> VolumeOptions:<nil> TmpfsOptions:<nil>} {Type:volume Source:act-test-yml-test-env Target:/var/run/act ReadOnly:false Consistency: BindOptions:<nil> VolumeOptions:<nil> TmpfsOptions:<nil>} {Type:volume Source:act-test-yml-test Target:/tmp/nektos-act-env-case-sensitive ReadOnly:false Consistency: BindOptions:<nil> VolumeOptions:<nil> TmpfsOptions:<nil>}] MaskedPaths:[] ReadonlyPaths:[] Init:<nil>}
[test.yml/test] [DEBUG] Created container name=act-test-yml-test id=6a8c84f736ae5c326b7ac33bdd10ab82c8e66a77c73d6c33aad041af79ecb759 from image catthehacker/ubuntu:act-latest (platform: )
[test.yml/test] [DEBUG] ENV ==> [RUNNER_TOOL_CACHE=/opt/hostedtoolcache RUNNER_OS=Linux RUNNER_ARCH=arm64 RUNNER_TEMP=/tmp]
[test.yml/test]   🐳  docker run image=catthehacker/ubuntu:act-latest platform= entrypoint=["/usr/bin/tail" "-f" "/dev/null"] cmd=[]
[test.yml/test] [DEBUG] Starting container: 6a8c84f736ae5c326b7ac33bdd10ab82c8e66a77c73d6c33aad041af79ecb759
[test.yml/test] [DEBUG] Started container: 6a8c84f736ae5c326b7ac33bdd10ab82c8e66a77c73d6c33aad041af79ecb759
[test.yml/test] [DEBUG] Writing entry to tarball workflow/event.json len:2
[test.yml/test] [DEBUG] Writing entry to tarball workflow/envs.txt len:0
[test.yml/test] [DEBUG] Writing entry to tarball workflow/paths.txt len:0
[test.yml/test] [DEBUG] Extracting content to '/var/run/act/'
[test.yml/test] [DEBUG] Loading slug from git directory '/tmp/nektos-act-env-case-sensitive/.git'
[test.yml/test] [DEBUG] Loading revision from git directory '/tmp/nektos-act-env-case-sensitive/.git'
[test.yml/test] [DEBUG] Found revision: 4bad47dbaefe882a6b5b278bad97c4bd2d939a39
[test.yml/test] [DEBUG] HEAD points to '4bad47dbaefe882a6b5b278bad97c4bd2d939a39'
[test.yml/test] [DEBUG] using github ref: refs/heads/main
[test.yml/test] [DEBUG] Found revision: 4bad47dbaefe882a6b5b278bad97c4bd2d939a39
[test.yml/test] [DEBUG] Loading slug from git directory '/tmp/nektos-act-env-case-sensitive/.git'
[test.yml/test] [DEBUG] Loading revision from git directory '/tmp/nektos-act-env-case-sensitive/.git'
[test.yml/test] [DEBUG] Found revision: 4bad47dbaefe882a6b5b278bad97c4bd2d939a39
[test.yml/test] [DEBUG] HEAD points to '4bad47dbaefe882a6b5b278bad97c4bd2d939a39'
[test.yml/test] [DEBUG] using github ref: refs/heads/main
[test.yml/test] [DEBUG] Found revision: 4bad47dbaefe882a6b5b278bad97c4bd2d939a39
[test.yml/test] [DEBUG] Loading slug from git directory '/tmp/nektos-act-env-case-sensitive/.git'
[test.yml/test] [DEBUG] Loading revision from git directory '/tmp/nektos-act-env-case-sensitive/.git'
[test.yml/test] [DEBUG] Found revision: 4bad47dbaefe882a6b5b278bad97c4bd2d939a39
[test.yml/test] [DEBUG] HEAD points to '4bad47dbaefe882a6b5b278bad97c4bd2d939a39'
[test.yml/test] [DEBUG] using github ref: refs/heads/main
[test.yml/test] [DEBUG] Found revision: 4bad47dbaefe882a6b5b278bad97c4bd2d939a39
[test.yml/test] [DEBUG] setupEnv => map[A:1 ACT:true AGENT_TOOLSDIRECTORY:/opt/hostedtoolcache B:2 CI:true DEBIAN_FRONTEND:noninteractive DEPLOYMENT_BASEPATH:/opt/runner GITHUB_ACTION:0 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:nektos/act GITHUB_API_URL:https://api.github.com GITHUB_BASE_REF: GITHUB_ENV:/var/run/act/workflow/envs.txt GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/var/run/act/workflow/event.json GITHUB_GRAPHQL_URL:https://api.github.com/graphql GITHUB_HEAD_REF: GITHUB_JOB:test GITHUB_PATH:/var/run/act/workflow/paths.txt GITHUB_REF:refs/heads/main GITHUB_REF_NAME:main GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:jsoref/nektos-act-env-case-sensitive GITHUB_REPOSITORY_OWNER:jsoref GITHUB_RETENTION_DAYS:0 GITHUB_RUN_ID:1 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://github.com GITHUB_SHA:4bad47dbaefe882a6b5b278bad97c4bd2d939a39 GITHUB_TOKEN: GITHUB_WORKFLOW:test.yml GITHUB_WORKSPACE:/tmp/nektos-act-env-case-sensitive IMAGE_OS:ubuntu20 ImageOS:ubuntu20 LSB_OS_VERSION:2004 LSB_RELEASE:20.04 PATH:/opt/hostedtoolcache/node/16.18.1/arm64/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin RUNNER_PERFLOG:/dev/null RUNNER_TRACKING_ID: RUNNER_USER:root RUN_TOOL_CACHE:/opt/hostedtoolcache USER:root]
[test.yml/test] [DEBUG] Loading slug from git directory '/tmp/nektos-act-env-case-sensitive/.git'
[test.yml/test] [DEBUG] Loading revision from git directory '/tmp/nektos-act-env-case-sensitive/.git'
[test.yml/test] [DEBUG] Found revision: 4bad47dbaefe882a6b5b278bad97c4bd2d939a39
[test.yml/test] [DEBUG] HEAD points to '4bad47dbaefe882a6b5b278bad97c4bd2d939a39'
[test.yml/test] [DEBUG] using github ref: refs/heads/main
[test.yml/test] [DEBUG] Found revision: 4bad47dbaefe882a6b5b278bad97c4bd2d939a39
[test.yml/test] [DEBUG] Loading slug from git directory '/tmp/nektos-act-env-case-sensitive/.git'
[test.yml/test] [DEBUG] Loading revision from git directory '/tmp/nektos-act-env-case-sensitive/.git'
[test.yml/test] [DEBUG] Found revision: 4bad47dbaefe882a6b5b278bad97c4bd2d939a39
[test.yml/test] [DEBUG] HEAD points to '4bad47dbaefe882a6b5b278bad97c4bd2d939a39'
[test.yml/test] [DEBUG] using github ref: refs/heads/main
[test.yml/test] [DEBUG] Found revision: 4bad47dbaefe882a6b5b278bad97c4bd2d939a39
[test.yml/test] [DEBUG] evaluating expression ''
[test.yml/test] [DEBUG] expression '' evaluated to 'true'
[test.yml/test] ⭐ Run Main env
[test.yml/test] [DEBUG] Writing entry to tarball workflow/outputcmd.txt len:0
[test.yml/test] [DEBUG] Writing entry to tarball workflow/statecmd.txt len:0
[test.yml/test] [DEBUG] Extracting content to '/var/run/act'
[test.yml/test] [DEBUG] Loading slug from git directory '/tmp/nektos-act-env-case-sensitive/.git'
[test.yml/test] [DEBUG] Loading revision from git directory '/tmp/nektos-act-env-case-sensitive/.git'
[test.yml/test] [DEBUG] Found revision: 4bad47dbaefe882a6b5b278bad97c4bd2d939a39
[test.yml/test] [DEBUG] HEAD points to '4bad47dbaefe882a6b5b278bad97c4bd2d939a39'
[test.yml/test] [DEBUG] using github ref: refs/heads/main
[test.yml/test] [DEBUG] Found revision: 4bad47dbaefe882a6b5b278bad97c4bd2d939a39
[test.yml/test] [DEBUG] Loading slug from git directory '/tmp/nektos-act-env-case-sensitive/.git'
[test.yml/test] [DEBUG] Loading revision from git directory '/tmp/nektos-act-env-case-sensitive/.git'
[test.yml/test] [DEBUG] Found revision: 4bad47dbaefe882a6b5b278bad97c4bd2d939a39
[test.yml/test] [DEBUG] HEAD points to '4bad47dbaefe882a6b5b278bad97c4bd2d939a39'
[test.yml/test] [DEBUG] using github ref: refs/heads/main
[test.yml/test] [DEBUG] Found revision: 4bad47dbaefe882a6b5b278bad97c4bd2d939a39
[test.yml/test] [DEBUG] Loading slug from git directory '/tmp/nektos-act-env-case-sensitive/.git'
[test.yml/test] [DEBUG] Loading revision from git directory '/tmp/nektos-act-env-case-sensitive/.git'
[test.yml/test] [DEBUG] Found revision: 4bad47dbaefe882a6b5b278bad97c4bd2d939a39
[test.yml/test] [DEBUG] HEAD points to '4bad47dbaefe882a6b5b278bad97c4bd2d939a39'
[test.yml/test] [DEBUG] using github ref: refs/heads/main
[test.yml/test] [DEBUG] Found revision: 4bad47dbaefe882a6b5b278bad97c4bd2d939a39
[test.yml/test] [DEBUG] Loading slug from git directory '/tmp/nektos-act-env-case-sensitive/.git'
[test.yml/test] [DEBUG] Loading revision from git directory '/tmp/nektos-act-env-case-sensitive/.git'
[test.yml/test] [DEBUG] Found revision: 4bad47dbaefe882a6b5b278bad97c4bd2d939a39
[test.yml/test] [DEBUG] HEAD points to '4bad47dbaefe882a6b5b278bad97c4bd2d939a39'
[test.yml/test] [DEBUG] using github ref: refs/heads/main
[test.yml/test] [DEBUG] Found revision: 4bad47dbaefe882a6b5b278bad97c4bd2d939a39
[test.yml/test] [DEBUG] Wrote command 

echo "$a $B"

 to 'workflow/0'
[test.yml/test] [DEBUG] Writing entry to tarball workflow/0 len:14
[test.yml/test] [DEBUG] Extracting content to '/var/run/act'
[test.yml/test]   🐳  docker exec cmd=[bash --noprofile --norc -e -o pipefail /var/run/act/workflow/0] user= workdir=
[test.yml/test] [DEBUG] Exec command '[bash --noprofile --norc -e -o pipefail /var/run/act/workflow/0]'
[test.yml/test] [DEBUG] Working directory '/tmp/nektos-act-env-case-sensitive'
[test.yml/test]   |  2
[test.yml/test]   ✅  Success - Main env
[test.yml/test] [DEBUG] Removed container: 6a8c84f736ae5c326b7ac33bdd10ab82c8e66a77c73d6c33aad041af79ecb759
[test.yml/test] [DEBUG]   🐳  docker volume rm act-test-yml-test
[test.yml/test] [DEBUG]   🐳  docker volume rm act-test-yml-test-env
[test.yml/test] 🏁  Job succeeded
[test.yml/test] [DEBUG] Loading slug from git directory '/tmp/nektos-act-env-case-sensitive/.git'
[test.yml/test] [DEBUG] Loading revision from git directory '/tmp/nektos-act-env-case-sensitive/.git'
[test.yml/test] [DEBUG] Found revision: 4bad47dbaefe882a6b5b278bad97c4bd2d939a39
[test.yml/test] [DEBUG] HEAD points to '4bad47dbaefe882a6b5b278bad97c4bd2d939a39'
[test.yml/test] [DEBUG] using github ref: refs/heads/main
[test.yml/test] [DEBUG] Found revision: 4bad47dbaefe882a6b5b278bad97c4bd2d939a39
```


### Additional information

https://github.com/jsoref/nektos-act-env-case-sensitive/actions/runs/3598970524/jobs/6062193588#step:2:1

Run echo "$a $B"
```
1 2
```

---

```
|  2
```

The `|` is from the docker environment and doesn't count as output.


Discussion / hints:
Hmm, you found something I have not expected in the codebase

https://github.com/nektos/act/blob/7754ba7fcf3f80b76bb4d7cf1edbe5935c8a6bdc/pkg/model/workflow.go#L463-L470

@KnisterPeter git blame tells me that it was your PR
Yes I'm guilty. That seem to be a regression.

~~I don't think I did a regression, it was like that before:~~

https://github.com/nektos/act/blob/7754ba7fcf3f80b76bb4d7cf1edbe5935c8a6bdc/pkg/model/workflow.go#L479

~~But anyway I'll look if I can provide a fix for that.~~

Hmm, maybe I'm wrong here :smile: 


Fix patch:
diff --git a/pkg/model/workflow.go b/pkg/model/workflow.go
index f567a1f7806..78914e82e2f 100644
--- a/pkg/model/workflow.go
+++ b/pkg/model/workflow.go
@@ -458,16 +458,8 @@ func (s *Step) String() string {
 }
 
 // Environments returns string-based key=value map for a step
-// Note: all keys are uppercase
 func (s *Step) Environment() map[string]string {
-	env := environment(s.Env)
-
-	for k, v := range env {
-		delete(env, k)
-		env[strings.ToUpper(k)] = v
-	}
-
-	return env
+	return environment(s.Env)
 }
 
 // GetEnv gets the env for a step
diff --git a/pkg/runner/step.go b/pkg/runner/step.go
index 560ba632a79..a3829fb9bbe 100644
--- a/pkg/runner/step.go
+++ b/pkg/runner/step.go
@@ -183,7 +183,7 @@ func setupEnv(ctx context.Context, step step) error {
 			(*step.getEnv())[k] = exprEval.Interpolate(ctx, v)
 		}
 	}
-	// after we have an evaluated step context, update the expresson evaluator with a new env context
+	// after we have an evaluated step context, update the expressions evaluator with a new env context
 	// you can use step level env in the with property of a uses construct
 	exprEval = rc.NewExpressionEvaluatorWithEnv(ctx, *step.getEnv())
 	for k, v := range *step.getEnv() {


Test patch:
diff --git a/pkg/runner/testdata/environment-variables/push.yml b/pkg/runner/testdata/environment-variables/push.yml
new file mode 100644
index 00000000000..37218ad1372
--- /dev/null
+++ b/pkg/runner/testdata/environment-variables/push.yml
@@ -0,0 +1,33 @@
+name: environment variables
+on: push
+
+jobs:
+  test:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Test on job level
+        run: |
+          echo \$UPPER=$UPPER
+          echo \$upper=$upper
+          echo \$LOWER=$LOWER
+          echo \$lower=$lower
+          [[ "$UPPER" = "UPPER" ]] || exit 1
+          [[ "$upper" = "" ]] || exit 1
+          [[ "$LOWER" = "" ]] || exit 1
+          [[ "$lower" = "lower" ]] || exit 1
+      - name: Test on step level
+        run: |
+          echo \$UPPER=$UPPER
+          echo \$upper=$upper
+          echo \$LOWER=$LOWER
+          echo \$lower=$lower
+          [[ "$UPPER" = "upper" ]] || exit 1
+          [[ "$upper" = "" ]] || exit 1
+          [[ "$LOWER" = "" ]] || exit 1
+          [[ "$lower" = "LOWER" ]] || exit 1
+        env:
+          UPPER: upper
+          lower: LOWER
+    env:
+      UPPER: UPPER
+      lower: lower