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
65 changes: 65 additions & 0 deletions .github/actions/notify-deploy/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Rich, best-effort Slack deploy/rollback notification.
# Canonical source in shared-workflows; synced into consumer repos as a local action.
# All presentation lives in message.json — a Block Kit template you can paste into
# app.slack.com/block-kit-builder. This action just wires inputs into env vars that the
# template reads (payload-templated substitutes + escapes them). Best-effort: never fails the job.
name: Notify deploy
description: Post a rich deployment/rollback status message to Slack. Best-effort — never fails the job.

inputs:
slack-webhook:
description: Slack incoming webhook URL. If empty, the notification is skipped.
required: true
status:
description: "Job status: success | failure | cancelled (callers pass job.status)."
required: true
environment:
description: Deploy target environment (e.g. staging, production).
required: true
title:
description: Action noun shown in the header (Deploy | Rollback).
required: false
default: Deploy
version:
description: Component version/ref for the Version field. Defaults to the short commit sha.
required: false
default: ""
sha:
description: The commit actually deployed. Defaults to the workflow sha; pass the resolved sha for promotions.
required: false
default: ${{ github.sha }}
service-url:
description: Live service URL for the "Open <environment>" button. Defaults to the GitHub deployments page.
required: false
default: ""
changes-url:
description: Diff/compare URL for the "Changes" button. Defaults to the deployed commit.
required: false
default: ""
summary:
description: Extra mrkdwn appended under the header (e.g. a rollback worker/version table). Multi-line is safe.
required: false
default: ""

runs:
using: composite
steps:
- name: Notify Slack
if: ${{ inputs.slack-webhook != '' }}
continue-on-error: true
uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3
env:
SLACK_STATUS: ${{ inputs.status }}
SLACK_TITLE: ${{ inputs.title }}
SLACK_ENV: ${{ inputs.environment }}
SLACK_VERSION: ${{ inputs.version }}
SLACK_SHA: ${{ inputs.sha }}
SLACK_SERVICE_URL: ${{ inputs.service-url }}
SLACK_CHANGES_URL: ${{ inputs.changes-url }}
SLACK_SUMMARY: ${{ inputs.summary }}
with:
webhook: ${{ inputs.slack-webhook }}
webhook-type: incoming-webhook
errors: "false"
payload-file-path: ${{ github.action_path }}/message.json
payload-templated: true
33 changes: 33 additions & 0 deletions .github/actions/notify-deploy/message.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"text": "{{env.SLACK_TITLE}} {{env.SLACK_STATUS}}: {{env.GITHUB_REPOSITORY}} ({{env.SLACK_ENV}})",
"attachments": [
{
"color": "{{if env.SLACK_STATUS|equals>success}}#2eb67d{{else}}{{if env.SLACK_STATUS|equals>failure}}#e01e5a{{else}}#667085{{/if}}{{/if}}",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "{{if env.SLACK_STATUS|equals>success}}✅{{else}}{{if env.SLACK_STATUS|equals>failure}}❌{{else}}⚪{{/if}}{{/if}} `{{env.GITHUB_REPOSITORY}}` · *{{env.SLACK_TITLE}} {{if env.SLACK_STATUS|equals>success}}succeeded{{else}}{{if env.SLACK_STATUS|equals>failure}}failed{{else}}{{env.SLACK_STATUS}}{{/if}}{{/if}}* · {{env.SLACK_ENV}}{{if env.SLACK_SUMMARY|notempty}}\n{{env.SLACK_SUMMARY}}{{/if}}"
}
},
{
"type": "section",
"fields": [
{ "type": "mrkdwn", "text": "*Commit:*\n<{{env.GITHUB_SERVER_URL}}/{{env.GITHUB_REPOSITORY}}/commit/{{env.SLACK_SHA}}|`{{env.SLACK_SHA|limit>7}}`>" },
{ "type": "mrkdwn", "text": "*Triggered by:*\n<{{env.GITHUB_SERVER_URL}}/{{env.GITHUB_ACTOR}}|@{{env.GITHUB_ACTOR}}>" },
{ "type": "mrkdwn", "text": "*Version:*\n`{{if env.SLACK_VERSION|notempty}}{{env.SLACK_VERSION}}{{else}}{{env.SLACK_SHA|limit>7}}{{/if}}`" }
]
},
{
"type": "actions",
"elements": [
{ "type": "button", "text": { "type": "plain_text", "text": "CI run" }, "url": "{{env.GITHUB_SERVER_URL}}/{{env.GITHUB_REPOSITORY}}/actions/runs/{{env.GITHUB_RUN_ID}}" },
{ "type": "button", "text": { "type": "plain_text", "text": "Changes" }, "url": "{{if env.SLACK_CHANGES_URL|notempty}}{{env.SLACK_CHANGES_URL}}{{else}}{{env.GITHUB_SERVER_URL}}/{{env.GITHUB_REPOSITORY}}/commit/{{env.SLACK_SHA}}{{/if}}" },
{ "type": "button", "text": { "type": "plain_text", "text": "Open {{env.SLACK_ENV}}" }, "url": "{{if env.SLACK_SERVICE_URL|notempty}}{{env.SLACK_SERVICE_URL}}{{else}}{{env.GITHUB_SERVER_URL}}/{{env.GITHUB_REPOSITORY}}/deployments/{{env.SLACK_ENV}}{{/if}}", "style": "primary" }
]
}
]
}
]
}
9 changes: 9 additions & 0 deletions .github/workflows/deploy-production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,12 @@ jobs:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: pages deploy dist --project-name ${{ vars.CLOUDFLARE_PAGES_PROJECT }} --branch=main

- name: Notify Slack
if: always()
uses: ./.github/actions/notify-deploy
with:
slack-webhook: ${{ secrets.SLACK_DEPLOY_WEBHOOK }}
status: ${{ job.status }}
environment: production
sha: ${{ steps.resolve.outputs.sha }}
8 changes: 8 additions & 0 deletions .github/workflows/deploy-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,11 @@ jobs:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: pages deploy dist --project-name ${{ vars.CLOUDFLARE_PAGES_PROJECT }} --branch=main

- name: Notify Slack
if: always()
uses: ./.github/actions/notify-deploy
with:
slack-webhook: ${{ secrets.SLACK_DEPLOY_WEBHOOK }}
status: ${{ job.status }}
environment: staging