Add slack notifications after deployments (#1485)

* Add slack notifications after deployments

* Fix copy paste mistakes

* Add deployment workflows to CODEOWNERS
This commit is contained in:
GrzegorzKowalik 2021-10-11 10:51:53 +02:00 committed by GitHub
parent 2096671e0c
commit 031d012d0d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 155 additions and 2 deletions

6
.github/CODEOWNERS vendored
View file

@ -1,2 +1,4 @@
# Restrict Test Environment Deployment Workflows to be Approved by Cloud Team
.github/workflows/test-env* @saleor/cloud
# Restrict Deployment Workflows to be Approved by Cloud Team
.github/workflows/test-env* @saleor/cloud
.github/workflows/deploy-* @saleor/cloud
.github/workflows/notify/* @saleor/cloud

View file

@ -55,3 +55,12 @@ jobs:
if [[ -n "$CF_2_ID" ]]; then
aws cloudfront create-invalidation --distribution-id ${CF_2_ID} --paths "/dashboard*"
fi
- name: Notify Slack
if: ${{ always() }}
env:
JOB_DEPLOYMENT_KIND: production
JOB_STATUS: ${{ job.status }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CLOUD_DEPLOYMENTS_WEBHOOK_URL }}
JOB_TITLE: "Dashboard deployment to {{ env.ENVIRONMENT }}"
run: |
python3 ./.github/workflows/notify/notify-slack.py

View file

@ -39,3 +39,12 @@ jobs:
aws s3 sync build/dashboard s3://${{ secrets.AWS_DEMO_DEPLOYMENT_BUCKET }}/dashboard/static/
aws s3 cp build/dashboard/index.html s3://${{ secrets.AWS_DEMO_DEPLOYMENT_BUCKET }}/dashboard/
aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_DEMO_CF_DIST_ID }} --paths "/dashboard*"
- name: Notify Slack
if: ${{ always() }}
env:
JOB_DEPLOYMENT_KIND: production
JOB_STATUS: ${{ job.status }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CLOUD_DEPLOYMENTS_WEBHOOK_URL }}
JOB_TITLE: "Dashboard deployment to {{ env.ENVIRONMENT }}"
run: |
python3 ./.github/workflows/notify/notify-slack.py

View file

@ -49,3 +49,13 @@ jobs:
aws s3 sync build/dashboard s3://${{ secrets.AWS_STAGING_DEPLOYMENT_BUCKET }}/${ENVIRONMENT}/static/
aws s3 cp build/dashboard/index.html s3://${{ secrets.AWS_STAGING_DEPLOYMENT_BUCKET }}/${ENVIRONMENT}/
aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_STAGING_CF_DIST_ID }} --paths "/dashboard*"
- name: Notify Slack
if: ${{ always() }}
env:
JOB_DEPLOYMENT_KIND: staging
JOB_STATUS: ${{ job.status }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CLOUD_DEPLOYMENTS_WEBHOOK_URL }}
JOB_TITLE: "Dashboard deployment to {{ env.ENVIRONMENT }}"
run: |
python3 ./.github/workflows/notify/notify-slack.py

View file

@ -43,3 +43,13 @@ jobs:
aws s3 sync build/dashboard s3://${{ secrets.AWS_STAGING_DEPLOYMENT_BUCKET }}/${ENVIRONMENT}/static/
aws s3 cp build/dashboard/index.html s3://${{ secrets.AWS_STAGING_DEPLOYMENT_BUCKET }}/${ENVIRONMENT}/
aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_STAGING_CF_DIST_ID }} --paths "/dashboard*"
- name: Notify Slack
if: ${{ always() }}
env:
JOB_DEPLOYMENT_KIND: staging
JOB_STATUS: ${{ job.status }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CLOUD_DEPLOYMENTS_WEBHOOK_URL }}
JOB_TITLE: "Dashboard deployment to {{ env.ENVIRONMENT }}"
run: |
python3 ./.github/workflows/notify/notify-slack.py

View file

@ -49,3 +49,13 @@ jobs:
aws s3 sync build/dashboard s3://${{ secrets.AWS_STAGING_DEPLOYMENT_BUCKET }}/${ENVIRONMENT}/static/
aws s3 cp build/dashboard/index.html s3://${{ secrets.AWS_STAGING_DEPLOYMENT_BUCKET }}/${ENVIRONMENT}/
aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_STAGING_CF_DIST_ID }} --paths "/dashboard*"
- name: Notify Slack
if: ${{ always() }}
env:
JOB_DEPLOYMENT_KIND: staging
JOB_STATUS: ${{ job.status }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CLOUD_DEPLOYMENTS_WEBHOOK_URL }}
JOB_TITLE: "Dashboard deployment to {{ env.ENVIRONMENT }}"
run: |
python3 ./.github/workflows/notify/notify-slack.py

103
.github/workflows/notify/notify-slack.py vendored Executable file
View file

@ -0,0 +1,103 @@
#!/usr/bin/env python
"""
Notifies about deployment status to a given slack channel.
This file currently needs to be duplicated between repositories until
https://github.com/github/roadmap/issues/98 is closed.
Dependencies (already shipped by ubuntu-20.04):
- Python 3.6+
- requests package (any version)
Manual Environment Variables (explicit):
- JOB_DEPLOYMENT_KIND: deployment target kind, staging, dev, etc.
- SLACK_WEBHOOK_URL: incoming webhook URL to send payload/message to
- JOB_STATUS: status from GitHub's ``job.status``
- JOB_TITLE: the title of the job
Global GitHub Environment Variables (implicit):
- GITHUB_RUN_ID
- GITHUB_REPOSITORY
- GITHUB_ACTOR
"""
import os
import sys
import requests
class JobNotifier:
JOB_STATUS_COLOR_MAP = {
"success": "#5DC292",
"failure": "#FE6E76",
"cancelled": "#868B8E",
}
def __init__(self):
# The title of the pull request
self.title: str = os.environ["JOB_TITLE"]
# The kind of deployment (dev, staging, ...)
self.deployment_kind: str = os.environ["JOB_DEPLOYMENT_KIND"]
# Incoming Webhook Endpoint, it is set a the organization level
# Development notifier configuration is available at: https://api.slack.com/apps/A0210C30YLD/
self.slack_endpoint = os.environ["SLACK_WEBHOOK_URL"]
# Workflow Run ID to retrieve the logs permalink of the actual run (failed/succeeded)
self.run_id: str = os.environ["GITHUB_RUN_ID"]
# <owner>/<repo>
self.repository: str = os.environ["GITHUB_REPOSITORY"]
# The user that triggered the action
self.author: str = os.environ["GITHUB_ACTOR"]
# Job Status (success|failure|cancelled)
self.job_status: str = os.environ["JOB_STATUS"]
@property
def run_permalink(self) -> str:
"""Permalink to the current run logs"""
return f"https://github.com/{self.repository}/actions/runs/{self.run_id}"
@property
def job_status_color(self) -> str:
"""Color from Saleor Cloud palette for job status"""
return self.JOB_STATUS_COLOR_MAP[self.job_status]
def make_slack_message(self) -> dict:
status = self.job_status.capitalize()
# Dev deployment triggered by JohnDoe: Success
text = (
f"{self.author} deployment finished for '{self.deployment_kind.capitalize()}', result: "
f"{status}"
)
message_data = {
"attachments": [
{
"fallback": text,
"pretext": "",
"title": f"{self.repository}: {self.title}",
"title_link": self.run_permalink,
"text": text,
"color": self.job_status_color,
}
]
}
return message_data
def send_notification(self) -> None:
post_data = self.make_slack_message()
print(f"Notifying slack with payload: {post_data!r}", file=sys.stderr)
response = requests.post(self.slack_endpoint, json=post_data)
response.raise_for_status()
def main():
JobNotifier().send_notification()
if __name__ == "__main__":
main()