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
153 changes: 153 additions & 0 deletions .github/scripts/announce_pr_on_slack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
#!/usr/bin/env python3
"""
GitHub Actions script to send Slack notifications for new pull requests.
"""

import os
import sys
from typing import Tuple

import httpx


def send_slack_message(
slack_team: str, slack_service: str, slack_token: str, message: str
) -> bool:
"""Send a message to Slack channel."""

url = (
f"https://hooks.slack.com/services/T{slack_team}/B{slack_service}/{slack_token}"
)

headers = {
"Content-Type": "application/json",
}

data = {"text": message}

try:
with httpx.Client() as client:
response = client.post(url, headers=headers, json=data)
response.raise_for_status()

result = response.text
if "ok" in result:
print("✅ Slack message sent successfully")
return True
else:
print(f"❌ Slack API error: {result}")
return False

except httpx.HTTPError as e:
print(f"❌ Request error: {e}")
return False


def ensure_environment_variables_are_present() -> (
Tuple[str, str, str, str, str, str, str, str]
):
"""
Ensures that all necessary environment variables are present for the application to run.

This function checks for the presence of required environment variables related to Slack bot token,
Pull Request (PR) details, and repository name. It also validates that the Slack channel is set.

Raises:
SystemExit: If any of the required environment variables are missing.

Returns:
A tuple containing the values of the following environment variables:
- SLACK_TOKEN: The token for the Slack bot.
- SLACK_TEAM: The ID of the Slack team.
- SLACK_SERVICE: The ID of the Slack service.
- PR_NUMBER: The number of the Pull Request.
- PR_TITLE: The title of the Pull Request.
- PR_URL: The URL of the Pull Request.
- PR_AUTHOR: The author of the Pull Request.
- REPO_NAME: The name of the repository.
"""
# Get environment variables
slack_token = os.getenv("SLACK_TOKEN")
slack_team = os.getenv("SLACK_TEAM")
slack_service = os.getenv("SLACK_SERVICE")
pr_number = os.getenv("PR_NUMBER")
pr_title = os.getenv("PR_TITLE")
pr_url = os.getenv("PR_URL")
pr_author = os.getenv("PR_AUTHOR")
repo_name = os.getenv("REPO_NAME")

# Validate required environment variables
if not slack_token:
print("❌ SLACK_TOKEN environment variable is required")
sys.exit(1)

if not slack_team:
print("❌ SLACK_TEAM environment variable is required")
sys.exit(1)

if not slack_service:
print("❌ SLACK_SERVICE environment variable is required")
sys.exit(1)

if not all([pr_number, pr_title, pr_url, pr_author, repo_name]):
print(
"❌ Missing required PR information (PR_NUMBER, PR_TITLE, PR_URL, PR_AUTHOR, REPO_NAME)"
)
sys.exit(1)

# Since we're validating these variables, we can assert they're not None
assert pr_number is not None
assert pr_title is not None
assert pr_url is not None
assert pr_author is not None
assert repo_name is not None

return (
slack_token,
slack_team,
slack_service,
pr_number,
pr_title,
pr_url,
pr_author,
repo_name,
)


def main() -> None:
"""Main function to process PR and send Slack notification."""

(
slack_token,
slack_team,
slack_service,
pr_number,
pr_title,
pr_url,
pr_author,
repo_name,
) = ensure_environment_variables_are_present()

print(f"Processing PR #{pr_number}")

# Create Slack message
message = (
f":mega: Oyez! Oyez! Oyez!\n"
f"Hello Team. Please, review the opened PR #{pr_number} in {repo_name}\n"
f"*{pr_title}* by @{pr_author}\n"
f":pull-request-opened: {pr_url}"
)

# Send to Slack
success = send_slack_message(slack_service, slack_team, slack_token, message)

if not success:
sys.exit(1)

print("✅ Process completed successfully")


if __name__ == "__main__":
main()

# Made with Bob
92 changes: 92 additions & 0 deletions .github/scripts/announce_release_on_slack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/usr/bin/env python3

import logging
import os
import sys

import httpx
from github import Github


def ensure_environment_variables_are_present() -> None:
required_env_vars = (
"GITHUB_RELEASE_TAG",
"GITHUB_TOKEN",
"SLACK_TOKEN",
"SLACK_SERVICE",
"SLACK_TEAM",
)

for env_var in required_env_vars:
if env_var not in os.environ:
logging.fatal(f"❌ A required environment variable is missing: {env_var}")
sys.exit(1)


def get_gh_release_info_text_with_token(release_tag: str, access_token: str) -> str:
gh = Github(access_token)
repo_name = "instana/python-sensor"
repo = gh.get_repo(repo_name)
release = repo.get_release(release_tag)

logging.info("GH Release fetched successfully %s", release)

