When using a repository, it is helpful to know the status of the executed jobs. In our organization, we want to send this information to our communication tool (Slack). We achieve this by using GitHub Actions.
The GitHub documentation defines actions as follows:
GitHub actions are individual tasks that you can combine to create jobs and customize your workflow. You can create your own actions or use and customize actions shared by the GitHub community. (About Actions — GitHub Docs)
There are already actions created by the community. So, why would we want to implement them again?
When we needed the action, what we found in the marketplace didn’t meet our requirements. By creating our custom action we ensure two things: first, the information posted to Slack is exactly what we want and sensitive data is treated properly. Second, we can optimize the action to be the most performant for our use case.
Types of Actions
Docker-based actions run GitHub Actions code inside Docker containers. This allows using specific versions of an operating system, dependencies and tools. This is an ideal option for actions that must run in a specific environment.
Composite run steps actions allow you to combine many workflow run steps in one action. You can use this feature to bundle together many run commands into an Action.
- If you use libraries, you must include them in the repository (although not having to download the dependencies every time is what makes it faster).
action.yml: Metadata file to define the
mainentry point for your action. The
.yamlextension is also valid for this file.
index.js: This file defines the behaviour of the action. In this case, a notification is sent to Slack with information about the GitHub event.
The code above sends a message to Slack indicating whether the GitHub event has been a success or a failure with its associated colour. The message is sent with the standard fetch method (using the node-fetch library), and structured using the Slack
blocks API. In another of my stories, you can find a detailed explanation about the structure of the message and the fetch call.
core package to get the action’s inputs.
Test the Action
To test the action we add a new workflow in the
The action uses the following inputs:
job-status: Gets its value from the
jobobject. This object contains information about the currently executing job.
channel: Slack channel name. Defined by the user.
slack-bot-token: Slack App Token. Provided using GitHub secrets.
Once the action has been defined and the workflow created, each time an event occurs in the repository, two notifications will be sent. One for success and one for failure. This way, we check that the notification works for both cases.
The Complete Action
The action above barely provides any information about the GitHub event. For our organization, we have created a more complete action.
This version customizes the message according to three types of events: push, pull request and manual triggers. Most of the information about the event is collected using the
event input and the Toolkit
event input gets its value from the
github object, which contains information about the workflow run. The github package also provides an authenticated Octokit
REST client that gives access to the GitHub API.
To get all the pull request information that we need, we use two different methods. Using the action’s inputs we get the names of the Pull Request’s related branches. Next, by using the Octokit
REST client, we get the name of the Pull Request.
With these improvements and properly structuring the message, we get notifications tailored to our needs.
By creating the action ourselves, we can customize it and adapt it to the specific uses of our organization. If one day we need to change the information, it will be easier than with a third party action.