using defined environmental variable in with block for github actions - github-actions

I am trying to figure out how to reference a global scoped environmental variable for input in to an action like so:
name: validate
on: pull_request
env:
CONFIG_PATH: configuration/conf.json
jobs:
upload_config:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v1
- name: create config
shell: bash -l {0}
run: |
mkdir `dirname ${CONFIG_PATH}`
echo "some config" > ${CONFIG_PATH}
- name: upload config
uses: actions/upload-artifact#v1
with:
name: config
path: ${{ CONFIG_PATH }}
However I am getting an invalid yaml error stating there is an "Unrecognized named-value: 'CONFIG_PATH'". If I try referencing the environmental variable like so:
path: ${CONFIG_PATH}
I get a "Path does not exist ${CONFIG_PATH}" error.
Any ideas?

I couldn't find a clear example of it in the docs but you need to use the env context for this like so:
path: ${{ env.CONFIG_PATH }}

Related

GitHub Actions - How to use environment variable at job level?

I want to use environment variables at the job level. Is there a way to do it?
env:
stageEnv: UAT
jobs:
name: Upload Build
if: ${{ env.stageEnv == 'UAT' }}
steps:
....
I get unrecognized named-value: 'env' error. Tried $stageEnv and ${{ env.stageEnv }}
Note: It works when I access within 'steps', but would like this to be accessible at 'jobs' level.
I'm afraid not, but you can do like this:
env:
stageEnv: UAT
jobs:
build:
name: Build
runs-on: ubuntu-latest
outputs:
stageEnv: ${{ steps.init.outputs.stageEnv }}
steps:
- name: Make environment variables global
id: init
run: |
echo "stageEnv=${{ env.stageEnv }}" >> $GITHUB_OUTPUT
And use it in another job:
upload:
name: Upload build
needs: build
if: ${{ needs.build.outputs.stageEnv == 'UAT' }}
Note this is just an example, and I personally prefer environment variables uppercase and output variables lowercase

Use an array in workflow level env variable?

You can set env vars available across the entire workflow e.g. like in this post.
(From solution on linked post)
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 have a workflow that uses a matrix strategy and I have to update it in each job if I ever change it. I tried to make it a global variable like above:
name: Model Multipliers
on:
push:
branches:
- main
env:
FRUIT: ["Apple", "Pear", "Banana", "Orange"]
jobs:
ssql-get:
runs-on: ubuntu-latest
strategy:
matrix:
FRUIT: ${{ env.FRUIT }}
name: Get data
steps:
- name: Checkout cum-rev repo
But this gives error:
The workflow is not valid. .github/workflows/main.yml (Line: 12, Col:
9): A sequence was not expected .github/workflows/main.yml (Line: 19,
Col: 15): Unrecognized named-value: 'env'. Located at position 1
within expression: env.FRUIT
Is what I'm trying to do possible by any other means?
If you're using bash, you can create a regular array (like in bash) to use in your steps or inside github expressions -
Example:
env:
MAIN_BRANCHES: ("develop" "main")
Now you can use the array in any step. In the run property, as an environment variable with "${MAIN_BRANCHES}", or inside if conditions with Github expression syntax.
...
- name: Tag build
if: ${{ github.event_name == 'push' && contains(env.MAIN_BRANCHES, steps.calculate_changed_services.outputs.diff_dest) }}
run: echo "my main branches ${MAIN_BRANCHES}"
...
You can find the full Workflow File here - gitversion.yml
if you remove the double quotes in the values it should work

Can I define a global across jobs

I have a workflow with 2 jobs:
on: [push]
jobs:
ssql:
runs-on: ubuntu-latest
### bunch of steps in between ###
- name: Upload data as artifact
uses: actions/upload-artifact#v2
with:
name: ${{ env.GAME }} + "-" + "data"
path: output_data/training-data.csv
env:
GAME: "FunGame"
Rtrain:
runs-on: ubuntu-latest
name: Train model
needs: ssql
steps:
- name: checkout current repo
uses: actions/checkout#v2
- name: Retreive data from ssql job
uses: actions/download-artifact#v2
with:
name: ${{ env.GAME }} + "-" + "data"
env:
GAME: "FunGame"
I had to set env variable $GAME twice, once in each job. Is there any syntax where I can e.g. add this at the top to make it truly global across jobs, e.g. something like:
on: [push]
env:
GAME: "FunGame"
jobs: ...
You can set an env variable exactly as you described at the workflow level.
Just note that it can conflict with env variables set at the job level, or at the step level, if they have the same name. In that case, the variable used is the most specific one: STEP over JOB over WORKFLOW.
Reference 1 + Reference 2
Here is an example of how to use env variables at different levels (without conflict):
name: Environment Workflow
on:
workflow_dispatch:
env:
WORKFLOW_VARIABLE: WORKFLOW
jobs:
job1:
runs-on: ubuntu-latest
env:
JOB_VARIABLE: JOB
steps:
- name: Run Commands with various variables
if: ${{ env.WORKFLOW_VARIABLE == 'WORKFLOW' }}
env:
STEP_VARIABLE: STEP
run: |
echo "Hello World"
echo "This is the $WORKFLOW_VARIABLE environment variable"
echo "This is the $JOB_VARIABLE environment variable"
echo "This is the $STEP_VARIABLE environment variable"
Full workflow implementation (if you want to reproduce)
Previous workflow run display

