Check whether environment variable is empty - github-actions

What is the nicest approach to check if environment variable is empty on Github action as a condition to a step? I've tried the trivial approach but it doesn't seem to work.
For example:
name: SimpleWorkflow
on:
push:
env:
MULTI_LINE_ARG: |
ARG1: value
jobs:
update:
runs-on: ubuntu-latest
steps:
- name: Fetching Local Repository
uses: actions/checkout#master
- name: run step if multiline not null
if: ${{env.MULTI_LINE_ARG}} != ""
run: echo multiline not null
No matter how I've tried this I fail to properly check if env is empty.

Updated to new GitHub syntax (as of 2022-12)
Background: The issue of secrets not available to forks is known to GitHub folks, but no concrete activity announced: https://github.community/t/github-workflow-not-running-from-pull-request-from-forked-repository/16379/41?u=koppor
One can use output variables of steps to determine whether a secret is available.
The name of the secret in GitHub is SECRET.
- name: Check secrets presence
id: checksecrets
shell: bash
run: |
if [ "$SECRET" == "" ]; then
echo "secretspresent=NO" >> $GITHUB_OUTPUT
else
echo "secretspresent=YES" >> $GITHUB_OUTPUT
fi
env:
SECRET: ${{ secrets.SECRET}}
- name: run step if secret is present
if: (steps.checksecrets.outputs.secretspresent == 'YES')
run: echo secret is present
Note: Solution adapted from https://github.community/t/if-expression-with-context-variable/16558/6?u=koppor.

Related

Setting env varables for entire workflow [duplicate]

