Passing Environment Variables to Reusable Workflow #26671
Replies: 30 comments 21 replies
|
I don’t think you can use You could have a step that converts an env item into an output and then use the step output was input to the reusable workflow. There are other similar restrictions, I tripped on not being able to use |
|
Yeah, I’ve dealt with the env scope problem and used outputs to get around it. I just thought this was within scope since I set the env value at the workflow level and the “With” is down in a step. Unless someone has an official position on it, I’m going to submit a feature request and see if it goes anywhere. I think the problem is specific to reusable workflows, but I’ll test. |
|
Can you please provide an example how did you do this? I cannot figure it out for hours already. |
|
https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability sorry, it’s It seems like there may be a typo in their documentation. |
Some important things to note about this code snippet that calls a reusable workflow:
|
|
Hi there. I know that the following fix doesn't cover all cases, but in case of "local" called workflows, I just applied this: being I mean I did't need to apply: |
|
Has anyone opened an issue for this? This seems like a no brainer feature/bug fix |
|
I found something like this to work for me. Nothing fancy just exposes an env var to the "with" block. Of course you could add multiple output values for more env vars. |
|
Yes, I need another workaround for something that should be a no-brainer, had to do the same to use env/inputs with It saddens me to see stuff like this, sometimes I think Github Actions is run by a skeleton crew. |
|
@github-staff Is this on the roadmap? It would be beneficial to avoid running these workarounds and be able to leverage reusable workflows with environments. |
|
This is one more time a weird an not intuitive way github actions are setup. Any person would expect to be able to use an env variable as an input of a reusable workflow, but instead there is no clean way to do it.... ... and you get a weird error message as well! In the docs https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations it is surely stated, but what is the alternative? Please fix this. |
|
Can we please have the ability to pass |
|
This has also caused a lot of issues and a several weeks delay in implementing reusable workflows for my company. The workarounds here only get us so far. When we need to add an arbitrary number of secrets to the env of the reusable workflow from the caller workflow, options are really limited, and with those limited options there are a lot of drawbacks. We were able to mostly work around this by passing a map of secrets in a JSON string to another secret then let the reusable workflow process those. However, that loses the automatic secret masking inside the reusable workflow (since secrets are no longer inherited), and we have to manually re-mask secret values. Even with that, we've run into the issue where passing toJson(secrets) causes Injecting the secrets as an output doesn't work for us since we run the reusable worfklow in a matrix of GitHub Environments, and each environment has its own environment secrets. Even if we just had more GitHub expressions available that could run a substring, replace, or convert objects to a non-prettified JSON would greatly help. |
|
I guess the use of ::set-output is now deprecated so - the accepted answer might not work... |
|
I hope GitHub has planned a method like |
BACKGROUND CONTEXTAlthough there are now docs on masking and passing secrets between jobs or workflows (as @reed-hanger linked), it didn't meet requirements like:
PROBLEM STATEMENTSWith these factors in mind, the main blockers are:
PROPOSED SOLUTION
WORKING EXAMPLEThese methods are sourced from DevSecTop/TF-via-PR (permalink) repository, which hosts a reusable workflow to run Terraform commands via PR comments, like a CLI. As a bonus, any number of secrets can be securely passed into the reusable workflow to be used as environment variables, for example. The repository also contains recent GitHub Actions workflow runs to verify that the secrets remain masked throughout. # caller-workflow.yml
jobs:
credentials:
runs-on: ubuntu-latest
outputs:
CREDENTIAL1: ${{ steps.credentials.outputs.CREDENTIAL1 }}
CREDENTIAL2: ${{ steps.credentials.outputs.CREDENTIAL2 }}
steps:
- name: Output encoded credentials
id: credentials
env:
CREDENTIAL1: ${{ secrets.CREDENTIAL1 }}
CREDENTIAL2: ${{ secrets.CREDENTIAL2 }}
run: |
echo "CREDENTIAL1=$(echo $CREDENTIAL1 | base64 -w0 | base64 -w0)" >> $GITHUB_OUTPUT
echo "CREDENTIAL2=$(echo $CREDENTIAL2 | base64 -w0 | base64 -w0)" >> $GITHUB_OUTPUT
reusable-workflow:
needs: credentials
uses: reusable-workflow.yml
secrets:
env_vars: |
CREDENTIAL1=${{ needs.credentials.outputs.CREDENTIAL1 }}
CREDENTIAL2=${{ needs.credentials.outputs.CREDENTIAL2 }}# reusable-workflow.yml
on:
workflow_call:
secrets:
env_vars:
required: true
jobs:
parse-credentials:
runs-on: ubuntu-latest
env:
env_vars: ${{ secrets.env_vars }}
steps:
- name: Decode credentials as environment variables
run: |
for i in $env_vars; do
i=$(echo $i | sed 's/=.*//g')=$(echo ${i#*=} | base64 -di | base64 -di)
echo ::add-mask::${i#*=}
printf '%s\n' "$i" >> $GITHUB_ENV
done
- name: Validate credentials
run: |
# Secrets are now available as masked environment variable.
echo $CREDENTIAL1 # or ${{ env.CREDENTIAL1 }}
echo $CREDENTIAL2 # or ${{ env.CREDENTIAL2 }}Where:
FLAWS
|
|
This is really dumb and the workaround with the extra "set environment variables" step and double base64 encoding is nasty. Has anyone raised an issue for this?! All I need to be able to do is use "environment" and "uses" together to call my reusable workflow, and pass some vars.abc and secrets.xyz parameters as inputs. I can't see a good reason why this shouldn't be allowed? |
|
2 years 2 months since this thread. Do we have a feature request? |
|
any update?? a simplistic solution would be nice |
|
When possible, use a composite action instead of reusable workflows. That being said, we should be able to define a reusable workflow env from the workflow that is calling the reusable workflow. |
|
+1 for this feature request. |
|
Migrated from GitLab CI, but this feature has still not been available for over 2 years. What a disappointment. |
|
Where is this feature? Surely this is required by so many different projects... |
|
on: jobs: |
Thanks @rdhar for your comprehensive explanation. I derived a superior solution that avoids all of your flaws. We are using it for our company here: https://github.com/MatrixAI/.github/blob/master/.github/actions/secrets-parse/action.yml. Take note that it also solves the problem of potential newlines in the input secrets. This allows us to pass a dynamic bundle of secrets down to the individual job/step in the reusable workflow. It's used like this: However we are likely to use Polykey (https://github.com/MatrixAI/Polykey) to perform a pull-based workflow as described in Github's documentation which would provide a more direct principle of least privilege process. However this secret bundle action is going to be a building block for more complex secret flows. |
|
works now |
|
Very weird that is is not built-in functionality yet, having to add that extra step is dirtying all yml files. It's kind of strange that we can inherit the secrets in a template, but not the GitHub env vars themselves? As a sidenote, I think the naming of these things is quite confusing, since there is a big difference between GitHub environment and workflow environment. The solution in actions/runner#1490 (comment) is also not that clean because we still have to explicitely load the environment and pass each var... |
|
A "variables: inherit" would be the perfect solution in my opinion. Just the same way as we have "secrets: inherit". |
|
Overcomplicating it. Simply pass the name of the environment as one input into the reusable chunk, and then as another input, pass the key of a variable in the environment that you passed the name for only, as the value. So something like this job: So, in an environment named Quality Assurance, I have variables named PKG_PATH and ARTIFACT_NAME with some value that is specific to QA, such as some QA Path, and an artifact name only in QA. Then in the reusable workflow, what you need to do is the following: The resolution by key name in the array, i.e. the square brackets, doesn't get resolved until execution time, which will follow the environment setting that happens prior to execution. This is set to the job env context, like above, and then can be referenced in the rest of the job by env. |


Uh oh!
There was an error while loading. Please reload this page.
It’s my understanding that the environment from main workflow does not extend to the reusable workflow it calls. When I dump the env from both jobs to the stdout, indeed, the env variables I set in the main job do not appear in the env of the reusable workflow I have called.
When I pass a variable other than an ‘env’ variable from the main workflow to the reusable workflow with the following syntax (an expression), it works:
When I attempt to do this with an environment variable I get an error:
Unrecognized named-value: 'env’
Here is the offending syntax:
So ‘with’ doesn’t like to evaluate the ‘env’ context in an expression.
I’ve tried bash (I’m on an ubuntu runner) notation which doesn’t work, either:
I’ve tried about everything I can think of including stupid things like quotes, using github context, etc. What is the magic cookie I need here?
All reactions