How to replace string in expression with GitHub actions

This is my action that returns $TOXENV that looks like this py3.6-django2.2 I'd like to $TOXENV to look like this instead py36-django22 is there any substitute/replace function that I could use to replace . char?
name: CI
on:
workflow_dispatch:
branches: [ master, actions ]
jobs:
demo:
runs-on: ubuntu-latest
strategy:
matrix:
python: [3.6, 3.7, 3.8, 3.9]
django: ['2.2', '3.0']
steps:
- uses: actions/checkout#v2
- uses: actions/setup-python#v1
name: Set up Python ${{ matrix.python }} ${{ matrix.django }}
with:
python-version: ${{ matrix.python }}
- name: python version
env:
TOXENV: "py${{ matrix.python }}-django${{ matrix.django }}"
run:
echo $TOXENV
Another way by using BASH native variable substitution:
- name: python version
env:
TOXENV: "py${{ matrix.python }}-django${{ matrix.django }}"
run: |
TOXENV=${{ env.TOXENV }}
TOXENV=${TOXENV//.} # replace all dots
echo TOXENV=${TOXENV} >> $GITHUB_ENV # update GitHub ENV vars
- name: print env
run: echo ${{ env.TOXENV }}
The idea is to read the GitHub actions expression variable into a BASH variable and do the string manipulation then export or set-output to update in GitHub actions runtime.
I don't think there's an easy way to do this in the env directive of your step when defining the value of TOXENV. The env directive accepts expressions, but the functions that can be used in expressions are limited, with nothing that can replace arbitrary characters. The closest I could find is format(), but that unfortunately requires numbered braces in the target string, which won't work for your situation.
Instead, perhaps you could set the value of TOXENV in the run directive using sed, then add it to the environment:
- name: python version
run:
RAW_TOXENV="py${{ matrix.python }}-django${{ matrix.django }}"
TOXENV=$(echo $RAW_TOXENV | sed 's/\.//')
echo "TOXENV=$TOXENV" >> $GITHUB_ENV

Options to have variables in GitHub Actions

I know that I can use Runner's Linux environment variables in GitHub Actions.
Do I have any other options to have variables and use them in workflow steps?
This is how variables are designed to work in GitHub Actions. I mean declared variables are mapped to env variables, like here:
name: Show env
on:
push:
branches:
- '*'
env:
somevar: 'lastvar'
jobs:
show:
runs-on: ubuntu-latest
steps:
- name: Is variable exported?
run: |
echo "${{ env.somevar }}"
However, you can't use them everywhere - please check this topic:
env:
pluginId: 'plugin-fn-xml-node'
on:
push:
paths:
- ${{env.pluginId}}/**
- .github/workflows/**
pull_request:
paths:
- ${{env.pluginId}}/**
- '.github/workflows/**'
jobs:
build:
env:
working-directory: ${{env.pluginId}}
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [8.x, 10.x, 12.x]
steps:
This will not work because you can't use workflow variable at job level.
So if you define variable at workflow level you should be able to use it across steps.
I added also dynamically set variable based on documentation
env:
somevar: 'lastvar'
jobs:
show:
runs-on: ubuntu-latest
steps:
- name: Is variable exported?
run: |
echo "${{ env.somevar }}"
echo "action_state=yellow" >> $GITHUB_ENV
- name: PowerShell script
# You may pin to the exact commit or the version.
# uses: Amadevus/pwsh-script#25a636480c7bc678a60bbf4e3e5ac03aca6cf2cd
uses: Amadevus/pwsh-script#v2.0.0
continue-on-error: true
with:
# PowerShell script to execute in Actions-hydrated context
script: |
Write-Host $env:somevar
Write-Host $env:action_state
- name: Read exported variable
run: |
echo "$action_state"
echo "${{ env.action_state }}"