As a tech team, we love when new features and bug fixes are shipped fast in production. For this, we want, as a member of this dev team, to be reminded of all Pull Requests I have missed (sorry guys...) and the ones which are finished but not merged yet.
It's also a nice time to grab a coffee and make some code review.
We want to maintain this fast track for many reasons:
The more you wait, the more you will be creating conflicts and differences with the work in progress inside other teams
For bug fixes: they are ready, so why wait much more time to ship it to end-users? Some fixes can be the difference between a bad and a good day
All devs can rely on your new code, including new functions, utilities, and components
There is already a scheduled reminder feature inside GitHub, but we wanted to have more control over notifications and have rules based on code.
Also, this feature on Github is only available for Slack and we wanted to make it compatible with Discord too.
How we have done it with Meta API
We have done it with a Spell, of course!
Then, this Spell will be deployed as an API and can be run manually, with a scheduler, or even with an external Webhook.
This is how this Spell works:
As an API, we will provide as a parameter a list of repositories we want to scan
For each repo, we will:
Retrieve all the Pull Requests
Filter them (we don't want to be notified of pull requests generated by dependabot for example)
Get some details for each PR, like the creation date, the number of commits, if our automated tests run successfully, etc.
Check if each reviewer has done his review and get the associated status
Mix all these data and create a nice Slack message
Send, we send the message on Slack on our custom channel
We have created a bunch of functions to retrieve and transform data from Github like a list of Pull Request, reviews attached to these pull requests, etc...
Here is how our final Slack message looks like
Step by step
The code you write inside your own Spell on Meta-API is plain TS / JS code: so it can be reused outside Meta API. Each part managed by connectors can be replaced by libraries or API requests done by a client like axios.
Of course, you will lose the automatic monitoring, the ability to update your Spell with new connectors in minutes, etc. but it will continue to work!
So here is our step-by-step creation with technical details.
The main processing
Our main processing code is simple and consist in imbricated loops.
For starting, we want to create a counter and an array to store the text section we will send later to Slack
Then, we start our loop over each repositories
We call an internal function to help us getting all info about a repo:
Then we apply a filter on it to remove drafts and dependabot PRs.
We increment our counter and generate an header block for Slack based on the number of PRs.
We now need to go deeper inside each PR and retrieve more information
First, we will also use internal functions to details and all the reviewers on each PR.
Tips: we use Promises and concurrent calls to make our code a bit faster!
Then, we prepare a bunch of text to create a nice display on Slack. You can use the Block Kit Builder on Slack to help you with this particular format.
Let's then loop over reviewers to determine if there have already done the review or not and choose a nice emoji to represent it.
In the end, we push new blocks inside our Slack array to build our message line by line.
Here is the full code:
Functions to make our code cleaner
Here are a bunch of functions we used to make our main code much more readable:
This function will call our Connector with all the configurations inside our Connector interface, like binding the correct repo and owner, sorting repos, filtering by a specific state, etc...
All APIs capabilities are extracted and available through our interface.
The whole interface is dynamically generated from an Open API Specification file, making our platform compatible with any APIs.
We first extract some data into variables to binding them into the connector interface
Same thing for extracting info into variables to binding them
More utility functions to help us with formatting and manipulating arrays.
You can see TypeScript's type between this function to enforce some type checking.
The final part is formatting the blocks for Slack and send through Slack's Connector
That's it! Our Spell is ready to be used with a total of 4 connectors and 163 lines of code (with a lot of spaces).
It will be versioned, deployed, and monitored in less than 30s.
If anything is going wrong after going live, we will receive notifications.
You will find the source code here, feel free to use it for you!
What about Discord?
As you can read, the text is formatted for Slack and then sent through a dedicated connector. We are migrating our internal communication from Slack to Discord and we already updated some of our Spell to use Discord.
Here is an example of how we can send a message both on Slack and Discord within the same Spell:
So we will need to change the way we format messages on Discord, testing it on our staging environment, and then push it to production.
We think about many features we can add to our Spell:
Mention people to get more attention
Trigger some alerts if a PR is not merged within 4 days
Create a summary of all comments inside each PRs
Send us your ideas!