Environment variables are overwritten by previous actions and break consecutive Docker Actions

I wrote a GitHub Action which uses the Golang base image to install some additional tooling. I have a workflow like this:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Install Go
        uses: actions/setup-go@v2
        with:
          go-version: 1.14
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Test
        run: go test -tags sqlite -failfast ./...

# This is my own Docker-based action:
      -
        name: Build release snapshot
        uses: ory/actions@v0.0.14
        with:
          run: release/snapshot

Executing the ory/actions action fails because GitHub Actions overrides the GOROOT path which is apparently being set by actions/setup-go@v2:

   ⨯ build failed after 0.01s error=hook failed: go mod download
30
go: cannot find GOROOT directory: /opt/hostedtoolcache/go/1.14.4/x64

This happens because the docker exec command appears to be setting the GOROOT env var to /opt/hostedtoolcache/go/1.14.4/x64 (apparently the value coming from actions/setup-go@v2). This is reflected in the GitHub Workflow log (https://github.com/ory/cli/pull/11/checks?check_run_id=865292617#step:6:10):

/usr/bin/docker run --name c201270f687b95744d53b57aea51f5a87bec_ed5ed4 --label 87c201 --workdir /github/workspace --rm -e GOROOT  ...

I would not expect that two actions have side effects which may break one or the other action. I’ve already observed that with other actions as well (golangci-lint breaks when actions/setup-go@v2 is executed prior). How can I prevent this from happening? I do not want to run a dedicated job as a workaround.

1 Like

@aeneasr,

According to my troubleshooting:
Unlike “GITHUB_WORKSPACE”, the directory “GOROOT” or the tool cache directory (RUNNER_TOOL_CACHE=/opt/hostedtoolcache) will not be automatically set volume to share data between the container and the runner machine, when startup the container.

docker run
...
-e GOROOT
-e RUNNER_TOOL_CACHE
-e GITHUB_WORKSPACE
...
-v "/home/runner/work/my-repos/my-repos":"/github/workspace"

This causes that when the environment variable “GOROOT” is mapped in the container, its value still is the path in the runner machine’s filesystem, instead of an existing path in the container’s filesystem.

I tried to set the volume for “GOROOT” in the Dockerfile by using the VOLUME instruction, but it did not work. I also tried to set these steps into a container job, but still did not work as expected.

I’m not sure if there are any other ways to set some custom volumes on a Docker container action, or to access the runner machine’s filesystem when running in the container.
I have created an internal ticket to report this question to the appropriate engineering team for further discussion and evaluation. If they have any progress, I will notify you in time, and sometimes the appropriate engineers may directly reply you here.

1 Like

As you correctly identified in your post, the issue you’re running into here @aeneasr is that when we run Dockerfile-based actions, we pass the environment variables set by prior steps to the docker run command. That’s why your GOROOT environment variable is being overridden.

There are a few options here of varying degrees of complexity.

Option 1: Unset GOROOT Explicitly

Since GOROOT isn’t set by the golang container, and I don’t think you’re setting it explicitly anywhere, you can also add unset GOROOT to your entrypoint.sh script, which I believe would also solve this.

Option 2: Run tests in the Dockerfile

In your workflow, rather than using actions/setup-go and then running your tests, run the tests as an additional preliminary stage in your release Dockerfile.

Option 3: Build and Run Without an Action

Rather than relying on an action to build and run this Dockerfile, you can explicitly also just call the docker command line tool in the VM (for example: run: docker build ... and run: docker run ...). Since the Dockerfile and associated scripts are in a separate repository, you’d have to clone that repository to the VM (via actions/checkout or just a run: git clone ...), and then explicitly docker build and docker run it. Or, you could move it the repository where this workflow is running and it’d already be copied by your checkout step.

You may wonder why we pass all of the environment variables set by prior steps to the docker run command. The use of Docker in an action is meant to be as transparent as possible to consumers of that action, and so we carry the environment over. Obviously, this can cause confusion for specific use cases like this one, however, but there are the above workarounds.