Can I define a global across jobs - github-actions

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

Related

Is it possible to access step outputs from another Github actions job?

Given the following sample workflow
name: My workflow
on:
push:
branches:
- 'main'
jobs:
job_1:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout#v3
with:
fetch-depth: 0
- name: Get next version
id: get_next_version
uses: thenativeweb/get-next-version#2.5.0
- name: Echo for new version
if: ${{ steps.get_next_version.outputs.hasNextVersion == 'true' }}
run: echo there is a new version
- name: Echo for no new version
if: ${{ steps.get_next_version.outputs.hasNextVersion != 'true' }}
run: echo there is no new version
job_2:
needs: job_1
if: needs.job_1.steps.get_next_version.outputs.hasNextVersion == 'true'
runs-on: ubuntu-latest
steps:
- name: First step
run: echo job_2 is running
The action get-next-version analyzes my commit and calculates a new version. As you can see in job_1 I can access the calculated result.
job_2 depends on job_1 and should only run if there would be a new version. I tried to access the result in the if statement of job_2 but it seems that didn't work, I might be using the wrong syntax.
I get the echo
there is a new version
but job_2 was skipped. Is there a way to get access to the data of get_next_version.outputs ( I want the fields hasNextVersion and version )?
Yes - it's possible.
Each job can define its output as an output of one of its steps.
The related documentation can be found here
name: My workflow
on:
push:
branches:
- 'main'
jobs:
job_1:
runs-on: ubuntu-latest
# define output for first job forwarding output of hasNextVersionOutput job
outputs:
hasNextVersion: ${{ steps.hasNextVersionOutput.outputs.hasNextVersion }}
steps:
- name: Checkout repository
uses: actions/checkout#v3
with:
fetch-depth: 0
- name: Get next version
id: get_next_version
uses: thenativeweb/get-next-version#2.5.0
# add a step to generate the output that will be read by the job
- name: Generate output
run: echo "hasNextVersion=${{
steps.get_next_version.outputs.hasNextVersion }}" >> $GITHUB_OUTPUT
- name: Echo for new version
if: ${{ steps.get_next_version.outputs.hasNextVersion == 'true' }}
run: echo there is a new version
- name: Echo for no new version
if: ${{ steps.get_next_version.outputs.hasNextVersion != 'true' }}
run: echo there is no new version
job_2:
needs: job_1
# read output directly from job (you cannot access its steps
if: needs.job_1.outputs.hasNextVersion == 'true'
runs-on: ubuntu-latest
steps:
- name: First step
run: echo job_2 is running

Github Actions workflow_dispatch choice not working

So, i have tried different versions of this, but i still cannot get it right.
I have a github actions pipeline where i would like to insert a choice so people don't have to look for it in documentation:
name: Echo message
on:
workflow_dispatch:
inputs:
hubAddressGroupObject:
type: choice
description: 'Enter the name of the hub where the entry is added'
required: true
default: 'AZURE-EUW-XXXXX'
options:
- 'AZURE-EUW-XXXXX'
- 'AZURE-FRC-XXXXX'
- 'AZURE-USE-XXXXX'
- 'AZURE-FRC-XXXXX'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- name: WriteMessage
shell: pwsh
run: |
Test-script.ps1 -message "${{ github.event.inputs.hubAddressGroupObject }}"
The 'Test-script.p1' can look like this:
param (
[string] $message
)
Write-Host ('{0}' -f $message)
The output is still a normal workflow_dispatch with no choice.
What am i doing wrong?
Also, i have merged the current branch into main (default).
your code seems to be correct, you have space issue's with "jobs",
shift-tab it and it should work:
name: Echo message
on:
workflow_dispatch:
inputs:
hubAddressGroupObject:
type: choice
description: 'Enter the name of the hub where the entry is added'
required: true
default: 'AZURE-EUW-XXXXX'
options:
- 'AZURE-EUW-XXXXX'
- 'AZURE-FRC-XXXXX'
- 'AZURE-USE-XXXXX'
- 'AZURE-FRC-XXXXX'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- name: WriteMessage
run: |
echo "${{ github.event.inputs.hubAddressGroupObject }}"

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 }}

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 }}"

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}}