devcontainers / ci

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

feature request: inherit CI environment #242

Closed OmarTawfik closed 2 months ago

OmarTawfik commented 1 year ago

When running in GitHub actions using the built-in Docker runner:

      - name: "Run Tests"
        uses: "./.devcontainer"
        with:
          entrypoint: "./tests/run.sh"

User scripts running inside the devcontainer can read environment variables on the CI machine, like:

But unfortunately that is not the same when running through the devcontainer CLI:

      - name: "Run Tests"
        uses: "devcontainers/ci@v0.3"
        with:
          runCmd: "./tests/run.sh"

The current workarounds are to either use the env: {} input parameter of devcontainers/ci, or the remoteEnv field in devcontainer.json. But this has a major drawback. Users have to list every single environment variable their scripts (or their dependencies) can possibly use/need. The issue gets worse when using third-party scripts and CLIs that don't explicitly declare which environment variables they read, but depend on their existence to run correctly (as if they ran directly on the CI machine without the devcontainer).

I wonder if there is a reason this is not enabled by default. If so, Is it possible to configure it to inherit the CI environment variables via devcontainer.json, instead of listing every single one there?

bamurtaugh commented 1 year ago

Thank you for filing!

@stuartleeks if you have a chance, could you check this out? Thanks so much!

OmarTawfik commented 1 year ago

@stuartleeks can you please advise?

ontoneio commented 1 year ago

@bamurtaugh Do you know how much visibility this issue has? Really would appreciate some information regarding this.

It's hard to get around especially if you use secrets tooling that operates at runtime.

Can someone maybe verify a workaround? @stuartleeks ?

Part of the appeal of using this action was that the devcontainer should work as expected in some fashion both locally and in the cloud. Makes it hard to use when you can't shift it into new environments without much friction.

bamurtaugh commented 1 year ago

Thanks folks for the discussion so far.

I'd initially think that if the container has a dependency on a specific environment variable, that variable should be encoded in the dev container so that it gets set up on all environments, even when run outside of Actions. I wonder if automatically inheriting all environment variables could lead to scenarios where they're less reproducible or portable.

It'd be great to learn more about your scenarios. What type of environment variable in Actions are you trying to inject?

Additionally, if you'd like to connect with other folks in the dev container community to get their feedback and ideas on issues like these, we definitely recommend joining our Slack channel! https://aka.ms/dev-container-community

cc @jkeech

bamurtaugh commented 1 year ago

Upon some further discussion and great insights from @jkeech, I think an opt-in experience (i.e. autoEnv or inerhitEnv) could make good sense. This way it doesn't change the default experience / dev container expectations for all scenarios, but it'd be a helpful option in ones such as those detailed above. And if env was used, it could be treated as an override to anything that was automatically inherited.

OmarTawfik commented 1 year ago

An optional flag would work perfectly. This is similar to how GitHub allows passing secrets between workflows, via jobs.<job_id>.secrets.inherit:

https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idsecretsinherit

Use the inherit keyword to pass all the calling workflow's secrets to the called workflow. This includes all secrets the calling workflow has access to, namely organization, repository, and environment secrets. The inherit keyword can be used to pass secrets across repositories within the same organization, or across organizations within the same enterprise.

jobs:
  pass-secrets-to-workflow:
    uses: ./.github/workflows/called-workflow.yml
    secrets: inherit
ontoneio commented 1 year ago

our organization is using dotenv.org for our secrets management, because of its relative flexibility an simplicity.

I am using NX as my mono-repo tooling inside the development container which takes care of my variable loading locally from an .env file.

The problem comes in when I need to inject similarly named variables into my CI environment on github actions, where nx also requires them to manage my packages. Since I am using a dev container as something like a prepackaged CI environment, I need to have the ability to load the env variables inside the container at runtime.

The usage is pretty straight forward, and the only way in which I see this being able to do this currently, is running this process in the initializeCommand lifecycle script, where it can then copy 1 locally set variable DOTENV_KEY which is set in Github secrets that will allow it to decrypt the committed .env.vault file and load the environment variables in similar way that NX can take advantage of them inside the dev container inside a github actions runner.

Then we need access to the GITHUB scoped enviroment variables and it feels impractical to set all of them inside the dev container itself via containerEnv.

Thanks for the response!

bamurtaugh commented 1 year ago

Thanks all for the great context!

I've tagged this as a feature request. We welcome contributions to this repo and any other in the devcontainers org too!

OmarTawfik commented 2 months ago

@bamurtaugh I have implemented the feature via inheritEnv as you suggested above in #295 .. Please let me know if there is anything else needed.

OmarTawfik commented 2 months ago

Fixe by #295