Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/daily.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ name: Daily Collection

on:
workflow_dispatch:
inputs:
slack_channel:
description: Slack channel to post the error message to if the builds fail.
required: false
default: "sdv-alerts-debug"
schedule:
- cron: '0 0 * * *'

Expand All @@ -28,3 +33,22 @@ jobs:
env:
PYDRIVE_CREDENTIALS: ${{ secrets.PYDRIVE_CREDENTIALS }}
BIGQUERY_CREDENTIALS: ${{ secrets.BIGQUERY_CREDENTIALS }}

alert:
needs: [collect]
runs-on: ubuntu-latest
if: failure()
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.13'
- name: Install slack dependencies
run: |
python -m pip install --upgrade pip
python -m pip install invoke
python -m pip install .[dev]
- name: Slack alert if failure
run: python -m github_analytics.slack_utils -r ${{ github.run_id }} -c ${{ github.event.inputs.slack_channel || 'sdv-alerts' }}
env:
SLACK_TOKEN: ${{ secrets.SLACK_TOKEN }}
33 changes: 29 additions & 4 deletions .github/workflows/dryrun.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
name: Health-check Dry Run

on:
- workflow_dispatch
- push
- pull_request
workflow_dispatch:
inputs:
slack_channel:
description: Slack channel to post the error message to if the builds fail.
required: false
default: "sdv-alerts-debug"

push:
pull_request:

jobs:
collect:
dry_run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -29,3 +35,22 @@ jobs:
env:
PYDRIVE_CREDENTIALS: ${{ secrets.PYDRIVE_CREDENTIALS }}
BIGQUERY_CREDENTIALS: ${{ secrets.BIGQUERY_CREDENTIALS }}

alert:
needs: [dry_run]
runs-on: ubuntu-latest
if: failure()
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.13'
- name: Install slack dependencies
run: |
python -m pip install --upgrade pip
python -m pip install invoke
python -m pip install .[dev]
- name: Slack alert if failure
run: python -m github_analytics.slack_utils -r ${{ github.run_id }} -c ${{ github.event.inputs.slack_channel || 'sdv-alerts' }}
env:
SLACK_TOKEN: ${{ secrets.SLACK_TOKEN }}
100 changes: 100 additions & 0 deletions download_analytics/slack_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
"""Utility functions for Slack integration."""

import argparse
import os

from slack_sdk import WebClient

GITHUB_URL_PREFIX = 'https://github.com/datacebo/download-analytics/actions/runs/'
DEFAULT_SLACK_CHANNEL = 'sdv-alerts-debug'


def _get_slack_client():
"""Create an authenticated Slack client.

Returns:
WebClient:
An authenticated Slack WebClient instance.
"""
token = os.getenv('SLACK_TOKEN')
client = WebClient(token=token)
return client


def post_slack_message(channel, text):
"""Post a message to a Slack channel.

Args:
channel (str):
The name of the channel to post to.
text (str):
The message to send to the channel.

Returns:
SlackResponse:
Response from Slack API call
"""
client = _get_slack_client()
response = client.chat_postMessage(channel=channel, text=text)
if not response['ok']:
error = response.get('error', 'unknown_error')
msg = f'{error} occured trying to post message to {channel}'
raise RuntimeError(msg)

return response


def post_slack_message_in_thread(channel, text, thread_ts):
"""Post a message as a threaded reply in a Slack channel.

Args:
channel (str):
The name of the channel to post to.
text (str):
The message to send as a reply in the thread.
thread_ts (str):
The timestamp of the message that starts the thread.

Returns:
SlackResponse:
Response from Slack API call.
"""
client = _get_slack_client()
response = client.chat_postMessage(channel=channel, text=text, thread_ts=thread_ts)
if not response['ok']:
error = response.get('error', 'unknown_error')
msg = f'{error} occurred trying to post threaded message to {channel}'
raise RuntimeError(msg)

return response


def send_alert(args):
"""Send an alert message to a slack channel."""
url = GITHUB_URL_PREFIX + args.run_id
message = (
f'Download Analytics build failed :fire: :dumpster-fire: :fire: See errors <{url}|here>'
)
post_slack_message(args.channel, message)


def get_parser():
"""Get the parser."""
parser = argparse.ArgumentParser(description='Function to alert when a Github workflow fails.')
parser.add_argument('-r', '--run-id', type=str, help='The id of the github run.')
parser.add_argument(
'-c',
'--channel',
type=str,
help='The slack channel to post to.',
default=DEFAULT_SLACK_CHANNEL,
)
parser.set_defaults(action=send_alert)

return parser


if __name__ == '__main__':
parser = get_parser()
args = parser.parse_args()
args.action(args)
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ include = ['download_analytics', 'download_analytics.*']
[project.optional-dependencies]
dev = [
"ruff>=0.9.8",
"invoke"
"invoke",
"slack-sdk>=3.34,<4.0",
]

[tool.ruff]
Expand Down