I have a boolean env var TAG_EVENT and I update it in one of the steps to false (I also print it and I see it false) but for some reason, the last step is not executed although TAG_EVENT is false. I appreciate help with that,
on:
workflow_dispatch:
env:
TAG_EVENT: ${{ true }}
jobs:
push_images:
name: Push images
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request' }}
steps:
- id: version
name: Infer version
run: |
version="${GITHUB_REF#refs/tags/v}"
echo $version
if [[ $version == refs/* ]] ;
then
echo 'TAG_EVENT=false' >> $GITHUB_ENV
branch="${GITHUB_REF#refs/heads/}"
version=$branch
fi
echo ::set-output name=version::$version
- name: Publish latest image tag for release
if: github.event_name != 'pull_request' && TAG_EVENT == false
run: |
echo "printme!!!"
As you make use of a text-based shell like bash, you will have to deal with strings. Therefore you wont be able to do a check for false, but need to do it for 'false'. But I would suggest marshaling the boolean by using GitHub's built-in toJSON and fromJSON functions:
...
steps:
- name: I produce a boolean output
id: output_producer
shell: bash
run: |
if [[ $RANDOM > 100 ]]; then i=true; else i=false; fi
echo "::set-output name=boolean_output::${{ toJSON($i) }}"
echo "::set-output name=integer_output::${{ toJSON($i) }}"
- name: I run conditionally on that boolean
if: fromJSON(steps.output_producer.outputs.boolean_output)
shell: bash
run: |
echo "Ran successfully!"
- name: I run always
if: always()
shell: bash
run: |
echo ${{ fromJSON(steps.output_producer.outputs.integer_output) }}
There is some inconsistency between the input context and the way booleans are treated in GitHub Actions. I have a short write-up on this. Hope you find this helpful
GitHub Actions: Passing Boolean input variables to reusable workflow_call
Try to use in second if-statement ${{ env.TAG_EVENT == false }}
Related
My current github workflow as quite repeating code to allow a conditionnement in what and where releases should be pushed depending on the event type :
name: Build LaTeX document & latexdiff to previous tagged version.
on:
push:
branches: [master]
pull_request:
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Build stuff
...
...
- name: Upload results (master latest)
uses: "marvinpinto/action-automatic-releases#latest"
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: "latest"
prerelease: true
draft: true
title: "Build"
files: |
result
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
- name: Upload results (pull request)
uses: "marvinpinto/action-automatic-releases#latest"
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: github.ref_name
prerelease: true
draft: true
title: "Build"
files: |
result
if: ${{ github.event_name == 'pull_request' }}
- name: Upload results (tag)
uses: "marvinpinto/action-automatic-releases#latest"
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: github.ref_name
prerelease: false
draft: false
title: "Build"
files: |
result
if: ${{ github.ref_type == 'tag' }}
Is there a way to conditontionally set values so that i dont have to repeat 3 times the same thing ? Basically i want to deal with the three different cases :
Some commit lands on master, I releas it with the latest tag.
Some tag lands on master, I release it with its propper tag.
PRs are released under their names.
Not that it changes anything, but it really looks ugly to me.
You could set the params as an output of a step and then use them in the upload step:
name: Build LaTeX document & latexdiff to previous tagged version.
on:
push:
branches: [master]
pull_request:
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Build stuff
...
- name: Set params
id: params
run: |
if [[ "${{ github.event_name }}" -eq "push" && "${{ github.ref }}" -eq "refs/heads/master" ]]; then
echo "tag=latest" >> $GITHUB_OUTPUT
echo "prerelease=true" >> $GITHUB_OUTPUT
echo "draft=true" >> $GITHUB_OUTPUT
elif [[ "${{ github.event_name }}" -eq "pull_request" ]]; then
echo "tag=${{ github.ref_name }}" >> $GITHUB_OUTPUT
echo "prerelease=true" >> $GITHUB_OUTPUT
echo "draft=true" >> $GITHUB_OUTPUT
elif [[ "${{ github.ref_type }}" -eq "tag" ]]; then
echo "tag=${{ github.ref_name }}" >> $GITHUB_OUTPUT
echo "prerelease=false" >> $GITHUB_OUTPUT
echo "draft=false" >> $GITHUB_OUTPUT
fi
- name: Upload results
uses: "marvinpinto/action-automatic-releases#latest"
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: ${{ steps.params.outputs.tag }}
prerelease: ${{ steps.params.outputs.prerelease }}
draft: ${{ steps.params.outputs.draft }}
title: "Build"
files: |
result
Is it better then having 3 types of the step? I don't know. I have my doubts.
Notes:
There is no default. In case it's possible that there is an additional GitHub event that doesn't match these cases, then either set it in the additional else Bash condition or introduce an if condition to the upload step to make sure that it runs only in one of the three scenarios.
I haven't tested the code and there might be some bug. However, I believe you understand the idea of setting the params.
I need to generate environment variable from ${{ github.event.head_commit.message }}, ${{ github.sha }} and here is what I tried so far
- name: Setup env var
run: |
echo MESSAGE_SHA=${{ github.event.head_commit.message }}-${{ github.sha }}) >> $GITHUB_ENV #only the dash and the SHA is print out
echo ${{ env.MESSAGE_SHA }} #Nothing prints out
The concatenation for the commit message and commit SHA with the dash is not working at all. How can I solve this issue?
I made it work here using this workflow implementation.
For what I observed, there are 2 issues in your implementation:
First issue
According to the documentation, when setting an environment variable, you can't access the variable in the same step.
You can make an environment variable available to any subsequent steps in a workflow job by defining or updating the environment variable and writing this to the GITHUB_ENV environment file. The step that creates or updates the environment variable does not have access to the new value, but all subsequent steps in a job will have access. The names of environment variables are case-sensitive, and you can include punctuation. For more information, see "Environment variables."
Therefore, your implementation should instead looks like this:
- name: Setup env var
run: |
echo MESSAGE_SHA='${{ github.event.head_commit.message }}'-'${{ github.sha }}' >> $GITHUB_ENV
- name: Check env var
run: |
echo ${{ env.MESSAGE_SHA }}
However, that wouldn't be enough depending the context, due to the second point.
Second issue
The ${{ github.event.head_commit.message }} variable can be a multiline variable, in that case, you would need to create the variable with another syntax before adding it to the $GITHUB_ENV.
The solution I came with was using this implementation:
- name: Setup env var
run: |
MESSAGE=$(cat << EOF
'${{ github.event.head_commit.message }}'
-'${{ github.sha }}'
EOF
)
echo MESSAGE_SHA=$MESSAGE >> $GITHUB_ENV
Therefore, combining both concepts above, your workflow implementation should look like this to achieve what you want:
- name: Setup env var
run: |
MESSAGE=$(cat << EOF
'${{ github.event.head_commit.message }}'
-'${{ github.sha }}'
EOF
)
echo MESSAGE_SHA=$MESSAGE >> $GITHUB_ENV
- name: Check env var
run: |
echo ${{ env.MESSAGE_SHA }}
Note that using echo MESSAGE_SHA='${{ github.event.head_commit.message }}'-'${{ github.sha }}' >> $GITHUB_ENV could work if you can always guaranty the commit message is a single line.
EDIT:
This syntax also works to set multilines outputs (and looks easier to use):
run: |
echo "TEST=first line \
second line \
third line" >> $GITHUB_OUTPUT
How can i set output variables when using shell: cmd on Windows? My repo is hosted at Github (not Gitlab).
The following is based on this accepted answer
jobs:
job1:
runs-on: my-windows-machine
# Map a step output to a job output
outputs:
output1: ${{ steps.step1.outputs.test }}
output2: ${{ steps.step2.outputs.test }}
steps:
- id: step1
run: |
echo '::echo::on'
echo "::set-output name=test::hello"
shell: cmd
- id: step2
run: |
echo '::echo::on'
echo "::set-output name=test::world"
shell: cmd
job2:
runs-on: my-windows-machine
needs: job1
steps:
- run: echo ok: ${{needs.job1.outputs.output1}} ${{needs.job1.outputs.output2}}
shell: cmd
The echo stmt in job2 only shows ok: string if shell: cmd is used in the steps in job1.
As the OP Andrew concludes in the comments, output vars just is not supported with cmd.exe.
I went ahead and broke up the steps in my workflow to use shell: cmd for the things that need to be processed by cmd.exe and created a separate step (using the default shell) just to set the output vars.
As an alternative, you can see in "Github Actions, how to share a calculated value between job steps?" the $GITHUB_OUTPUT command, which can be used to define outputs for steps. The outputs can then be used in later steps and evaluated in with and env input sections.
You can see it used in "How can I use a GitHub action's output in a workflow?".
Note: the older ::set-output command has now (Oct. 2022) been deprecated.
name: 'Hello World'
runs:
using: "composite"
steps:
- id: random-number-generator
run: echo "name=random-id::$(echo $RANDOM)" >> $GITHUB_OUTPUT
shell: bash
...
jobs:
test-job:
runs-on: self-hosted
steps:
- name: Call Hello World
id: hello-world
uses: actions/hello-world-action#v1
- name: Comment
if: ${{ github.event_name == 'pull_request' }}
uses: actions/github-script#v3
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
github.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: 'Output - ${{ steps.hello-world.outputs.random-number }}'
})
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.
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