all.
I have this pipeline. Where I just basically want to get changed filed dirs and run helm push command on that dirs.
name: Helm Package and Push
on:
push:
branches:
- chartChange
paths:
- 'charts/**'
jobs:
detect_changes:
runs-on: ubuntu-latest
outputs:
list: ${{ steps.changed-files-specific.outputs.all_changed_files }}
steps:
- name: Checkout
uses: actions/checkout#v2
- name: Get changed files in the docs folder
id: changed-files-specific
uses: tj-actions/changed-files#v35
with:
json: true
files: charts/** # Alternatively using: `docs/**` or `docs`
- name: Run bash script
run: |
for i in ${{ steps.changed-files-specific.outputs.all_changed_files }}; do echo ${i%/*}; done
Test_from_first_job:
needs: detect_changes
runs-on: ubuntu-latest
strategy:
matrix:
folders: ${{fromJson(needs.detect_changes.outputs.list)}}
steps:
- name: Checkout
uses: actions/checkout#v2
- name: Run test step
run: |
echo ${{matrix.folders}}
But however my jobs failing with this error:
Error when evaluating 'strategy' for job 'Test_from_first_job'. .github/workflows/cm-
push.yml (Line: 37, Col: 22): Error parsing fromJson,.github/workflows/cm-push.yml
(Line: 37, Col: 22): Unexpected character encountered while parsing value: \. Path '',
line 1, position 1.,.github/workflows/cm-push.yml (Line: 37, Col: 22): Unexpected type
of value '', expected type: Sequence.
Any ideas how can i make it work ?
REgards
The matrix must be able to expand at the time the template is parsed and it can't rely on any runtime-defined values.
You'll need to rely on a script to trigger another workflow and pass the value in as a parameter. The parameter value IS available at parse time, so that can be used to spin up the matrix.
Or you must loop through the values using a runtime solution, such as a script block and a for-loop.
Related
I just want to print out the github.event context in a GitHub Actions step, so I am doing the following
- name: check context
shell: bash
run: echo ${{ toJSON(github.event) }}
However this fails as follows:
/home/runner/work/_temp/hd73999-5309-44cf-9218-9e2e3805d525.sh: line 2: after:: command not found
Error: Process completed with exit code 127.
(although the github.event DOES get printed before the error.
Why is that?
I am using the toJSON function because if I don't all that gets printed is:
Run echo Object
Object
You need to add quotes around the expression so it doesn't evaluate it as JS.
From: https://docs.github.com/en/actions/learn-github-actions/contexts#example-printing-context-information-to-the-log
name: Context testing
on: push
jobs:
dump_contexts_to_log:
runs-on: ubuntu-latest
steps:
- name: Dump GitHub context
id: github_context_step
run: echo '${{ toJSON(github) }}'
I'm trying to parametrize the jobs.myjob.container.image field. The documentation says the needs context is available there:
Contexts documentation
Specifically this:
Workflow key
Context
jobs.<job_id>.container
github, needs, strategy, matrix, env, secrets, inputs
But it doesn't work. My job output is an empty string, causing an error.
get_image:
name: get_image
runs-on: self-hosted
outputs:
image: ${{ steps.jq.image }}
needs:
- ...
steps:
- name: Checkout code
uses: actions/checkout#v3
- name: jq
id: jq
run: |
set -x
export TAG=$(jq -r '.${{ github.event.inputs.cluster }} | .tag' data.json)
echo "::set-output name=image::registry.com/mycontainer:$TAG"
job2:
name: job2
runs-on: self-hosted
needs:
- get_image
container:
image: ${{ needs.get_image.outputs.image }} <--- this is an empty string
credentials:
...
steps:
...
The error I'm getting is Error: The template is not valid. ...: Unexpected value ''.
Is the documentation lying to me or am I just reading it wrong?
Other questions lead me to think that the thing I want to do is not allowed.
parametrize container.image
github community discussion
You should use outputs here image: ${{ steps.jq.outputs.image }}.
I have this GitHub workflow that I need to parameterize on which runners runs. So in the YAML file I tried:
# ...
jobs:
process:
name: Process
runs-on: ${{ secrets.GH_RUNNER_TAG }}
# ...
However, I get this error:
The workflow is not valid. .github/workflows/action.yml (Line: 12, Col: 14): Unrecognized named-value: 'secrets'. Located at position 1 within expression: secrets.GH_RUNNER_TAG
Is the secrets injection not available for this element? Is there some other alternative? The value does not need to be a secret but I need to have it in one place and not edit hundreds of YAML files everytime the runner tag would change...
EDIT1:
I've tried, as GuiFalourd suggested, to create an environment variable at the workflow level which would hold the secret:
env:
RUNNER_LABEL: ${{ secrets.GH_RUNNER_TAG }}
jobs:
analyze:
name: Analyze
runs-on: $RUNNER_LABEL
And it doesn't work. The action gets stuck. I tried using:
$RUNNER_LABEL -> gets stuck
"$RUNNER_LABEL" -> gets stuck, too
${{ env.RUNNER_LABEL }} -> action does not start, outputs error:
The workflow is not valid. .github/workflows/action.yml (Line: 14, Col: 14): Unrecognized named-value: 'env'. Located at position 1 within expression: env.RUNNER_LABEL
Furthermore, I've checked that the env var is properly assigned, by placing a valid, hard-coded value for runs-on and setting first step as:
steps:
- name: Test
run: echo "$RUNNER_LABEL"
which produces "***" - proof that a secret has been output and redacted automatically by GitHub.
This is achievable using Reusable Workflow by configuring the "called" workflow to accept inputs from the caller.
The main pipeline which we can name it as "process" will use a shared codebase/pipeline lets call it "common" which can accept inputs, one of these inputs can be the runs-on value.
For example
# common.yml
name: parameterized job
on:
workflow_call:
inputs:
runner:
required: true
type: string
jobs:
common:
name: Common
runs-on: ${{ inputs.runner }}
steps:
- run: echo "Hello World"
# process.yml
name: process
on:
push:
jobs:
process:
uses: username/repo/.github/workflows/common.yml#branch
with:
runner: machine_with_specific_label # using ${{ env.MY_RUNNER_LABEL }} is possible as well
Building a GitHub action based on the commit message I'm trying to base a step on whether the commit message contains a particular string, set it to a variable and then in the next step check with a condition.
My current implementation of my action works:
name: Smoke Test
on:
push:
branches:
- main
permissions:
contents: read
issues: write
jobs:
smoking:
runs-on: [ubuntu-latest]
steps:
- name: Run smoke tests
if: ${{ !contains(github.event.head_commit.message, 'smoke_test') }}
run: |
echo 'Smoke Test not requested'
exit 1
stuff:
needs: smoking
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- uses: JasonEtco/create-an-issue#v2
env:
GITHUB_TOKEN: ${{ secrets.TOKEN }}
with:
filename: .github/ISSUE_TEMPLATE/smoke-test.md
id: create-issue
- run: 'echo Created issue number ${{ steps.create-issue.outputs.number }}'
- run: 'echo Created ${{ steps.create-issue.outputs.url }}'
but with the implementation of:
exit 1
causes the action to indicate it error'ed out in the action panel and while that works that isn't technically accurate because I don't need it to error I just don't want the remaining steps to run.
I've tried setting a variable:
if: ${{ contains(github.event.head_commit.message, 'smoke_test') }}
with:
run-smoke-test: true
run: |
echo 'Smoke Test requested'
but it's not passing to the next step.
Research
Use environment variable in github action if
How to pass variable between two successive GitHub Actions jobs?
github-action: does the IF have an ELSE?
How to fail a job in GitHub Actions?
GitHub Actions - trigger another action after one action is completed
Without relying on another GitHub action is there a way in step smoking to set an env variable that step stuff would need to validate for before running the step?
Edit
After reading the answer and implementing job outputs I've written:
name: Smoke Test
on:
push:
branches:
- main
permissions:
contents: read
issues: write
jobs:
commitMessage:
runs-on: ubuntu-latest
outputs:
output1: ${{ steps.isSmoke.outputs.test }}
steps:
- id: isSmoke
if: ${{ contains(github.event.head_commit.message, 'smoke_test') }}
run: echo "::set-output name=test::true"
smokeTest:
runs-on: ubuntu-latest
needs: commitMessage
steps:
- uses: actions/checkout#v2
- uses: JasonEtco/create-an-issue#v2
if: steps.isSmoke.output.test == true
env:
GITHUB_TOKEN: ${{ secrets.DEV_TOKEN }}
with:
filename: .github/ISSUE_TEMPLATE/smoke-test.md
but when the commit message of smoke_test is used it bypasses create-an-issue:
and I'm basing my condition after reading "Run github actions step based on output condition" and reading:
Contexts
Expressions
Using conditions to control job execution
Can a condition come before a step and/or what is the correct way to run a step based off the previous step?
You are looking for job outputs, which allow you to send data to the following jobs.
I'm trying to set the environment context for a HitHub Actions workflow dynamically based upon the branch. So if the workflow is being fired by a pull request to develop, then the development environment context would be used, but if the pull request is against main then the main environment context would be used.
At the moment I'm using an IF:
name: Deploy
on:
pull_request:
types: closed
branches:
- develop
- master
workflow_dispatch:
jobs:
deploy-develop:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x]
if: ${{ github.ref == 'refs/heads/develop' }}
environment: develop
It's the last line of the above that I want to make dynamic. I've tried the below:
environment: ${GITHUB_REF#refs/heads/}
and
environment: ${{ GITHUB_REF#refs/heads/ }}
and
environment: ${{github.event.pull_request.base.ref}}
But all the things I've tried result in:
.github/workflows/deploy.yaml#L23
The workflow is not valid. .github/workflows/deploy.yaml (Line: 23, Col: 18): Unexpected symbol: 'GITHUB_REF#refs/heads/'. Located at position 1 within expression: GITHUB_REF#refs/heads/
or
The workflow is not valid. .github/workflows/deploy.yaml (Line: 22, Col: 18): Unrecognized named-value: 'github'. Located at position 1 within expression: github.event.pull_request.base.ref
Any ideas how to set the context dynamically?