I have got two workflows:
workflow1.yaml
workflow2.yaml
I need in workflow2.yaml add something like:
jobs:
build_kotlin:
runs-on: [server1, server2, server3]
needs: [workflow1]
steps:
- name: Checkout code
uses: actions/checkout#v2
Currently "needs" doesn't work properly. How can reference separate workflow yaml file?
needs is only used to establish relationships between jobs -- not entire workflows.
If you want to run "workflow2.yaml" after "workflow1.yaml" has been completed, then add a trigger like so:
on:
workflow_run:
workflows: [workflow1]
types:
- completed
jobs:
build_kotlin
# ...
Read more on Events That Trigger Workflows
Alternatively, you could make workflow1 a reusable workflow and then make sure it is executed before workflow2 like so:
jobs:
workflow1:
uses: octo-org/example-repo/.github/workflows/workflow1.yaml#main
build_kotlin:
runs-on: [server1, server2, server3]
needs: [workflow1]
steps:
- name: Checkout code
uses: actions/checkout#v2
Related
I have below structure:
.github
└── workflows
└── main.yml
└── send_alerts.yml
Now in main, I am using
jobs:
main:
steps:
- name: Git Checkout
uses: actions/checkout#v3
- name: some job
run: |
......
send_alerts:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v3
- uses: ./.github/workflows/send_alerts.yml#feature/workflow1
with:
provision_status: "Success"
in my send_alerts.yml
name: Creating and Sending Alerts/Status
on:
workflow_call:
provision_status:
required: true
type: string
jobs:
create_send_alerts:
runs-on: ubuntu-latest
steps:
- name: Git Checkout
uses: actions/checkout#v3
- name: Some other jobs
run: |
.....
so this thorws me error:
Can't find 'action.yml', 'action.yaml' or 'Dockerfile' under '/home/runner/work/git-repo/.github/workflows/send_alerts.yml#feature/workflow1'. Did you forget to run actions/checkout before running your local action?
So my question is why it is complaining about action in send_alerts for main? while in the main.yml same actions/checkout#v3 works just fine?
I tried both actions/checkout#v2 and v3 in all cases I have same error
There are at least three things wrong:
You're calling a reusable workflow like an action. The call to a reusable workflow replaces the entire job, not just one step.
When you reference a workflow (or an action) that's in the same repository, with a relative path, you must not add an #version suffix. If you look at the error message, the runner is interpreting that as a directory name.
Both together result in something like this:
send_alerts:
uses: ./.github/workflows/send_alerts.yml
with:
provision_status: "Success"
You have to declare the parameter in an inputs object in the reusable workflow:
on:
workflow_call:
inputs:
provision_status:
required: true
type: string
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 one workflow (that I want to be triggered by any commit with no path filter)
name: workflow1
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
...
that triggers another workflow
name: workflow2
on:
workflow_run:
workflows: ["workflow1"]
types:
- completed
jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
...
which is working fine with the workflow_run event. Now is it possible somehow to restrict workflow2 from being triggered even further (like with a path filter)? E.g. I make a commit to folder folder1 -> workflow1 triggered -> workflow2 triggered and if it's not a commit to the folder folder1, e.g. folder2 -> workflow1 triggered -> workflow2 not triggered. Is there something like the following I can add to workflow2?
name: workflow2
on:
paths:
- 'folder1/**'
workflow_run:
workflows: ["workflow1"]
types:
- completed
jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
...
Or another way to achieve that?
Thanks in advance for any help.
First option: Did you consider using the action verify-changed-files in your workflow run to execute the jobs only if specific files are updated?
Second option: It's more verbose, but you could save the path from the first workflow in an artifact to download in the second workflow.
Using the variable GITHUB_EVENT_PATH that returns the path of the file with the complete webhook event payload. For example, /github/workflow/event.json
It would look like this
In the FIRST workflow, you extract the path, then you save that number into a file and upload it as an artifact.
- name: Save the PATH in an artifact
shell: bash
env:
- PATH: {{ github.event.path}} ## If it's not specific enough, you can extract the $PATH variable on a previous step using the shell.
run: echo $PATH > path.txt
- name: Upload the PATH
uses: actions/upload-artifact#v2
with:
name: path
path: ./path.txt
In the SECOND workflow, you get the artifact and the path from the FIRST workflow, using the following GitHub Apps:
- name: Download workflow artifact
uses: dawidd6/action-download-artifact#v2.11.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
workflow: <first_workflow_name>.yml
run_id: ${{ github.event.workflow_run.id }}
- name: Read the path.txt file
id: path_reader
uses: juliangruber/read-file-action#v1.0.0
with:
path: ./path/path.txt
- name: Step to check the path output from the step above with an if condition to perform an operation (or not)
[...]
This link can also help to understand how to extract the PATH depending on the event.
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.
I have two workflows: CI (for continuous integration) and CD (for continuous delivery). Both are working fine individually. My goal is to run the CD workflow only when:
A new tag like v1.1.1 is created on the master branch
The CI workflow is finished
To achieve my goal I'm using the workflow_run event. These are the snippets of my workflows files:
ci.yml:
name: CI
on:
push:
tags: v[1-9]+.[0-9]+.[0-9]+
pull_request:
branches: [develop, hotfix*]
cd.yml
name: CD
on:
workflow_run:
workflows: [CI]
branches: [master]
types:
- completed
The current behavior is: when a tag is created in the master branch only the CI workflow run. I've tried putting tags: v[1-9]+.[0-9]+.[0-9]+ in the workflow_run but the behavior is the same.
My question is: how can I achieve my goal? Is it possible?
According to docs you can only use branches option and not tags for workflow_run so I'm afraid that's why your current setting doesn't work.
You have some alternatives though:
You can turn your CD workflow into action and run it as part of your CI with condition:
.github/actiond/cd/action.yml:
name: CD
description: Run CD
runs:
using: composite
steps:
- run: echo "Success!"
shell: bash
CI:
name: CI
on:
push:
tags: v[1-9]+.[0-9]+.[0-9]+
pull_request:
branches: [develop, hotfix*]
jobs:
sucess:
name: Log success
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- run: echo "Success!"
- name: Run CD
if: github.event_name == 'push' && contains(github.event.ref, '/tags/')
uses: ./.github/actions/cd
Have it as a separate job that is dependant on CI job using needs option
Converting it to action makes for better encapsulation IMO although requires some work.
You need to put "" around the name of the triggering workflow in cd.yml:
name: CD
on:
workflow_run:
workflows: ["CI"]