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?
Related
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.
I'm trying to get this github action to work but once committed it gives me this error:
Invalid workflow file: .github/workflows/main.yml#L1
No steps defined in steps and no workflow called in uses for the following jobs: build
Anyone have any idea what this might depend on?
Below is the code I used:
name: Deploy to Cloud Foundry
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-18.04
# Build your app here
deploy:
runs-on: ubuntu-18.04
needs: build
steps:
- uses: citizen-of-planet-earth/cf-cli-action#master
with:
cf_api: https://api.my-cloud-foundry.com
cf_username: ${{ secrets.CF_USER }}
cf_password: ${{ secrets.CF_PASSWORD }}
cf_org: AwesomeApp
cf_space: Development
command: push -f manifest-dev.yml
Thanks in advance to everyone
Following the Workflow Syntax for Github Actions, you'll identify that some fields are mandatory.
At the workflow level, you need to have at least a trigger (configure with the on field) and a list of jobs specified.
Then, in that list of jobs, you have to specify at least one job, where each of those jobs needs at least the runner and the steps (or the uses for reusable workflow) field configured.
Example of the minimum configurations you would use for a job:
on: push
jobs:
job1:
runs-on: ubuntu-latest
steps:
- name: Print a greeting
run: echo 'Hello World'
job2: # reusable workflow scenario
uses: owner/repo/.github/workflows/reusable-workflow.yml#main
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
I want to learn how to use a self-hosted github runner with labels. I installed a self-hosted github runner on a server and assigned it the label prj1. I then made a github project and included this .github/workflows/deploy.yml file.
name: Environment
on:
push:
branches:
- master
jobs:
p1:
runs-on: self-hosted
steps:
- run: echo "The job was automatically triggered by a ${{ github.event_name }} event." >> deploy-log.txt
When I push to master branch, my self-hosted github runner says SUCCESS. This is perfect so far.
Then I changed my .github/workflows/deploy.yml to include a label like this:
name: Environment
on:
push:
types: [prj1]
branches:
- master
jobs:
p1:
runs-on: self-hosted
steps:
- run: echo "The job was automatically triggered by a ${{ github.event_name }} event." >> deploy-log.txt
Then I pushed to master. But the github runner does not show any indication it detected anything. The github website actions says "This check was skipped". So then I tried this:
name: Environment
on:
push:
branches:
- master
jobs:
p1:
if: ${{ github.event.label.name == 'prj1' }}
runs-on: self-hosted
steps:
- run: echo "The job was automatically triggered by a ${{ github.event_name }} event." >> deploy-log.txt
Again, when i push changes to master, the git hub runner does not show any indication it detected anything. The github website actions says "This check was skipped".
How do I get my self-hosted runner to deploy a project only on jobs with label prj1?
FOund the answer on : https://docs.github.com/en/actions/hosting-your-own-runners/using-self-hosted-runners-in-a-workflow#using-custom-labels-to-route-jobs
Basically I can use the runs-on to specify which label. SO my yml file looks liek this now
name: Environment
on:
push:
branches:
- master
jobs:
p1:
runs-on: prj1
steps:
- run: echo "The job was automatically triggered by a ${{ github.event_name }} event." >> deploy-log.txt
This means on self-hosted github runners tagged with prj1 will run the job.
I need help figuring something, I am trying to trigger 2 different workflows based on 2 different release tags. I want prod-* to trigger the production workflow and dev-* for the development workflow.
The problem is both tags trigger both workflows and I have no idea how to fix this
(I've canceled both actions but they triggered as you can see)
The tags element is not valid for release events. In consequence, the workflow is triggered for every release event of type published no matter the tag. There is no direct filter for tags with the release event as there is for push and pull_request events.
So you can leverage the if conditional on jobs in combination with the github.ref in the context which contains the tag of the release.
name: Deploy
on:
release:
types: [published]
jobs:
deploy-dev:
name: Deploy to development
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/dev-')
steps:
# [...]
deploy-prod:
name: Deploy to production
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/prod-')
steps:
# [...]
The published trigger is used in both cases here (independently of the tag), because your workflow will start for published OR tags (with the informed pattern) events.
To perform an operation only for a specific tag, you would have to extract the tag version from the $GITHUB_REF (env-var), for example using a step as below with an output in a first job:
- name: Get the version
id: get_tag_version
run: echo ::set-output name=version::${GITHUB_REF/refs\/tags\//}
And then use an if condition on 2 others jobs to check if the tag version contains prod- or dev- (needing the first job) to perform the operation you want for each scenario.
Here is an complete example of what could be used:
name: Example
on:
release:
types: [published]
jobs:
job1:
runs-on: ubuntu-latest
outputs:
tag_version: ${{ steps.get_tag_version.outputs.version }}
steps:
- name: Get the version
id: get_tag_version
run: echo ::set-output name=version::${GITHUB_REF/refs\/tags\//}
job2: # will be executed on for dev- tag
runs-on: ubuntu-latest
needs: [job1]
if: contains( needs.job1.outputs.tag_version , 'dev-')
steps:
[...]
job3: # will be executed on for prod- tag
runs-on: ubuntu-latest
needs: [job1]
if: contains( needs.job1.outputs.tag_version , 'prod-')
steps:
[...]
I coded a workflow to test the implementation above and it worked as expected creating a prod-2 release tag:
workflow file implementation
workflow run
EDIT: Note that you could also use a startWith instead of a contains function for the if expression.