An action that creates a workflow dispatch event and returns the run-id of started workflow. This action can also be used to wait on completion of the triggered workflow.
In contrast to other existing dispatch-actions, this action provides a way to reliably identify the workflow run (see With marker step).
To provide most flexibility, the action supports three different modes.
Thereby the mode is controlled by the two input parameters workflow-name
and run-id
.
-
'Trigger' mode:
In this mode the action triggers the workflow and just tries to receive the workflow run id. This can be used if you want to get the run id and wait for it in another step/job later on. This mode will be enabled if theworkflow-name
input is present. -
'Wait' mode:
In this mode the action waits until a workflow run finishes. This can be used in combination with 1. mode or if you get the run id from somewhere else. The mode will be enabled ifrun-id
is given. In this case the run-id is expected to be valid otherwise it results in error. -
'Trigger and wait' mode:
This is a combination of 1. and 2. mode. To enable it, specify theworkflow-name
andrun-id
inputs. In this case, therun-id
isn’t required to be valid because it gets replaced by the one detected in the trigger step.
In addition to the examples shown here, you can also take a look at the .github/workflows/ folder. There we have a few workflows for test purposes that might inspire you.
The following examples show the minimum setup without using a marker step. This mode is handy if you know that there will be only on workflow run at a time.
#...
- name: "Start and wait for a workflow"
id: startAndWaitWorkflow
uses: mathze/[email protected]
with:
workflow-name: my-workflow.yml
token: ${{ secrets.MY_PAT }}
run-id: dummy
#...
- name: "Reuse workflow run id"
run: "echo ${{ steps.startAndWaitWorkflow.outputs.run-id }}
#...
- name: "Start a workflow"
id: startWorkflow
uses: mathze/[email protected]
with:
workflow-name: my-workflow.yml
token: ${{ secrets.MY_PAT }}
#...
- name: "wait to complete"
uses: mathze/[email protected]
with:
token: ${{ secrets.MY_PAT }}
run-id: ${{ steps.startWorkflow.outputs.run-id }}
💡
|
You also can create a 'fire & forget' workflow by simply omitting the 'wait-to-complete' step. |
#...
- name: "Start workflow"
id: startWorkflow
uses: mathze/[email protected]
with:
workflow-name: workflow-with-marker.yml
token: ${{ secrets.MY_PAT }}
use-marker-step: true
#...
- name: "wait to complete"
uses: mathze/[email protected]
with:
token: ${{ secrets.MY_PAT }}
run-id: ${{ steps.startWorkflow.outputs.run-id }}
on:
workflow-dispatch:
inputs:
external_ref_id: #(1)
description: Id to use for unique run detection
required: false
type: string
default: ""
jobs:
beforeAll:
runs-on: ubuntu-latest
steps:
- name: ${{ github.event.inputs.external_ref_id }} #(2)
run: echo
-
The target workflow has to define the
external_ref_id
input -
Here we define a step with the name of the passed input.
In this section we show how to configure the payload
input of this action in two scenarios, with and without marker-step.
|
Be careful when using secrets within payload! They might get exposed in the target-workflow! |
First, lets assume we have the following (simple) workflow we want to trigger through our action
on:
workflow_dispatch:
inputs:
whom-to-greet:
required: false
description: Whom to greet
default: "World"
type: string
jobs:
greetJob:
runs-on: ubuntu-latest
steps:
- name: Greet
run: |
echo "::notice title=Greet::Hello ${{ github.event.inputs.whom-to-greet }}"
Now, the step in our calling workflow could look like this
#...
- name: "Start say hello"
id: startSayHello
uses: mathze/[email protected]
with:
workflow-name: say-hello.yml
token: ${{ secrets.MY_PAT }}
payload: | #(1)
{
"whom-to-greet": "${{ github.actor }}" #(2)
}
#...
-
We use multiline string (indicated by '|'). This allows us to write the json in a more natural way.
-
We only need the 'inputs' argument names — in this case "whom-to-greet" — and the value that shall be submitted. We also can use github expressions (even for/within the argument’s name).
on:
workflow-dispatch:
inputs:
external_ref_id:
description: Id to use for unique run detection
required: false
type: string
default: ""
whom-to-greet:
required: false
description: Whom to greet
default: "World"
type: string
jobs:
greetJob:
runs-on: ubuntu-latest
steps:
- name: ${{ github.event.inputs.external_ref_id }}
run: echo
- name: Greet
run: |
echo "::notice title=Greet::Hello ${{ github.event.inputs.whom-to-greet }}"
The respective step in our calling workflow could look like this
#...
- name: "Start say hello"
id: startSayHello
uses: mathze/[email protected]
with:
workflow-name: say-hello-with-marker.yml
token: ${{ secrets.MY_PAT }}
use-marker-step: true
payload: | #(1)
{
"whom-to-greet": "${{ github.actor }}" #(2)(3)
}
#...
-
We use multiline string (indicated by '|'). This allows us to write the json in a more natural way.
-
We only need the 'inputs' argument names — in this case "whom-to-greet" — and the value that shall be submitted. We also can use github expressions (even for/within the argument’s name).
-
Note that you do not need to specify the
external_ref_id
input, as it will be added automatically whenuse-marker-step
is enabled.
Input | Description | R equired/O ptional |
Default | ||
---|---|---|---|---|---|
|
Organization or user under which the repository of the workflow resist. |
O |
Current owner |
||
|
Name of the repository the workflow resist in. |
O |
Current repository |
||
|
The token used to work with the API.
|
R |
- |
||
|
Name of the workflow to trigger. E.g. 'my-workflow.yml'. |
|
- |
||
|
The git reference for the workflow. The reference can be a branch or tag name.
|
O |
Default branch of the target repository. |
||
|
Json-String representing any payload/input that shall be sent with the dispatch event.
|
O |
{} |
||
|
Maximum duration(D) of workflow run id retrieval. |
O |
1 minute |
||
|
Duration(D) to wait between consecutive tries to retrieve a workflow run id. |
O |
1 second |
||
|
Indicates if the action shall look for a marker-step to find the appropriate run. |
O |
|
||
|
A workflow run id for which to wait. |
|
- |
||
|
Maximum duration(D) to wait until a workflow run completes. |
O |
10 minutes |
||
|
Duration(D) to wait between consecutive queries on the workflow run status. |
O |
1 second |
||
|
Defines if the action should result in a workflow failure if an error was discovered.
|
O |
|
(D): Duration can be specified in either ISO-8601 Duration format or in specific format e.g. 1m 10s
(details see https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.time/-duration/parse.html)
Output | Type | Description |
---|---|---|
|
Boolean |
Indicates if there was an issue within the action run, and the workflow may not have been triggered correctly or didn’t reach the completed status. To drill down the cause you can check the |
|
String |
The run id of the started workflow. May be empty if no run was found or in case of an error. |
|
String |
The status of the triggered workflow. (Normally always 'completed') |
|
String |
The conclusion of the triggered workflow. |
- Trigger-mode
-
-
Determine workflow id for given workflow-name
-
If
use-marker-step
is enabled, generate a uniqueexternal_ref_id
(<CURRENT_RUN_ID>-<CURRENT_JOB_ID>-<UUID>) -
Trigger dispatch event to target workflow and store the
dispatch-date
(also passexternal_ref_id
in input if enabled) -
Query workflow runs for the given workflow (-id) that are younger than
dispatch-date
and targeting the givenref
The query use the etag to reduce rate-limit impact -
Filter found runs
-
If
use-marker-step
is enabled-
Filter runs that are not 'queued'
-
Get step details for each run
-
Find the step with the name of generated
external_ref_id
-
Take first (if any)
-
-
Else
-
Order runs by date created
-
Take first (if any)
ℹ️All subsequent requests use etag's
-
-
-
Repeat 4 and 5 until a matching workflow run was found or
trigger-timeout
exceeds. Between each round trip we pause fortrigger-interval
units. -
Return the found workflow run id or raise/log error (depending on
failOnError
)
-
- Wait-mode
-
This is quite simple, with the former retrieved workflow-run-id we query the state of the workflow-run until it becomes complete (or
wait-timeout
exceeds). All queries uses etag's