I'd like to define and set environment variable between jobs inside my Github Actions Workflow.
The workflow below is what I've tried but unfortunately the environment variable GIT_PR_SHA_SHORT and E2E_GIT_PR_SHA not working.
Is it possible?
name: Git Pull Request Workflow
on:
workflow_dispatch:
pull_request:
branches:
- master
env:
GIT_PR_SHA: ${{github.event.pull_request.head.sha}}
GIT_PR_SHA_SHORT: "${{ env.GIT_PR_SHA:0:10 }}"
ENV_NAME: test
E2E_GIT_PR_SHA: "${{ env.ENV_NAME }}-${{ env.GIT_PR_SHA_SHORT }}"
jobs:
first-job:
name: Build Docker Image
runs-on: ubuntu-latest
steps:
- name: First Echo Step
run: |
echo "GIT_PR_SHA_SHORT = ${GIT_PR_SHA_SHORT}"
echo "E2E_GIT_PR_SHA = ${E2E_GIT_PR_SHA}"
second-job:
name: Build Docker Image
runs-on: ubuntu-latest
steps:
- name: Second Echo Step
run: |
echo "GIT_PR_SHA_SHORT = ${GIT_PR_SHA_SHORT}"
echo "E2E_GIT_PR_SHA = ${E2E_GIT_PR_SHA}"
You reference a workflow's environment variables with ${{ env.VARIABLE_NAME }} not ${VARIABLE_NAME}. The latter is bash syntax, but these are not shell environment variables, they're workflow environment variables. They're part of the workflow execution, not part of the shell's context.
To reference a workflow environment variable:
name: Git Pull Request Workflow
on:
workflow_dispatch:
pull_request:
branches:
- master
env:
one: 1
two: zwei
three: tres
jobs:
first-job:
runs-on: ubuntu-latest
steps:
- run: |
echo "${{ env.one }}"
echo "${{ env.two }}"
echo "${{ env.three }}"
(I like to use lower-case for my workflow environment variables, and UPPER_CASE for my shell environment variables, so that it's more obvious to me which is which.)
Similarly, this won't work:
env:
GIT_PR_SHA_SHORT: "${{ env.GIT_PR_SHA:0:10 }}"
This is mixing bash syntax :0:10 with the workflow syntax, but the workflow variables are not run through any shell. No virtual machine has been started when the workflow file is parsed, so there's no shell to run things though.
If you wanted to use bash expressions to manipulate the environment, you would need to create a step that runs bash to do that, and you would need to use the ::set-env or ::set-output syntax.
Then you can refer to a step's output using the ${{ steps... }} context.
Unfortunately, passing things between different jobs is trickier, since they run on different virtual machines. You'll need to set variables on the overall workflow itself. You'll need to first ::set-output so that it's visible to the job, then you can raise the visibility from the job to the workflow.
name: Demonstration
on:
push:
branches: [master]
jobs:
first-job:
runs-on: ubuntu-latest
steps:
- id: identify
run: |
# use bash variable expression to get the substring
export GIT_PR_SHA="${{ github.sha }}"
export GIT_PR_SHA_SHORT="${GIT_PR_SHA:0:10}"
echo "::set-output name=git_pr_sha::${GIT_PR_SHA}"
echo "::set-output name=git_pr_sha_short::${GIT_PR_SHA_SHORT}"
outputs:
git_pr_sha: ${{ steps.identify.outputs.git_pr_sha }}
git_pr_sha_short: ${{ steps.identify.outputs.git_pr_sha_short }}
second-job:
needs: first-job
runs-on: ubuntu-latest
steps:
- run: |
echo "${{ needs.first-job.outputs.git_pr_sha }}"
echo "${{ needs.first-job.outputs.git_pr_sha_short }}"
I'd like to add an extension to this since I've had similar difficulties finding how to compute & set environment variables for multi-step use.
Below is a basic example of how to push back to the github environment from within a step if processing is needed to compute an environment variable for later use. You can also update existing variables this same way, not just create new.
name: minimal variable example
on:
push:
env:
MAJOR: "1"
MINOR: "0"
PATCH: "1"
jobs:
vars-example:
runs-on: ubuntu-latest
steps:
- name: only available local variable
run: LOCAL_VERSION=${MAJOR}.${MINOR}.${PATCH}
- name: available across multiple steps
run: echo "GLOBAL_VERSION=${MAJOR}.${MINOR}.${PATCH}" >> $GITHUB_ENV
- name: Vars
run: |
echo LOCAL_VERSION = $LOCAL_VERSION
echo GLOBAL_VERSION = $GLOBAL_VERSION
which results in Vars output of
echo LOCAL_VERSION = $LOCAL_VERSION
echo GLOBAL_VERSION = $GLOBAL_VERSION
shell: /usr/bin/bash -e {0}
env:
MAJOR: 1
MINOR: 0
PATCH: 1
GLOBAL_VERSION: 1.0.1
LOCAL_VERSION =
GLOBAL_VERSION = 1.0.1
You can't use env in an expression under the env element. I don't see another way than using duplicate values instead of an expression.
The env context syntax allows you to use the value of an environment variable in your workflow file. You can use the env context in the value of any key in a step except for the id and uses keys. For more information on the step syntax, see "Workflow syntax for GitHub Actions".
https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#env-context
The following is the newer way of sharing the variables across jobs after the deprication
Have also covered the scenario when the value itself is a variable and needs to be computed at runtime.
The following would be invoked when a push is made master branch
name: Sharing envs across jobs
on:
push:
branches: ['master']
env:
one: onevalue
two: twovalue
three: threevalue
jobs:
job0:
runs-on: ubuntu-latest
steps:
- run: |
echo "${{ env.one }}"
echo "${{ env.two }}"
echo "${{ env.three }}"
job1:
runs-on: ubuntu-latest
# Map a step output to a job output
outputs:
output1: ${{ steps.step1.outputs.test }}
output2: ${{ steps.step2.outputs.test }}
steps:
- id: step1
run: echo "test=$(date +"%d-%m-%Y")-asdfads223" >> $GITHUB_OUTPUT
- id: step2
run: echo "test=world" >> $GITHUB_OUTPUT
job2:
runs-on: ubuntu-latest
needs: job1
steps:
- run: echo ${{needs.job1.outputs.output1}} ${{needs.job1.outputs.output2}}

Having issues with variables and outputs

I started learning Github Actions a few days ago and I am playing around with it. I am having issues with defining outputs and using them in variables or as input values in another workflow step. I am not sure what I am doing wrong.
name: Demo
on:
workflow_dispatch:
jobs:
build:
runs-on: [ ubuntu-latest ]
outputs:
paths: ${{ steps.find_path.outputs.paths }}
steps:
- name: Code Checkout
uses: actions/checkout#v2
- name: Find Paths
id: find_path
run: |
all_paths=$(cat document.txt)
# some code
echo "::set-output name=paths::$(echo ${all_paths})"
- name: List
id: list_path
run: |
var_paths=${{ steps.find_path.outputs.paths }}
for part in ${var_paths[#]}; do
# parent_dir=$(cat...)
# ....
# some code
echo $part
done
I have a text file with some paths in it
/home/ubuntu
/home/ubuntu/docs
/home/ariel/code
I want to use the output from find_path step in another list_path step. There is some other code I didn't include as it's irrelevant to my question. So I defined the paths output in find_path step and it is basically a space-separated string /home/ubuntu /home/ubuntu/docs /home/ariel/code and that's format I want to have.
But I don't know how to use outputs from one step as input value in another step.
Basically,
var_paths=/home/ubuntu /home/ubuntu/docs /home/ariel/code
But when I loop var_paths I get weird errors like no such file or directory.
You're missing the quotes when assigning the output from the step to the variable:
name: Demo
on:
workflow_dispatch:
jobs:
build:
runs-on: [ ubuntu-latest ]
steps:
- name: Code Checkout
uses: actions/checkout#v3
- name: Find Paths
id: find_path
run: |
all_paths=$(cat document.txt)
# some code
echo "::set-output name=paths::$(echo ${all_paths})"
- name: List
id: list_path
run: |
# add quotes here
var_paths="${{ steps.find_path.outputs.paths }}"
for part in ${var_paths[#]}; do
# parent_dir=$(cat...)
# ....
# some code
echo $part
done
Misc comments:
You don't need to declare the outputs on the job level unless the output from a step should also be the output from the job. In your case, you're only using the output between steps.
The checkout action is available in v3

Use dynamic input value for Environment in GitHub Actions workflow job

I'm trying to make a GitHub Actions workflow where one job has a dynamic value to its environment setting. https://docs.github.com/en/actions/reference/environments I have two jobs in this workflow. The first job determines which environment the second job will run in, and this is in turn based on which git branch the Actions job is run from.
This is my naive attempt to make it work, but I get an error which says
(Line: 29, Col: 18): Unrecognized named-value: 'needs'. Located at position 1 within expression: needs.get-environment.outputs.environment_name
name: Environments
on:
push:
workflow_dispatch:
jobs:
get-environment:
runs-on: ubuntu-latest
outputs:
environment_name: ${{ steps.get_environment.outputs.environment_name }}
steps:
- id: get_environment
run: |
if [ "$GITHUB_REF" = "refs/heads/test" ]
then
echo "::set-output name=environment_name::test"
elif [ "$GITHUB_REF" = "refs/heads/qa" ]
then
echo "::set-output name=environment_name::qa"
elif [ "$GITHUB_REF" = "refs/heads/master" ]
then
echo "::set-output name=environment_name::production"
fi
use-environment:
runs-on: ubuntu-latest
needs: [get-environment]
environment: ${{ needs.get-environment.outputs.environment_name }}
steps:
- uses: actions/checkout#v2
- name: Run a one-line script
run: echo ${{ secrets.ENV_DEPENDENT_SECRET }}
Is it possible to achieve what I'm trying to do? My end goal is to have a single workflow file for three different app environments (test, QA and prod), where each app environment uses a separate Actions environment. (terminology gets confusing, I know)
I actually had to solve this issue for the place I work. You can use a matrix with the list of your env names and dynamically set the environment name. Take a look at the link for the workflow file.
Have you tried
> use-environment:
> runs-on: ubuntu-latest
> needs: [get-environment]
> environment:
> name: ${{ needs.get-environment.outputs.environment_name }}

GitHub Action - Define Workflow Level Environment Variable Between Jobs

I'd like to define and set environment variable between jobs inside my Github Actions Workflow.
The workflow below is what I've tried but unfortunately the environment variable GIT_PR_SHA_SHORT and E2E_GIT_PR_SHA not working.
Is it possible?
name: Git Pull Request Workflow
on:
workflow_dispatch:
pull_request:
branches:
- master
env:
GIT_PR_SHA: ${{github.event.pull_request.head.sha}}
GIT_PR_SHA_SHORT: "${{ env.GIT_PR_SHA:0:10 }}"
ENV_NAME: test
E2E_GIT_PR_SHA: "${{ env.ENV_NAME }}-${{ env.GIT_PR_SHA_SHORT }}"
jobs:
first-job:
name: Build Docker Image
runs-on: ubuntu-latest
steps:
- name: First Echo Step
run: |
echo "GIT_PR_SHA_SHORT = ${GIT_PR_SHA_SHORT}"
echo "E2E_GIT_PR_SHA = ${E2E_GIT_PR_SHA}"
second-job:
name: Build Docker Image
runs-on: ubuntu-latest
steps:
- name: Second Echo Step
run: |
echo "GIT_PR_SHA_SHORT = ${GIT_PR_SHA_SHORT}"
echo "E2E_GIT_PR_SHA = ${E2E_GIT_PR_SHA}"
You reference a workflow's environment variables with ${{ env.VARIABLE_NAME }} not ${VARIABLE_NAME}. The latter is bash syntax, but these are not shell environment variables, they're workflow environment variables. They're part of the workflow execution, not part of the shell's context.
To reference a workflow environment variable:
name: Git Pull Request Workflow
on:
workflow_dispatch:
pull_request:
branches:
- master
env:
one: 1
two: zwei
three: tres
jobs:
first-job:
runs-on: ubuntu-latest
steps:
- run: |
echo "${{ env.one }}"
echo "${{ env.two }}"
echo "${{ env.three }}"
(I like to use lower-case for my workflow environment variables, and UPPER_CASE for my shell environment variables, so that it's more obvious to me which is which.)
Similarly, this won't work:
env:
GIT_PR_SHA_SHORT: "${{ env.GIT_PR_SHA:0:10 }}"
This is mixing bash syntax :0:10 with the workflow syntax, but the workflow variables are not run through any shell. No virtual machine has been started when the workflow file is parsed, so there's no shell to run things though.
If you wanted to use bash expressions to manipulate the environment, you would need to create a step that runs bash to do that, and you would need to use the ::set-env or ::set-output syntax.
Then you can refer to a step's output using the ${{ steps... }} context.
Unfortunately, passing things between different jobs is trickier, since they run on different virtual machines. You'll need to set variables on the overall workflow itself. You'll need to first ::set-output so that it's visible to the job, then you can raise the visibility from the job to the workflow.
name: Demonstration
on:
push:
branches: [master]
jobs:
first-job:
runs-on: ubuntu-latest
steps:
- id: identify
run: |
# use bash variable expression to get the substring
export GIT_PR_SHA="${{ github.sha }}"
export GIT_PR_SHA_SHORT="${GIT_PR_SHA:0:10}"
echo "::set-output name=git_pr_sha::${GIT_PR_SHA}"
echo "::set-output name=git_pr_sha_short::${GIT_PR_SHA_SHORT}"
outputs:
git_pr_sha: ${{ steps.identify.outputs.git_pr_sha }}
git_pr_sha_short: ${{ steps.identify.outputs.git_pr_sha_short }}
second-job:
needs: first-job
runs-on: ubuntu-latest
steps:
- run: |
echo "${{ needs.first-job.outputs.git_pr_sha }}"
echo "${{ needs.first-job.outputs.git_pr_sha_short }}"
I'd like to add an extension to this since I've had similar difficulties finding how to compute & set environment variables for multi-step use.
Below is a basic example of how to push back to the github environment from within a step if processing is needed to compute an environment variable for later use. You can also update existing variables this same way, not just create new.
name: minimal variable example
on:
push:
env:
MAJOR: "1"
MINOR: "0"
PATCH: "1"
jobs:
vars-example:
runs-on: ubuntu-latest
steps:
- name: only available local variable
run: LOCAL_VERSION=${MAJOR}.${MINOR}.${PATCH}
- name: available across multiple steps
run: echo "GLOBAL_VERSION=${MAJOR}.${MINOR}.${PATCH}" >> $GITHUB_ENV
- name: Vars
run: |
echo LOCAL_VERSION = $LOCAL_VERSION
echo GLOBAL_VERSION = $GLOBAL_VERSION
which results in Vars output of
echo LOCAL_VERSION = $LOCAL_VERSION
echo GLOBAL_VERSION = $GLOBAL_VERSION
shell: /usr/bin/bash -e {0}
env:
MAJOR: 1
MINOR: 0
PATCH: 1
GLOBAL_VERSION: 1.0.1
LOCAL_VERSION =
GLOBAL_VERSION = 1.0.1
You can't use env in an expression under the env element. I don't see another way than using duplicate values instead of an expression.
The env context syntax allows you to use the value of an environment variable in your workflow file. You can use the env context in the value of any key in a step except for the id and uses keys. For more information on the step syntax, see "Workflow syntax for GitHub Actions".
https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#env-context
The following is the newer way of sharing the variables across jobs after the deprication
Have also covered the scenario when the value itself is a variable and needs to be computed at runtime.
The following would be invoked when a push is made master branch
name: Sharing envs across jobs
on:
push:
branches: ['master']
env:
one: onevalue
two: twovalue
three: threevalue
jobs:
job0:
runs-on: ubuntu-latest
steps:
- run: |
echo "${{ env.one }}"
echo "${{ env.two }}"
echo "${{ env.three }}"
job1:
runs-on: ubuntu-latest
# Map a step output to a job output
outputs:
output1: ${{ steps.step1.outputs.test }}
output2: ${{ steps.step2.outputs.test }}
steps:
- id: step1
run: echo "test=$(date +"%d-%m-%Y")-asdfads223" >> $GITHUB_OUTPUT
- id: step2
run: echo "test=world" >> $GITHUB_OUTPUT
job2:
runs-on: ubuntu-latest
needs: job1
steps:
- run: echo ${{needs.job1.outputs.output1}} ${{needs.job1.outputs.output2}}

Use environment variable in github action if

I'm trying to use an environment variable in an if condition in github actions like so:
name: Worfklow
on:
push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v1
- name: EXIT step
if: $GITHUB_REF == 'specific-branch'
run: exit 1
I want to exit if the current branch is equal to a specific branch.
Unfortunately, the github actions console displays an error:
Unexpected symbol: '$GITHUB_REF'
I can use $GITHUB_REF in a run: (where it contains the current branch), but not in an if:. What am I doing wrong?
Though the original problem had been solved without environment vars, I'd like to share how it can be used with if conditions.
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Set env BRANCH
run: echo "BRANCH=$(echo $GITHUB_REF | cut -d'/' -f 3)" >> $GITHUB_ENV
- name: Set env NEED
run: |
if [[ $BRANCH == 'master' && $GITHUB_EVENT_NAME == 'push' ]]; then
echo "NEED=true" >> "$GITHUB_ENV"
else
echo "NEED=false" >> "$GITHUB_ENV"
fi
- name: Skip Deploy?
if: env.NEED != 'true'
run: echo "Only pushing to 'master' causes automatic deployment"
...
The first two steps set 2 env variables, the third step demonstrates what syntax you need to follow to use these vars in if conditions.
do it like this:
if: github.ref == 'specific-branch'
reference branch conditional
If you want to check an environment variable on job-level (refer to Github context), you can do like this:
env:
MY_VAR: Dummy
jobs:
build:
name: Build
runs-on: ubuntu-latest
outputs:
myVar: ${{ steps.init.outputs.myVar }}
steps:
- name: Environment variables to output
id: init
run: |
echo "myVar=${{ env.MY_VAR }}" >> $GITHUB_OUTPUT
And use it in another job:
second_job:
name: Second Job
needs: build
if: needs.build.outputs.myVar == 'Dummy'
You can use some restrictions on the push section of the action
on:
push:
branches:
- '*' # matches every branch that doesn't contain a '/'
- '*/*' # matches every branch containing a single '/'
- '**' # matches every branch
- '!master' # excludes master
This answer was taken from this stack overflow question