Saltar al contenido
mypipelines
Pipelines Actions Gradle Buscar
Shared (cross-cutting)· Reusable workflow ·on: workflow_call

Shared Slack Notify

Shared - Slack Notification

.github/workflows/shared-slack-notify.yml

.github/workflows/shared-slack-notify.yml
name: Shared - Slack Notification
on:
workflow_call:
inputs:
channel:
description: 'Slack channel name (without #)'
required: true
type: string
status:
description: 'Pipeline status: success, failure, cancelled, info'
required: false
type: string
default: 'info'
title:
description: 'Notification title (overrides auto-generated)'
required: false
type: string
default: ''
message:
description: 'Notification message body'
required: false
type: string
default: ''
environment:
description: 'Deployment environment (develop, staging, prod)'
required: false
type: string
default: ''
version:
description: 'Release version (e.g., 1.2.3)'
required: false
type: string
default: ''
changelog:
description: 'Release changelog (commit list)'
required: false
type: string
default: ''
mention_on_failure:
description: 'Slack mention on failure (e.g., @channel, @here)'
required: false
type: string
default: ''
pr_url:
description: 'Pull request URL (for PR notifications)'
required: false
type: string
default: ''
jobs:
notify:
name: Slack Notification
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Send Slack notification
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
CHANNEL: ${{ inputs.channel }}
STATUS: ${{ inputs.status }}
TITLE: ${{ inputs.title }}
MESSAGE: ${{ inputs.message }}
ENVIRONMENT: ${{ inputs.environment }}
VERSION: ${{ inputs.version }}
CHANGELOG: ${{ inputs.changelog }}
MENTION_ON_FAILURE: ${{ inputs.mention_on_failure }}
PR_URL: ${{ inputs.pr_url }}
REPO: ${{ github.repository }}
BRANCH: ${{ github.ref_name }}
ACTOR: ${{ github.actor }}
COMMIT_AUTHOR: ${{ github.event.head_commit.author.name || github.event.pull_request.user.login || github.actor }}
SERVER_URL: ${{ github.server_url }}
RUN_ID: ${{ github.run_id }}
run: |
set -euo pipefail
if [ -z "$SLACK_WEBHOOK_URL" ]; then
echo "::warning::SLACK_WEBHOOK_URL secret is not set, skipping notification"
exit 0
fi
# Status emoji and color
case "$STATUS" in
success) EMOJI="✅"; COLOR="#36a64f" ;;
failure) EMOJI="❌"; COLOR="#E01E5A" ;;
cancelled) EMOJI="⚠️"; COLOR="#ECB22E" ;;
*) EMOJI="ℹ️"; COLOR="#1264A3" ;;
esac
# Auto-generate title if not provided
if [ -z "$TITLE" ]; then
if [ -n "$VERSION" ]; then
TITLE="Release v${VERSION} — ${REPO##*/}"
else
TITLE="Pipeline ${STATUS} — ${REPO##*/}"
fi
fi
HEADER="${EMOJI} ${TITLE}"
# Build blocks array
BLOCKS=$(jq -n --arg header "$HEADER" \
'[{"type":"header","text":{"type":"plain_text","text":$header,"emoji":true}}]')
# Info fields
BLOCKS=$(echo "$BLOCKS" | jq \
--arg repo "<${SERVER_URL}/${REPO}|${REPO}>" \
--arg branch "\`${BRANCH}\`" \
--arg env "${ENVIRONMENT:-N/A}" \
--arg actor "$ACTOR" \
--arg author "$COMMIT_AUTHOR" \
'. += [{"type":"section","fields":[
{"type":"mrkdwn","text":("*Repository:*\n" + $repo)},
{"type":"mrkdwn","text":("*Branch:*\n" + $branch)},
{"type":"mrkdwn","text":("*Environment:*\n" + $env)},
{"type":"mrkdwn","text":("*Triggered by:*\n" + $actor)},
{"type":"mrkdwn","text":("*Commit author:*\n" + $author)}
]}]')
# Custom message
if [ -n "$MESSAGE" ]; then
BLOCKS=$(echo "$BLOCKS" | jq --arg msg "$MESSAGE" \
'. += [{"type":"section","text":{"type":"mrkdwn","text":$msg}}]')
fi
# Changelog
if [ -n "$VERSION" ] && [ -n "$CHANGELOG" ]; then
BLOCKS=$(echo "$BLOCKS" | jq --arg cl "*Changelog:*\n${CHANGELOG}" \
'. += [{"type":"section","text":{"type":"mrkdwn","text":$cl}}]')
fi
# PR link
if [ -n "$PR_URL" ]; then
BLOCKS=$(echo "$BLOCKS" | jq --arg pr "📋 *Pull Request:* <${PR_URL}|View PR>" \
'. += [{"type":"section","text":{"type":"mrkdwn","text":$pr}}]')
fi
# Mention on failure
if [ "$STATUS" = "failure" ] && [ -n "$MENTION_ON_FAILURE" ]; then
BLOCKS=$(echo "$BLOCKS" | jq --arg m "<!${MENTION_ON_FAILURE#@}> Pipeline failed — attention needed" \
'. += [{"type":"section","text":{"type":"mrkdwn","text":$m}}]')
fi
# View Run button
BLOCKS=$(echo "$BLOCKS" | jq --arg url "${SERVER_URL}/${REPO}/actions/runs/${RUN_ID}" \
'. += [{"type":"actions","elements":[{"type":"button","text":{"type":"plain_text","text":"View Run"},"url":$url}]}]')
# Build payload — channel field honored only by legacy incoming-webhook integrations
if [ -n "$CHANNEL" ]; then
PAYLOAD=$(jq -n \
--arg channel "$CHANNEL" \
--argjson blocks "$BLOCKS" \
--arg color "$COLOR" \
--arg text "$HEADER" \
'{channel: $channel, text: $text, blocks: $blocks, attachments: [{color: $color, blocks: []}]}')
else
PAYLOAD=$(jq -n \
--argjson blocks "$BLOCKS" \
--arg color "$COLOR" \
--arg text "$HEADER" \
'{text: $text, blocks: $blocks, attachments: [{color: $color, blocks: []}]}')
fi
# Send via Slack Incoming Webhook
HTTP_CODE=$(curl -s -o /tmp/slack_response.txt -w "%{http_code}" \
-X POST -H "Content-Type: application/json" \
-d "$PAYLOAD" "$SLACK_WEBHOOK_URL")
if [ "$HTTP_CODE" -eq 200 ]; then
echo "Slack notification sent (channel hint: #${CHANNEL:-default})"
else
echo "::warning::Slack notification failed (HTTP $HTTP_CODE)"
cat /tmp/slack_response.txt
fi