devcontainers / ci

A GitHub Action and Azure DevOps Task designed to simplify using Dev Containers (https://containers.dev) in CI/CD systems.
MIT License
303 stars 46 forks source link

Passing an optional input that's unset to the devcontainer `env` gives `Unmatched argument format: remote-env must match <name>=<value>` #231

Closed jjgriff93 closed 4 months ago

jjgriff93 commented 1 year ago

Current behaviour

We have a re-usable workflow that has an optional input called suffix_override like so:

on:
  workflow_call:
      inputs:
          suffix_override:
            type: string
            required: false
            description: An override for the naming suffix. If defined the core address space is random

Then, in a devcontainer/ci step, we use runCmd and pass several environment variables to env, including the inputs.suffix_override:

 - name: Deploy core and build agent
        uses: devcontainers/ci@v0.3
        with:
          imageName: ${{ steps.dc.outputs.image_path }}
          imageTag: ${{ steps.dc.outputs.tag }}
          runCmd: make infrastructure-core
          push: never
          env: |
            DOCKER_BUILDKIT=1
            TF_INPUT=0
            TF_IN_AUTOMATION=1
            SUFFIX_OVERRIDE=${{ inputs.suffix_override }}
            ...

Because the suffix_override is optional, sometimes it's not set by the parent workflow. When that happens, because GitHub treats unset as empty strings, the devcontainers/ci step tries to set the env var; however it's empty, so we get an error:

Run devcontainers/ci@v0.3
Starting...
Adding --cache-from acrmgmtflwrgriffci.azurecr.io/flowehr/devcontainer:Infra-Test to build args
🏗️ build container
🏃 start container
  About to run devcontainer up --workspace-folder /home/runner/work/FlowEHR/FlowEHR --remote-env DOCKER_BUILDKIT=1 --remote-env TF_INPUT=0 --remote-env TF_IN_AUTOMATION=1 --remote-env SUFFIX=  --remote-env GITHUB_OUTPUT=/mnt/github/output --remote-env GITHUB_ENV=/mnt/github/env --remote-env GITHUB_PATH=/mnt/github/path --remote-env GITHUB_STEP_SUMMARY=/mnt/github/step-summary --cache-from acrmgmtflwrgriffci.azurecr.io/flowehr/devcontainer:Infra-Test
  devcontainer up
  Create and run dev container
  Options:
    --help                            Show help  [boolean]
    --version                         Show version number  [boolean]
    --docker-path                     Docker CLI path.  [string]
    --docker-compose-path             Docker Compose CLI path.  [string]
    ...

  Unmatched argument format: remote-env must match <name>=<value>

Error: Unexpected empty output from CLI

Note the --remove-env SUFFIX= which is the culprit.

Expected behaviour

If an env is an empty string, follow the GitHub Actions behaviour and don't set it. To illustrate this is my current workaround:

- name: Deploy core and build agent
        uses: devcontainers/ci@v0.3
        env: # Add suffix as step env so it's only passed as an env var if it's not empty
          SUFFIX_OVERRIDE: ${{ inputs.suffix_override }}
        with:
          imageName: ${{ steps.dc.outputs.image_path }}
          imageTag: ${{ steps.dc.outputs.tag }}
          runCmd: make infrastructure-core
          push: never
          env: |
            DOCKER_BUILDKIT=1
            TF_INPUT=0
            TF_IN_AUTOMATION=1
            SUFFIX_OVERRIDE
...

@stuartleeks

stuartleeks commented 1 year ago

Looking at the output, it seems that the action code passes --remote-env SUFFIX= to the devcontainer CLI.

My initial thought was that the action could detect this scenario and skip passing that env var to the CLI, but that would result in the env var not being set.

I ran a quick test of a GitHub action run that included the following step:

  - name: env var test
    env:
      TEST_VAR:
    run: |
      printenv | sort

The output included TEST_VAR= indicating that the environment variable was set as an empty string, so my inclination is to match this behaviour.

@chrmarti - what are your thoughts?