msg = (
f":mega: Oyez! Oyez! Oyez!\n"
f":package: A new version of the Python Tracer has been released.\n"
f"Name: Instana Python Tracer {release.title}\n"
f"Tag: {release.tag_name}\n"
f"Created at: {release.created_at}\n"
f"Published at: {release.published_at}\n"
f"{release.body}\n"
)

logging.info(msg)
return msg


def post_on_slack_channel(
slack_team: str, slack_service: str, slack_token: str, message_text: str
) -> None:
"""Send a message to Slack channel."""

url = (
f"https://hooks.slack.com/services/T{slack_team}/B{slack_service}/{slack_token}"
)

headers = {
"Content-Type": "application/json",
}
body = {"text": message_text}

with httpx.Client() as client:
response = client.post(url, headers=headers, json=body)
response.raise_for_status()

result = response.text
if "ok" in result:
print("✅ Slack message sent successfully")
else:
print(f"❌ Slack API error: {result}")


def main() -> None:
# Setting this globally to DEBUG will also debug PyGithub,
# which will produce even more log output
logging.basicConfig(level=logging.INFO)
ensure_environment_variables_are_present()

msg = get_gh_release_info_text_with_token(
os.environ["GITHUB_RELEASE_TAG"], os.environ["GITHUB_TOKEN"]
)

post_on_slack_channel(
os.environ["SLACK_TEAM"],
os.environ["SLACK_SERVICE"],
os.environ["SLACK_TOKEN"],
msg,
)


if __name__ == "__main__":
main()
41 changes: 41 additions & 0 deletions .github/workflows/opened-pr-notification-on-slack.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: PR Slack Notification

permissions:
contents: read
pull-requests: read

on:
pull_request:
types: [opened, reopened, review_requested]

jobs:
notify-slack:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history to access commit messages

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.13'

- name: Install dependencies
run: |
pip install httpx

- name: Send Slack notification
env:
SLACK_TOKEN: ${{ secrets.RUPY_PR_ANNOUNCEMENT_TOKEN }}
SLACK_SERVICE: ${{ secrets.RUPY_PR_ANNOUNCEMENT_CHANNEL_ID }}
SLACK_TEAM: ${{ secrets.RUPY_TOWN_CRIER_SERVICE_ID }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.number }}
PR_TITLE: ${{ github.event.pull_request.title }}
PR_URL: ${{ github.event.pull_request.html_url }}
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
REPO_NAME: ${{ github.repository }}
run: python .github/scripts/announce_pr_on_slack.py
71 changes: 51 additions & 20 deletions .github/workflows/release-notification-on-slack.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,57 @@ on:

# https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#release
release:
types: [published]
types: [published, released]
jobs:
build:
name: Slack Post
notify-slack:
runs-on: ubuntu-latest

steps:
- name: 'Checkout the needed file only ./bin/announce_release_on_slack.py'
uses: actions/checkout@v3
- run: |
if [[ ${{ github.event_name == 'workflow_dispatch' }} == true ]]; then
export GITHUB_RELEASE_TAG=${{ inputs.github_ref }}
else # release event
export GITHUB_RELEASE_TAG=$(basename ${GITHUB_REF})
fi
echo "New release published ${GITHUB_RELEASE_TAG}"
pip3 install PyGithub
echo $PWD
ls -lah
./bin/announce_release_on_slack.py
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
SLACK_CHANNEL_ID_RELEASES: ${{ secrets.SLACK_CHANNEL_ID_RELEASES }}
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history to access commit messages

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.13'

- name: Install dependencies
run: |
pip install httpx PyGithub

# Set environment variables safely
- name: Set event name
id: set-event-name
env:
EVENT_NAME: ${{ github.event_name }}
run: echo "EVENT_NAME=$EVENT_NAME" >> $GITHUB_ENV

# Handle workflow_dispatch event
- name: Set GitHub ref for workflow dispatch
if: ${{ github.event_name == 'workflow_dispatch' }}
env:
INPUT_REF: ${{ inputs.github_ref }}
run: echo "GITHUB_RELEASE_TAG=$INPUT_REF" >> $GITHUB_ENV

# Handle release event
- name: Set GitHub ref for release event
if: ${{ github.event_name != 'workflow_dispatch' }}
env:
GH_REF: ${{ github.ref }}
run: |
REF_NAME=$(basename "$GH_REF")
echo "GITHUB_RELEASE_TAG=$REF_NAME" >> $GITHUB_ENV

# Send notification using the safely set environment variables
- name: Send Slack notification
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SLACK_TOKEN: ${{ secrets.RUPY_TRACER_RELEASES_TOKEN }}
SLACK_SERVICE: ${{ secrets.RUPY_TRACER_RELEASES_CHANNEL_ID }}
SLACK_TEAM: ${{ secrets.RUPY_TOWN_CRIER_SERVICE_ID }}
run: |
echo "New release published ${GITHUB_RELEASE_TAG}"
python .github/scripts/announce_release_on_slack.py

Loading
Loading