In this topic, you will explore advanced event usage in GitHub Actions through the 'on' directive. By customizing these events, developers can automate processes, orchestrate workflows, and integrate external services.
Configure manual launch for workflows
workflow_dispatch is a triggering mechanism in GitHub Actions that lets you manually initiate a GitHub Action without the need to push changes or create a pull request. The workflow is manually triggered within the same repository. An added advantage is the ability to pass custom parameters during the manual trigger process.
The workflow_dispatch event does not have specific activity types. It serves as a general-purpose event for manually triggering workflows.
To utilize workflow_dispatch, you must include it within the on section of your workflow file.
name: Manual trigger
on:
workflow_dispatch:
inputs:
name:
description: "Whom to greet"
default: "World"
jobs:
hello:
runs-on: ubuntu-latest
steps:
- name: Hello Step
run: echo "Hello ${{ github.event.inputs.name }}" That's all! Now, to manually trigger your GitHub Action, navigate to the Actions tab in your repository and simply click on the "Run workflow" button.
Configure dependencies between workflows
workflow_run is an event in GitHub Actions that allows the completion or status change of one workflow to trigger another workflow within the same repository. It establishes a parent-child relationship between workflows, enabling the execution of subsequent workflows based on the outcome of a triggering workflow.
The workflow_run event has two activity types:
requested: This activity type is triggered when another workflow requests the execution of a workflow using the
workflow_dispatchevent or by using the GitHub API.completed: This activity type is triggered when the requested workflow completes its execution.
in_progress: This activity type is assigned to a workflow run when it is actively running and executing the defined steps and actions. It indicates that the workflow run is currently in progress.
The workflow_run event is utilized in scenarios where you need to orchestrate a series of workflows and create dependencies between them. Some common use cases for workflow_run include:
Sequential execution: Running workflows one after the other, ensuring a specific order of operations.
Conditional workflows: Triggering a workflow only when a specific condition is met in a preceding workflow.
Post-processing: Performing actions in response to the completion or status change of a workflow, such as sending notifications or generating reports.
Let's walk through an example scenario that demonstrates the usage of workflow_run:
Consider a repository with two workflows: build.yml and test.yml. You want to ensure that the test.yml workflow only runs when the build.yml workflow is successful. Here's how to achieve this:
In the build.yml workflow:
name: Build
on:
push:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Hello Step
run: echo "Foo bar" In the test.yml workflow:
name: Test
on:
workflow_run:
workflows: [Build]
types: [completed]
jobs:
on-success:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- name: Print Success Message
run: echo 'The triggering workflow passed'
on-failure:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'failure' }}
steps:
- name: Print Failure Message
run: echo 'The triggering workflow failed'In this example, whenever a workflow with the name "Build" is completed, it triggers the "Test" workflow regardless of the branch. The workflow_run event is configured with the completed activity type.
The workflow consists of two jobs: on-success and on-failure. The on-success job runs only if the triggering workflow's conclusion is set to "success". Inside this job, a step is defined to print a success message using the run command.
Similarly, the on-failure job runs if the triggering workflow's conclusion is set to "failure". It contains a step that prints a failure message using the run command.
Running reusable workflows
workflow_call is a mechanism in GitHub Actions that allows you to invoke and reuse another workflow within the same repository or across repositories. It enables modular workflow design by encapsulating a set of actions and steps as a separate workflow, which can be called from other workflows.
The workflow_call event does not have specific activity types. It serves as a means to invoke and execute reusable workflows.
You should utilize the workflow_call feature in scenarios where you want to create reusable and modular workflows as the feature promotes code organization and reduces duplication. Some common use cases for workflow_call include:
Code reusability: Invoking a shared set of actions and steps across multiple workflows, ensuring consistency and reducing maintenance efforts.
Workflow composition: Composing complex workflows by invoking smaller, modular workflows, resulting in more manageable and maintainable CI/CD pipelines.
Centralized logic: Extracting common logic and configurations into separate workflows and invoking them from multiple workflows, improving code organization and reducing redundancy.
Let's walk through an example scenario that demonstrates the usage of workflow_call:
In this example, the caller workflow is ping.yml and the reusable workflow is pong.yml. You can define inputs and secrets in the caller workflow, which you can then use in the reusable workflow.
Suppose you have a repository with two workflows: ping.yml and pong.yml. The ping.yml workflow performs the build process and the test.yml workflow runs tests on the built artifacts.
Here's how you can modularize ping.ymland pong.yml workflows using workflow_call:
In the ping.yml workflow:
name: Workflow A (Ping)
on:
push:
branches:
- main
jobs:
ping:
uses: USER_OR_ORG_NAME/REPO_NAME/.github/workflows/pong.yaml@master
with:
ping: 'PONG'In the pong.yml workflow:
name: Workflow B (Pong)
on:
workflow_call:
inputs:
ping:
required: true
type: string
jobs:
pong:
runs-on: ubuntu-latest
steps:
- name: Pong
run: echo "${{ inputs.ping }}"In this example, the ping.yml workflow defines a job that utilizes workflow_call to invoke the pong.yml workflow. The pong.yml workflow expects input parameter ping which is passed from the ping.yml workflow.
Using REST API to launch workflows
The GitHub API provides the ability to dispatch events across repositories. For instance, you can trigger a workflow in Repository A from another workflow in Repository B. This cross-repository interaction enables advanced automation and workflow orchestration, empowering you to create complex CI/CD pipelines spanning multiple repositories.
The repository_dispatch event does not have specific activity types. It is a generic event triggered by custom events you define.
You can use the repository_dispatch event in scenarios where you need to trigger a workflow based on custom events within your repository. Some common use cases for repository_dispatch include:
External triggers: Initiating workflows based on events outside the repository, such as external systems, webhooks, or APIs
Custom workflows: Creating customized workflows that can be triggered based on unique events specific to your project's requirements.
Suppose you want to trigger a workflow in Repository A using the repository_dispatch event and provide custom payload data. Whenever a ping event occurs in the repository defined by repository_dispatch, it triggers the Remote Dispatch Responder (Repository A) workflow.
name: Remote Dispatch Responder (Repository A)
on: repository_dispatch
jobs:
ping-pong:
runs-on: ubuntu-latest
steps:
- name: Event Information
run: |
echo "Event '${{ github.event.action }}' received from '${{ github.event.client_payload.repository }}'"Remote Dispatch Action (Repository B) workflow consists of a single job called "ping-pong". The purpose of this step is to send a remote dispatch event to another GitHub repository named Repository A. It uses the curl command to make an HTTP POST request to the GitHub API endpoint(https://api.github.com/repos/OWNER/REPO/dispatches). The request includes the necessary headers, such as the Accept header for specifying the response format, the Authorization header for providing an access token stored in GitHub Secrets (${{secrets.ACCESS_TOKEN}}), and the X-GitHub-Api-Version header for specifying the GitHub API version.
name: Remote Dispatch Action (Repository B)
on:
push:
jobs:
ping-pong:
runs-on: ubuntu-latest
steps:
- name: PING
run: |
curl -L \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: token ${{secrets.ACCESS_TOKEN}}"\
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/OWNER/REPO/dispatches \
-d '{"event_type": "ping", "client_payload": { "repository": "'"$GITHUB_REPOSITORY"'" }}'One of the main requirements to perform requests to the repository dispatch endpoint is to use authentication. The endpoints require write access by using Personal Access Token (PAT). You can set up PAT using this guide in the documentation
This API call triggers the repository_dispatch event with the event type pingand includes a payload containing the repository field.
Conclusion
In conclusion, GitHub Actions offers a range of event-based triggers and features for workflow automation. Whether it's triggering workflows externally with repository_dispatch, manual triggering with workflow_dispatch, establishing dependencies with workflow_run, or modularizing workflows with workflow_call, these tools provide flexibility, control, and reusability. With GitHub Actions, you can streamline your CI/CD pipelines, enhance collaboration, and automate key processes to create efficient and effective software development workflows.