Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a Slack notification job to the CI + CD workflow #1066

Merged
merged 9 commits into from
Apr 4, 2023
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
3 changes: 3 additions & 0 deletions .github/actions/get-changes/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ outputs:
frontend:
description: "'true' if frontend changes are present"
value: ${{ steps.paths-filter.outputs.frontend }}
documentation:
description: "'true' if documentation changes are present"
value: ${{ steps.paths-filter.outputs.documentation }}
lint:
description: "'true' if linting setup changes are present"
value: ${{ steps.paths-filter.outputs.frontend }}
Expand Down
4 changes: 4 additions & 0 deletions .github/filters.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ frontend:
- .pnpmfile.cjs
# Change to the CI + CD workflow should trigger complete workflow.
- .github/workflows/ci_cd.yml
documentation:
- documentation/**
# Change to the CI + CD workflow should trigger complete workflow.
- .github/workflows/ci_cd.yml
lint:
- prettier.config.js
- .prettierignore
Expand Down
94 changes: 94 additions & 0 deletions .github/workflows/ci_cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ jobs:
api: ${{ steps.paths-filter.outputs.api }}
ingestion_server: ${{ steps.paths-filter.outputs.ingestion_server }}
frontend: ${{ steps.paths-filter.outputs.frontend }}
documentation: ${{ steps.paths-filter.outputs.documentation }}
changes: ${{ steps.paths-filter.outputs.changes }}
steps:
- name: Checkout repository
Expand Down Expand Up @@ -595,11 +596,13 @@ jobs:
github.actor != 'dependabot[bot]'
)
) &&
(needs.get-changes.outputs.frontend == 'true' || needs.get-changes.outputs.documentation == 'true') &&
(needs.test-ing.result == 'success' || needs.test-ing.result == 'skipped') &&
(needs.test-api.result == 'success' || needs.test-api.result == 'skipped') &&
(needs.nuxt-build.result == 'success' || needs.nuxt-build.result == 'skipped')
runs-on: ubuntu-latest
needs:
- get-changes
- test-ing
- test-api
- nuxt-build
Expand Down Expand Up @@ -787,3 +790,94 @@ jobs:
"Deployment: staging-api"
env:
GITHUB_TOKEN: ${{ github.token }}

################
# Notification #
################

send_report:
name: Send Slack report
runs-on: ubuntu-latest
if: |
!cancelled() &&
github.event_name == 'push' &&
github.repository == 'WordPress/openverse' &&
(
((needs.get-changes.outputs.frontend == 'true' || needs.get-changes.outputs.documentation == 'true') && needs.emit-docs.result != 'success') ||
(needs.determine-images.outputs.do_publish == 'true' && needs.publish-images.result != 'success') ||
(needs.get-changes.outputs.frontend == 'true' && needs.deploy-frontend.result != 'success') ||
(needs.get-changes.outputs.api == 'true' && needs.deploy-api.result != 'success')
Comment on lines +806 to +809
Copy link
Member Author

@dhruvkb dhruvkb Mar 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workflow has the following objectives.

  • If the frontend or docs have changed, new docs must be published.
  • If there are any images to publish, the publish-images job should successfully publish them.
  • If the frontend or the API have changes, they should be deployed.

Each condition expects a successful outcome of a particular job and if not, the report will be sent.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means that if you see the report in Slack, something's not right and calls for an investigation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! This makes a lot of sense to me, thanks for digging into this 🙏 Having the get-changes explicitly next to each one also makes it easier to understand how the conditions work and the intention of other jobs too. Like the frontend one: are there frontend changes? If so, then these things should have run and been successful. If they weren't then something is wrong.

This is very clear, thank you, again!

)
needs: # the end products of the CI + CD workflow
- get-changes
- determine-images
- emit-docs
- publish-images
- deploy-frontend
- deploy-api

steps:
- name: Generate report
id: report
shell: python
env:
EMIT_DOCS_RESULT: ${{ needs.emit-docs.result }}
PUBLISH_IMAGES_RESULT: ${{ needs.publish-images.result }}
DEPLOY_FRONTEND_RESULT: ${{ needs.deploy-frontend.result }}
DEPLOY_API_RESULT: ${{ needs.deploy-api.result }}
SERVER_URL: ${{ github.server_url }}
REPOSITORY: ${{ github.repository }}
RUN_ID: ${{ github.run_id }}
run: |
import json
import os
import sys
from collections import defaultdict

server_url = os.environ.get("SERVER_URL")
repository = os.environ.get("REPOSITORY")
run_id = os.environ.get("RUN_ID")

jobs = ["emit-docs", "publish-images", "deploy-frontend", "deploy-api"]

results = {}
counts = defaultdict(lambda: 0)

for job_name in jobs:
result = os.environ.get(f"{job_name.replace('-', '_')}_result".upper())
results[job_name] = result
counts[result] += 1

payload = {
"text": ", ".join(f"{count} {result}" for result, count in counts.items()),
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": f"<{server_url}/{repository}/actions/runs/{run_id}|Click here to review the completed CI + CD workflow>.",
},
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": f"*{job_name}:*\n:workflow-{result}: {result}",
dhruvkb marked this conversation as resolved.
Show resolved Hide resolved
}
for job_name, result in results.items()
],
},
],
}

with open(os.environ.get("GITHUB_OUTPUT"), "a") as gh_out:
for dest in [sys.stdout, gh_out]:
print(f"payload={json.dumps(payload)}", file=dest)

- name: Send report
uses: slackapi/slack-github-action@v1.23.0
with:
payload: ${{ steps.report.outputs.payload }}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}