Load `env` from files
It would be awesome if env could be loaded from a file. Example:
name: Loading env vars from file
on:
push:
branches:
- develop
env-file: dev.env
env:
other-env-var: env-var-value
jobs:
build:
...
A workaround would be to use core.exportVariable or fromJson:
jobs:
env:
runs-on: ubuntu-latest
outputs:
env: ${{ steps.import-env.outputs.result }}
steps:
- uses: actions/checkout@v2
- name: Import environment variables from a file
id: import-env
uses: actions/github-script@v2
with:
script: |
const env = parseEnv(`${process.env.GITHUB_WORKSPACE}/dev.env`);
Object.entries(env).forEach(x => core.exportVariable(...x)); // current job-level env
return env;
- name: Print environment variable
run: echo $ABC
env: ${{ fromJson(steps.import-env.outputs.result) }} # step-level env
build:
runs-on: ubuntu-latest
needs: [env]
env: ${{ fromJson(needs.env.outputs.env) }} # job-level env
steps:
- name: Print environment variable
run: echo $ABC
Note I've used actions/github-script to parse the .env to a JavaScript object. If the file is JSON, it's possible to directly read the file into the output.
We wrote an action that loads yaml, json, or env files into the current jobs env. However there is no good way to load into the workflow's env. Seems like that should be a feature.
parseEnv is not defined:
Run actions/github-script@v2
ReferenceError: parseEnv is not defined
Error: Unhandled error: ReferenceError: parseEnv is not defined
at eval (eval at callAsyncFunction (/home/runner/work/_actions/actions/github-script/v2/dist/index.js:7985:56), <anonymous>:3:13)
at callAsyncFunction (/home/runner/work/_actions/actions/github-script/v2/dist/index.js:7986:12)
at main (/home/runner/work/_actions/actions/github-script/v2/dist/index.js:8011:26)
at Module.833 (/home/runner/work/_actions/actions/github-script/v2/dist/index.js:7995:1)
at __webpack_require__ (/home/runner/work/_actions/actions/github-script/v2/dist/index.js:22:30)
at startup (/home/runner/work/_actions/actions/github-script/v2/dist/index.js:37:19)
at /home/runner/work/_actions/actions/github-script/v2/dist/index.js:43:18
at Object.<anonymous> (/home/runner/work/_actions/actions/github-script/v2/dist/index.js:46:10)
at Module._compile (internal/modules/cjs/loader.js:959:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
Ended up doing it with the shell:
- name: Import environment variables from a file
id: import-env
shell: bash
run: |
while read line; do
echo "$line" >> $GITHUB_ENV
done < ${{ env.ENV_FILE }}
Ended up doing it with the shell:
- name: Import environment variables from a file id: import-env shell: bash run: | while read line; do echo "$line" >> $GITHUB_ENV done < ${{ env.ENV_FILE }}
Why not just use cat?
run: cat ${{ env.ENV_FILE }} >> $GITHUB_ENV
or
run: < ${{ env.ENV_FILE }} >> $GITHUB_ENV
Ended up doing it with the shell:
- name: Import environment variables from a file id: import-env shell: bash run: | while read line; do echo "$line" >> $GITHUB_ENV done < ${{ env.ENV_FILE }}
@rgstephens
Im completely new to powershell scripts.
Can you post a windows runner script? Please
I faced with the same question and made a export-env-action that you can use as one of your steps:
constants.env file:
PROTOCOL=https
HOST=example.com
PORT=8080
URI=${PROTOCOL}://${HOST}:${PORT}
a step in your workflow:
- uses: cardinalby/export-env-action@v1
with:
envFile: 'constants.env'
expand: 'true'
# env.PROTOCOL == 'https'
# env.HOST == 'example.com'
# env.PORT == '8080'
# env.URI == 'https://example.com:8080'
Is there anyway to load from an .env file and use it when defining the credentials of a MySQL service? (e.g. DB_PORT=3307)
services:
mysql:
image: mysql:5.7
ports:
- $DB_PORT:3306
Is there anyway to load from an
.envfile and use it when defining the credentials of a MySQL service? (e.g.DB_PORT=3307)services: mysql: image: mysql:5.7 ports: - $DB_PORT:3306
First, I would warn you that if you store your creds in .env file in the repo then you probably doing something wrong and you should use GitHub Secrets instead.
You case can make sense if you download env file from outside for example. Then, yes, you can use mentioned cardinalby/export-env-action action to read the creds (use mask parameter to mark values as secrets in the workflow) and use ${{ env.MY_PSW }} expression in the workflow. But be aware that other untrasted steps in your workflow can also have access to env variables
Jumping in here with another solution since some of these didn't exactly do what I needed, which was to load a regular env file like this:
Into the env vars of the job itself so I can do other env replacement in subsequent steps without having to enumerate all the vars in the env file.
This did the trick:
- name: Inject env vars
run: |
export $(grep -Ev ^'(#|$)' .env)
envsubst < ./apps/api/.ebextensions/03_inject_env_vars.config | tee ./apps/api/.ebextensions/03_inject_env_vars.config
export takes in the output from grep which removes empty lines and comments from the file
envsubst does env substitution on the targeted file, finds all vars that are wrapped in brackets ${VAR} and replaces it with the actual value from the env file... all without having to enumerate them one by one.
Ended up doing it with the shell:
- name: Import environment variables from a file id: import-env shell: bash run: | while read line; do echo "$line" >> $GITHUB_ENV done < ${{ env.ENV_FILE }}
I have my ENV_FILE stored as a secret because it is quite large and has a few credentials in there.
How could I load in from a secret instead of a file?
Any references for the code above would be handy too.
I faced with the same question and made a export-env-action that you can use as one of your steps:
constants.env file:
PROTOCOL=https HOST=example.com PORT=8080 URI=${PROTOCOL}://${HOST}:${PORT}a step in your workflow:
- uses: cardinalby/export-env-action@v1 with: envFile: 'constants.env' expand: 'true' # env.PROTOCOL == 'https' # env.HOST == 'example.com' # env.PORT == '8080' # env.URI == 'https://example.com:8080'
I use a secret in the repo for my env file (we keep an env file for LOCAL, DEV, CI and PRODUCTION) so was able to use this approach by adding the following to the start of my job
- name: Create .env file from Secret
id: import-env
run: |
echo "${{ secrets.ENV_FILE }}" >> .env
- uses: cardinalby/export-env-action@v2
with:
mask: true
envFile: '.env'
I'm not sure what best practice is here and my only concern is that .env file hanging around but it works and the variables are masked in the logging - so thank you @cardinalby !
For posterity, the following is what I was trying which lead me here because the variables were all printed to the console:
- name: Setup environment
run: |
echo "${{ secrets.ENV_FILE }}" >> $GITHUB_ENV
@moleary-gsa I would comment on your approach:
- You can remove env file after
cardinalby/export-env-action@v2step because of the security concerns - Even though secrets are masked in the log, I still don't recommend exporting all secrets in this way for the entire job making them available for all untrusted steps. Instead, you should pass secrets only for the steps where they are actually needed.
You can achieve it by using export: false input for export action:
- uses: cardinalby/export-env-action@v2
id: readEnvFile
with:
mask: true
export: false
envFile: '.env'
And pass the secrets to the steps where they are needed by accessing them as steps.readEnvFile.outputs.YOUR_SECRET_NAME
Thank you for your interest in the runner application and taking the time to provide your valuable feedback. We kindly ask you to redirect this feedback to the GitHub Community Support Forum which our team actively monitors and would be a better place to start a discussion for new feature requests in GitHub Actions. For more information on this policy please read our contribution guidelines. 😃