Módulo 3: Deployment Automation
7. Notificaciones de despliegue
Qué cubre esta cápsula
Tu pipeline corre tests, buildea imagen, aplica migrations, deploya, y verifica health. Cuando termina, alguien tiene que saberlo. Hoy el "alguien" eres tú — vas a GitHub Actions, ves el ✅ o ❌, y lo comunicas manualmente al equipo en Slack. "Hey, deployé la feature X" o "Ojo, el deploy a prod falló".
Esta cápsula automatiza esa comunicación con webhooks a Slack o Discord. Cuando el deploy termina, un mensaje aparece automáticamente en el canal del equipo: success o failure, el commit y autor, la versión deployada, link al run. Cero intervención humana. Cero "¿alguien deployó algo?" en Slack.
Al terminar, podrás:
- Configurar un Slack webhook o Discord webhook para notificaciones del deploy
- Implementar notificaciones diferentes para success vs failure
- Incluir contexto útil: commit SHA, mensaje, autor, link al PR, link al run
- Manejar notificaciones cuando el job falla (no solo cuando "success")
- Decidir qué notificar y qué silenciar — evita spam
- Diagnosticar webhooks que no llegan o se ven mal
El problema: comunicación manual del deploy
Sin notificaciones automáticas:
[GitHub Actions: deploy successful]
↓
Tú: vas al canal #deploys en Slack
"Hey equipo, deployé v1.2.3 a producción ✅"
↓
Compañera A: "Gracias"
Compañera B: "¿Qué incluye?"
Tú: "Ah, dejame buscar el PR..."
[5 minutos buscando el link]
Tú: "Acá: github.com/repo/pull/42"
↓
[20 minutos después, deploy a prod automático en CI por otro PR]
[Nadie se entera porque tú te fuiste a almorzar]
[2 horas después]
Compañera C: "¿Alguien sabe si deploydeon? La feature X ya está en prod?"
Lo que falta es un patrón: que la comunicación del deploy sea automática, consistente, y con todo el contexto que el equipo necesita.
El modelo mental: el pipeline como bot del equipo
Piensa el pipeline como un bot que postea en Slack/Discord automáticamente:
[Pipeline termina]
↓
¿Success o failure?
/ \
✅ ❌
│ │
▼ ▼
[Mensaje Slack] [Mensaje Slack]
"🚀 Deploy v1.2.3" "🚨 Deploy FAILED"
"Author: alice" "Author: bob"
"Commit: abc1234" "Commit: xyz9876"
"PR: #42" "PR: #43"
"Run: actions/..." "Run: actions/..."
"Time: 3m 24s" "Step failed: migration"
"App: deploy.url" "Logs: see run"
El equipo entero está sincronizado en tiempo real con producción, sin que nadie tenga que recordar postear.
Step 1: configurar Slack webhook
Si tu equipo usa Slack:
-
Crear app de Slack:
- Ir a api.slack.com/apps
- Click Create New App → From scratch
- Nombre: "GitHub Deploy Notifications"
- Workspace: el de tu equipo
-
Activar Incoming Webhooks:
- En la app → Features → Incoming Webhooks → toggle On
- Click Add New Webhook to Workspace
- Elige el canal:
#deploys(recomendado crear uno dedicado) - Autoriza
-
Copiar el webhook URL:
- Formato:
https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX - Este URL es secreto: cualquiera con él puede postear al canal
- Formato:
-
Agregar a GitHub Secrets:
- GitHub → Settings → Secrets → New repository secret
- Name:
SLACK_WEBHOOK_URL - Value: el URL copiado
Step 1 alternativo: configurar Discord webhook
Si tu equipo usa Discord:
-
En tu server de Discord:
- Click derecho en el canal
#deploys→ Edit Channel - Integrations → Webhooks → New Webhook
- Nombre: "Deploy Bot"
- Click Copy Webhook URL
- Click derecho en el canal
-
Formato del URL:
https://discord.com/api/webhooks/000000000000000000/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-
Agregar a GitHub Secrets:
- Name:
DISCORD_WEBHOOK_URL - Value: el URL copiado
- Name:
Step 2: notificación de success al final del deploy
Agrega al final del job deploy:
- name: Notify Slack on success
if: success()
run: |
curl -X POST -H 'Content-type: application/json' \
--data '{
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "🚀 Deploy Successful"
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Repository:*\n${{ github.repository }}"
},
{
"type": "mrkdwn",
"text": "*Branch:*\n${{ github.ref_name }}"
},
{
"type": "mrkdwn",
"text": "*Author:*\n${{ github.actor }}"
},
{
"type": "mrkdwn",
"text": "*Commit:*\n<${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}>"
}
]
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Message:* ${{ github.event.head_commit.message }}"
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": { "type": "plain_text", "text": "View App" },
"url": "${{ vars.DEPLOY_URL }}"
},
{
"type": "button",
"text": { "type": "plain_text", "text": "View Run" },
"url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}
]
}
]
}' \
${{ secrets.SLACK_WEBHOOK_URL }}
Esto envía un mensaje rico con:
- Header destacando "Deploy Successful"
- Bloque con fields (repo, branch, author, commit SHA con link)
- Mensaje del commit
- Botones para ir a la app o al run
En Slack se ve así:
🚀 Deploy Successful
Repository: Branch:
mikenieva/myapp main
Author: Commit:
mikenieva abc1234 [link]
Message: feat: add user profile endpoint
[ View App ] [ View Run ]
Click en "View App" abre tu producción. Click en "View Run" abre el run de GitHub Actions.
Step 3: notificación de failure
El problema con if: success() es que solo notifica cuando todo pasó. ¿Qué pasa si el deploy falla? Nadie se entera.
Agrega una notificación separada para failure:
- name: Notify Slack on failure
if: failure()
run: |
curl -X POST -H 'Content-type: application/json' \
--data '{
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "🚨 Deploy FAILED"
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Repository:*\n${{ github.repository }}"
},
{
"type": "mrkdwn",
"text": "*Author:*\n${{ github.actor }}"
},
{
"type": "mrkdwn",
"text": "*Commit:*\n<${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}>"
},
{
"type": "mrkdwn",
"text": "*Failed Job:*\n${{ github.job }}"
}
]
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": ":warning: Investigate immediately. App may be in inconsistent state."
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": { "type": "plain_text", "text": "View Failed Run" },
"url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}",
"style": "danger"
}
]
}
]
}' \
${{ secrets.SLACK_WEBHOOK_URL }}
Diferencias:
if: failure(): corre solo cuando el job falló (en cualquier step previo)- Header rojo "Deploy FAILED"
- Warning explícito: "Investigate immediately"
- Botón danger style: visualmente distinto, en rojo
En Slack aparece destacado, imposible de ignorar.
Step 4: notificación a Discord (alternativa)
Si usas Discord, el formato JSON es distinto:
- name: Notify Discord on success
if: success()
run: |
curl -X POST -H "Content-Type: application/json" \
--data '{
"embeds": [{
"title": "🚀 Deploy Successful",
"color": 3066993,
"fields": [
{"name": "Repository", "value": "${{ github.repository }}", "inline": true},
{"name": "Branch", "value": "${{ github.ref_name }}", "inline": true},
{"name": "Author", "value": "${{ github.actor }}", "inline": true},
{"name": "Commit", "value": "[${{ github.sha }}](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})", "inline": false},
{"name": "Message", "value": "${{ github.event.head_commit.message }}", "inline": false}
],
"footer": {
"text": "Click for details"
},
"url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}",
"timestamp": "${{ github.event.head_commit.timestamp }}"
}]
}' \
${{ secrets.DISCORD_WEBHOOK_URL }}
Discord usa "embeds" con color hex (3066993 = verde, 15158332 = rojo).
Manejo de comillas y caracteres especiales
Un problema sutil: los commit messages pueden contener ", \, \n, emojis. Esto rompe el JSON.
Ejemplo problemático:
# commit message: feat: add "premium" filter
# JSON resultante:
"text": "*Message:* feat: add "premium" filter"
^ rompe el JSON
Solución 1: usar jq para escapar correctamente
- name: Build Slack payload
id: payload
run: |
MESSAGE=$(echo "${{ github.event.head_commit.message }}" | head -1)
PAYLOAD=$(jq -n \
--arg message "$MESSAGE" \
--arg sha "${{ github.sha }}" \
--arg author "${{ github.actor }}" \
'{
text: "Deploy Successful",
blocks: [{
type: "section",
text: { type: "mrkdwn", text: "*Message:* \($message)" }
}, {
type: "section",
text: { type: "mrkdwn", text: "*Author:* \($author)\n*Commit:* \($sha)" }
}]
}')
echo "payload<<EOF" >> $GITHUB_OUTPUT
echo "$PAYLOAD" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Send Slack notification
run: |
curl -X POST -H 'Content-type: application/json' \
--data '${{ steps.payload.outputs.payload }}' \
${{ secrets.SLACK_WEBHOOK_URL }}
jq escapa automáticamente comillas, backslashes, y caracteres especiales.
Solución 2: usar action de tercero
- name: Slack notification
uses: slackapi/slack-github-action@v1
with:
payload: |
{
"text": "Deploy successful",
"blocks": [...]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
La action maneja escaping automáticamente.
Workflow completo con notificaciones
deploy:
name: Deploy
runs-on: ubuntu-latest
needs: build-and-push
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: pip install -e ".[dev]"
- name: Run migrations
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
run: alembic upgrade head
- name: Redeploy Railway
env:
RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
run: |
npm install -g @railway/cli
railway redeploy --service ${{ secrets.RAILWAY_SERVICE_ID }}
- name: Health check
run: |
DEPLOY_URL="${{ vars.DEPLOY_URL }}"
for i in $(seq 1 24); do
CODE=$(curl -s -o /dev/null -w "%{http_code}" "$DEPLOY_URL/health" || echo "000")
[ "$CODE" = "200" ] && exit 0
sleep 5
done
exit 1
# ─── Notifications ───
- name: Notify Slack on success
if: success()
uses: slackapi/slack-github-action@v1
with:
payload: |
{
"blocks": [
{
"type": "header",
"text": {"type": "plain_text", "text": "🚀 Deploy Successful"}
},
{
"type": "section",
"fields": [
{"type": "mrkdwn", "text": "*Repo:*\n${{ github.repository }}"},
{"type": "mrkdwn", "text": "*Author:*\n${{ github.actor }}"},
{"type": "mrkdwn", "text": "*Branch:*\n${{ github.ref_name }}"},
{"type": "mrkdwn", "text": "*Commit:*\n<${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}>"}
]
},
{
"type": "actions",
"elements": [
{"type": "button", "text": {"type": "plain_text", "text": "View App"}, "url": "${{ vars.DEPLOY_URL }}"},
{"type": "button", "text": {"type": "plain_text", "text": "View Run"}, "url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"}
]
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
- name: Notify Slack on failure
if: failure()
uses: slackapi/slack-github-action@v1
with:
payload: |
{
"blocks": [
{
"type": "header",
"text": {"type": "plain_text", "text": "🚨 Deploy FAILED"}
},
{
"type": "section",
"text": {"type": "mrkdwn", "text": ":warning: *Author:* ${{ github.actor }}\n*Commit:* <${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}>\n*Failed step:* check the run"}
},
{
"type": "actions",
"elements": [
{"type": "button", "text": {"type": "plain_text", "text": "View Failed Run"}, "url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}", "style": "danger"}
]
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
Qué notificar y qué silenciar
Tentas de notificar todo: cada PR, cada CI run, cada deploy. Resultado: el canal se vuelve ruido. El equipo aprende a ignorarlo.
Qué notificar (señal alta):
- ✅ Deploy a producción exitoso (lo que estamos haciendo)
- ❌ Deploy a producción fallido
- ❌ CI failure en main (alguien rompió main)
- ⚠️ Migration que tarda inusualmente (>5 min)
- 🔄 Rollback ejecutado
Qué NO notificar (ruido):
- ❌ Cada CI run de feature branches (mucho ruido)
- ❌ Cada PR abierto (ya hay otro canal para PRs)
- ❌ Cada commit individual a feature branches
Regla: notifica eventos que el equipo necesita actuar sobre ellos o que representan cambios al estado de producción. Todo lo demás es ruido.
Canales separados por severidad
Equipo maduro usa múltiples canales:
#deploys → cada deploy a prod (success + failure)
#alerts → solo failures + incidents
#ci-failures-main → cuando main rompe (CI rojo en main)
#deploy-archive (silent) → audit log de todos los deploys (no notifications)
Cada canal tiene un webhook distinto. En GitHub Secrets:
SLACK_WEBHOOK_DEPLOYSSLACK_WEBHOOK_ALERTSSLACK_WEBHOOK_ARCHIVE
El workflow usa el correcto según contexto:
- name: Notify alerts on failure
if: failure()
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_ALERTS }} # canal de alerts
run: ...
- name: Notify deploys always
if: always()
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_DEPLOYS }} # canal de deploys
run: ...
Trampas comunes
1. Webhook URL leaked en el output
Síntoma: alguien ve el webhook URL en logs de Actions y lo usa para postear spam.
Causa: el URL aparece en algún log step (e.g., echo $SLACK_WEBHOOK_URL).
Cómo manejar: GitHub Secrets se enmascaran automáticamente en logs (***), pero solo si los referencias exactamente. Si construyes variantes (substring), no se enmascaran:
# ✅ Bien: GitHub enmascara $SLACK_WEBHOOK_URL en logs
- run: curl ... ${{ secrets.SLACK_WEBHOOK_URL }}
# ❌ Mal: substring de un secret no se enmascara
- run: echo "Webhook starts with: ${SLACK_WEBHOOK_URL:0:20}"
Nunca printees secrets, ni siquiera substrings.
2. Notificación en cada PR ruidoso
Síntoma: el canal #deploys recibe 50 mensajes/día porque notifica cada CI run.
Causa: el step de notificación no tiene if: github.ref == 'refs/heads/main' o el job no es solo de deploy.
Cómo manejar: notificaciones solo en deploys (job deploy), que ya tiene if: github.event_name == 'push' && github.ref == 'refs/heads/main'. CI runs en PRs no notifican.
3. JSON inválido por caracteres especiales
Síntoma: webhook retorna 400 Bad Request: invalid_payload.
Causa: comillas, backslashes, o newlines en commit messages rompen el JSON.
Cómo manejar: usar slackapi/slack-github-action (que maneja escaping) o jq para construir el JSON.
4. Notificación llega pero se ve fea
Síntoma: el mensaje aparece como JSON crudo o sin formato.
Causa: usaste el formato simple {"text": "..."} en lugar de bloques.
Cómo manejar: usar Block Kit Builder de Slack (app.slack.com/block-kit-builder) para diseñar visualmente y generar el JSON.
5. No notificar a Slack cuando Slack tiene outage
Síntoma: tu workflow falla porque Slack API está caída.
Causa: el step de notificación retorna error y el job falla aunque el deploy fue exitoso.
Cómo manejar: agrega continue-on-error: true a los steps de notificación:
- name: Notify Slack
continue-on-error: true # falla del webhook no rompe el workflow
if: success()
run: ...
El deploy es lo importante; la notificación es opcional.
Caso desarrollado: el deploy fallido detectado por el equipo
Sin notificaciones:
14:30 — Bob mergea PR #43 a main
14:32 — CI corre, deploy job falla en health check
14:32 — GitHub Actions muestra ❌
14:35 — Bob se va a almorzar (no ve el error)
15:00 — Usuarios reportan errores en producción
15:15 — Alice investiga, encuentra que el deploy falló
15:30 — Alice intenta rollback, pero el código viejo y nuevo están mezclados
16:00 — Resuelven, pero 1.5 horas de prod degradada
Con notificaciones:
14:30 — Bob mergea PR #43 a main
14:32 — CI corre, deploy job falla en health check
14:32 — Slack notification: "🚨 Deploy FAILED - Bob's commit abc1234"
14:33 — Alice ve la notificación, click en "View Failed Run"
14:35 — Alice identifica: missing env var STRIPE_KEY
14:36 — Alice configura la env var en Railway
14:38 — Alice triggea redeploy manual
14:40 — ✅ Slack: "🚀 Deploy Successful"
10 minutos vs 90 minutos. Diferencia entre "issue contenida" vs "incident".
Ejercicio: integra notificaciones en tu pipeline
- Elige Slack o Discord según el stack de tu equipo.
- Crear webhook según las instrucciones de Step 1.
- Agregar
SLACK_WEBHOOK_URLoDISCORD_WEBHOOK_URLa GitHub Secrets. - Agregar steps de notificación success y failure al job
deploy. - Push de prueba (un commit trivial) → verificar que llega notificación de success.
- Romper intencionalmente algo (e.g., cambiar
DATABASE_URLa algo inválido) → verificar que llega notificación de failure. - Revertir el cambio → verificar notificación success de nuevo.
Solución: workflow con notifications completas (Slack)
deploy:
name: Deploy
runs-on: ubuntu-latest
needs: build-and-push
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: '3.12' }
- run: pip install -e ".[dev]"
- name: Migrations
env: { DATABASE_URL: '${{ secrets.DATABASE_URL }}' }
run: alembic upgrade head
- name: Redeploy
env: { RAILWAY_TOKEN: '${{ secrets.RAILWAY_TOKEN }}' }
run: |
npm install -g @railway/cli
railway redeploy --service ${{ secrets.RAILWAY_SERVICE_ID }}
- name: Health check
run: |
DEPLOY_URL="${{ vars.DEPLOY_URL }}"
for i in $(seq 1 24); do
CODE=$(curl -s -o /dev/null -w "%{http_code}" "$DEPLOY_URL/health" || echo "000")
[ "$CODE" = "200" ] && exit 0
sleep 5
done
exit 1
- name: Notify success
if: success()
continue-on-error: true
uses: slackapi/slack-github-action@v1
with:
payload: |
{
"blocks": [
{"type": "header", "text": {"type": "plain_text", "text": "🚀 Deploy Successful"}},
{"type": "section", "fields": [
{"type": "mrkdwn", "text": "*Repo:* ${{ github.repository }}"},
{"type": "mrkdwn", "text": "*Author:* ${{ github.actor }}"},
{"type": "mrkdwn", "text": "*Commit:* <${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}>"},
{"type": "mrkdwn", "text": "*Branch:* ${{ github.ref_name }}"}
]},
{"type": "actions", "elements": [
{"type": "button", "text": {"type": "plain_text", "text": "View App"}, "url": "${{ vars.DEPLOY_URL }}"},
{"type": "button", "text": {"type": "plain_text", "text": "View Run"}, "url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"}
]}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
- name: Notify failure
if: failure()
continue-on-error: true
uses: slackapi/slack-github-action@v1
with:
payload: |
{
"blocks": [
{"type": "header", "text": {"type": "plain_text", "text": "🚨 Deploy FAILED"}},
{"type": "section", "text": {"type": "mrkdwn", "text": ":warning: *Author:* ${{ github.actor }}\n*Commit:* <${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}>\n*Investigate immediately*"}},
{"type": "actions", "elements": [
{"type": "button", "style": "danger", "text": {"type": "plain_text", "text": "View Failed Run"}, "url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"}
]}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
Auto-verificación
1. ¿Por qué continue-on-error: true en los steps de notificación?
Razón: separar la prioridad del deploy de la prioridad de la notificación.
Sin continue-on-error: true:
1. Migrations ✅
2. Deploy ✅
3. Health check ✅
4. Notify Slack ❌ (Slack tiene outage)
5. Job marked: FAILED
Resultado: tu deploy fue exitoso, pero el job aparece como failed.
Con continue-on-error: true:
1. Migrations ✅
2. Deploy ✅
3. Health check ✅
4. Notify Slack ⚠️ (Slack outage, pero continúa)
5. Job marked: SUCCESS (con warning en el step de notify)
Resultado: deploy real exitoso, status correcto, solo pierdes la notificación.
La notificación es comunicación, no parte del deploy. Si Slack está caído, perdiste un canal de comunicación — pero tu producción funciona. El estado del job debe reflejar el deploy real, no la salud de Slack.
2. Tu canal #deploys tiene 200 mensajes por día. El equipo lo ignora. ¿Cómo lo arreglas?
Diagnóstico: hay demasiado ruido. Pasos para reducir:
1. Identificar fuentes de ruido. Mira los últimos 50 mensajes del canal y categoriza:
- ¿Cuántos son deploys reales? (esperas 1-5/día en equipo activo)
- ¿Cuántos son CI failures de PRs? (debería ser 0 acá)
- ¿Cuántos son notificaciones de otros bots? (renovate, dependabot)
2. Separar canales por severidad:
#deploys-prod: solo deploys a producción success + failure. Pocos mensajes (1-10/día).#deploys-staging: deploys a staging. Más mensajes pero menos críticos.#alerts: solo failures que requieren acción inmediata.
Cada canal tiene su webhook. El workflow notifica al correcto según contexto.
3. Silenciar lo no-actionable:
- Renovate/Dependabot a un canal aparte (
#dependencies) - CI failures de feature branches a un canal aparte (
#ci-feature-branches) o a ningún canal - Solo notifica en
#deploys-prodlo que el equipo necesita actuar sobre
4. Threading por deploy:
Slack soporta threads. La primera notificación es el mensaje top-level; updates (build started, migration done, deploy done) van en thread. El canal ve 1 mensaje por deploy, no 5.
5. Filtros del cliente:
Slack permite que cada usuario configure notificaciones por keyword. Si el equipo ya no presta atención al canal, puedes sugerir que cada uno configure "notify me when 'FAILED' is mentioned in #deploys-prod" — así reciben notificaciones solo de failures.
Goal: que el canal de deploys tenga señal alta — cuando aparece algo, el equipo presta atención.
Resumen y siguiente paso
- Notificaciones automáticas eliminan el "¿alguien deployó?" del equipo
- Slack y Discord webhooks son la forma estándar — configuración en 5 min
- Notifica success Y failure (failure es más crítico)
- Incluye contexto útil: commit SHA con link, author, branch, mensaje
- Usar
if: success()yif: failure()para mensajes distintos continue-on-error: truepara que outage de Slack no rompa tu deploy- Separar canales por severidad evita ruido —
#deploys≠#alerts
Puente al próximo paso: Tu pipeline ahora hace todo: CI gate, build, migrations, deploy, health check, notificación. Falta consolidarlo en el proyecto integrador del módulo. En la cápsula 08 vas a unir todas las piezas en el Auto-Deploy Pipeline: el pipeline completo end-to-end, con experiencia del ciclo PR → CI → merge → CD → app live → notification. Es la pieza que va a tu portfolio demostrando dominio de CI/CD profesional.
Recursos
- Slack Block Kit Builder — diseña mensajes visualmente.
- Incoming Webhooks for Slack — docs oficiales.
- Discord Webhook docs — referencia.
- slackapi/slack-github-action — action oficial de Slack para GHA.
- GitHub Actions context — variables disponibles (
github.actor,github.sha, etc.).
Cápsula 07 de 08 — Módulo 3 — CI/CD for Python Backend Guide