Skip to content

Commit

Permalink
ci: Add a slack notifier workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
aborgna-q committed Oct 25, 2024
1 parent 1d4e95b commit 7895339
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 0 deletions.
92 changes: 92 additions & 0 deletions .github/workflows/slack-notifier.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: Post comments on slack, with rate limiting.
on:
workflow_call:
secrets:
SLACK_BOT_TOKEN:
description: 'The slack API token, with `chat:write` permissions.'
required: true
inputs:
channel-id:
description: 'The channel ID to send the message to.'
required: true
type: string
slack-message:
description: 'The message to send to slack.'
required: true
type: string
message-label:
description: 'A label identifying the message type. Used to rate limit messages.'
required: true
type: string
timeout-minutes:
description: 'The minimum time to wait before sending the message again, in minutes.'
required: false
type: string
# Default to 24 hours
default: '1440'
outputs:
sent:
description: 'Whether the message was sent. Returns false if we are waiting for a timeout.'
value: ${{ jobs.notify-slack.outputs.sent }}

jobs:
notify-slack:
runs-on: ubuntu-latest
outputs:
sent: ${{ steps.rate-limit.outputs.send }}
steps:
- name: Check last message timestamp
id: last-sent
uses: dawidd6/action-download-artifact@v6
with:
# Downloads the artifact from the most recent successful run
workflow: 'slack-notifier.yml'
name: last-sent-${{ inputs.message-label }}.txt
if_no_artifact_found: ignore

- name: Rate limit
id: rate-limit
run: |
# Check if the last message was sent within the timeout
echo "Preparing to send message:\n"
echo "\"$MESSAGE\"\n"
if [ -f last-sent-${{ inputs.message-label }}.txt ]
then
LAST_SENT=$( cat last-sent.txt )
echo "Last sent: $LAST_SENT"
NOW=$( date +%s )
echo "Now: $NOW"
echo "Timeout: $TIMEOUT mins"
echo "Difference: $(( NOW - LAST_SENT ))"
if [ $(( NOW - LAST_SENT )) -lt $(( TIMEOUT * 60 )) ]
then
echo "Rate limiting. Not sending the message."
echo "send=false" >> "$GITHUB_OUTPUT"
exit 0
fi
else
echo "No last-sent file found."
fi
echo "send=true" >> "$GITHUB_OUTPUT"
date +%s > last-sent-${{ inputs.message-label }}.txt
env:
TIMEOUT: ${{ inputs.timeout-minutes }}
MESSAGE: ${{ inputs.slack-message }}

- name: Send notification
if: ${{ steps.rate-limit.outputs.send == 'true' }}
uses: slackapi/[email protected]
with:
channel-id: ${{ inputs.channel-id }}
slack-message: ${{ inputs.slack-message }}
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}

- name: Upload the new last-sent timestamp
if: ${{ steps.rate-limit.outputs.send == 'true' }}
uses: actions/upload-artifact@v4
with:
name: last-sent-${{ inputs.message-label }}.txt
path: last-sent-${{ inputs.message-label }}.txt
48 changes: 48 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ The following workflows are available:
- [`drop-cache`](#drop-cache): Drops the cache for a branch when a pull request is closed.
- [`pr-title`](#pr-title): Checks the title of pull requests to ensure they follow the conventional commits format.
- [`rs-semver-checks`](#rs-semver-checks): Runs `cargo-semver-checks` on a PR against the base branch, and reports back if there are breaking changes.
- [`slack-notifier`](#slack-notifier): Post comments on slack, with a rate limit to avoid spamming the channel.

## [`add-to-project`](https://github.com/CQCL/hugrverse-actions/blob/main/.github/workflows/add-to-project.yml)

Expand Down Expand Up @@ -184,3 +185,50 @@ The fine-grained `GITHUB_PAT` secret must include the following permissions:
| --- | --- |
| Pull requests | Read and write |


## [`slack-notifier`](https://github.com/CQCL/hugrverse-actions/blob/main/.github/workflows/slack-notifier.yml)

Post comments on slack using
[slackapi/slack-github-action](https://github.com/slackapi/slack-github-action),
adding a rate limit to avoid spamming the channel.

### Usage
```yaml
name: Send a slack message
on:
pull_request:
branches:
- main
jobs:
message-slack:
uses: CQCL/hugrverse-actions/.github/workflows/slack-notifier.yml@main
with:
channel-id: "SOME CHANNEL ID"
slack-message: "Hello 🌎!"
# An unique identifier for the message type, to use in rate limiting.
message-label: "hello"
# A minimum time in minutes to wait before sending another message.
timeout-minutes: 60
secrets:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
```

### Inputs

- `channel-id`: The ID of the channel to post the message to. (**required**)
- `slack-message`: The message to post. (**required**)
- `message-label`: An identifier for the message type, to use in rate limiting.
This label is tied to the workflow name. (**required**)
- `timeout-minutes`: A minimum time in minutes to wait before sending another message. Defaults to 24 hours.

### Outputs

- `sent`: A boolean indicating if the message was sent.

### Token Permissions

`SLACK_BOT_TOKEN` is a token generated by Slack with `chat:write` access to the
channel. See the
[slackapi/slack-github-action](https://github.com/slackapi/slack-github-action?tab=readme-ov-file#technique-2-slack-app)
documentation for more information.

0 comments on commit 7895339

Please sign in to comment.