Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Живое ревью с ИИ
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. Уведомления и алерты
notifications_alerts

Уведомления и алерты

Настройка уведомлений в Slack, Telegram, email, интеграция с incident management.

Уведомления и алерты

Оперативное информирование команды о статусе деплоя критически важно для быстрого реагирования на инциденты. Изучите настройку уведомлений в Slack, Telegram, Discord, email и интеграцию с PagerDuty.

#Slack уведомления

#Incoming Webhooks

Slack Incoming Webhooks — простейший способ отправлять сообщения из CI/CD.

Настройка:

  1. Создайте app в Slack API
  2. Добавьте Incoming Webhooks feature
  3. Activate и создайте webhook для канала
  4. Сохраните URL в secrets
name: Deploy with Slack Notifications on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest environment: production steps: - uses: actions/checkout@v4 - name: Deploy run: ./deploy.sh env: DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }} - name: Notify Slack on Success if: success() run: | curl -X POST $SLACK_WEBHOOK \ -H "Content-Type: application/json" \ -d '{ "text": "✅ Deploy successful", "attachments": [{ "color": "good", "fields": [ {"title": "Repository", "value": "${{ github.repository }}", "short": true}, {"title": "Commit", "value": "${{ github.sha }}", "short": true}, {"title": "Environment", "value": "Production", "short": true}, {"title": "Deployed by", "value": "${{ github.actor }}", "short": true} ] }] }' env: SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} - name: Notify Slack on Failure if: failure() run: | curl -X POST $SLACK_WEBHOOK \ -H "Content-Type: application/json" \ -d '{ "text": "❌ Deploy failed", "attachments": [{ "color": "danger", "fields": [ {"title": "Repository", "value": "${{ github.repository }}", "short": true}, {"title": "Commit", "value": "${{ github.sha }}", "short": true}, {"title": "Error", "value": "Check workflow logs for details", "short": false} ], "actions": [{ "type": "button", "text": "View Logs", "url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" }] }] }' env: SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}

#Slack Block Kit

Block Kit предоставляет больше контроля над форматированием.

- name: Notify with Blocks run: | curl -X POST $SLACK_WEBHOOK \ -H "Content-Type: application/json" \ -d '{ "blocks": [ { "type": "header", "text": { "type": "plain_text", "text": "🚀 Deployment Complete", "emoji": true } }, { "type": "section", "fields": [ {"type": "mrkdwn", "text": "*Repository:*\n${{ github.repository }}"}, {"type": "mrkdwn", "text": "*Commit:*\n`${{ github.sha }}`"}, {"type": "mrkdwn", "text": "*Environment:*\nProduction"}, {"type": "mrkdwn", "text": "*Status:*\n✅ Success"} ] }, { "type": "actions", "elements": [ { "type": "button", "text": {"type": "plain_text", "text": "View Deployment"}, "url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" }, { "type": "button", "text": {"type": "plain_text", "text": "Rollback"}, "url": "${{ github.server_url }}/${{ github.repository }}/actions/new?workflow=rollback" } ] } ] }' env: SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}

#Threading для группировки

- name: Send Initial Notification id: notify_start run: | RESPONSE=$(curl -s -X POST $SLACK_WEBHOOK \ -H "Content-Type: application/json" \ -d "{\"text\": \"🔄 Deployment started...\"}") # Extract thread_ts from response if using chat.postMessage echo "thread_ts=$(echo $RESPONSE | jq -r '.ts')" >> $GITHUB_OUTPUT env: SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} - name: Send Completion Update if: always() run: | curl -X POST $SLACK_WEBHOOK \ -H "Content-Type: application/json" \ -d "{ \"thread_ts\": \"$THREAD_TS\", \"text\": \"✅ Deployment completed successfully\" }" env: SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} THREAD_TS: ${{ steps.notify_start.outputs.thread_ts }}

#Telegram уведомления

#Bot API

Telegram Bot API позволяет отправлять сообщения через HTTP requests.

Настройка бота:

  1. Создайте бота через @BotFather
  2. Получите токен бота
  3. Добавьте бота в канал/чат
  4. Узнайте chat_id (через @getmyid_bot или API)
- name: Notify Telegram if: always() run: | STATUS="${{ job.status }}" if [ "$STATUS" = "success" ]; then EMOJI="✅" COLOR="green" elif [ "$STATUS" = "failure" ]; then EMOJI="❌" COLOR="red" else EMOJI="⚠️" COLOR="yellow" fi MESSAGE="*${EMOJI} Deploy ${STATUS}* *Repository:* \`${{ github.repository }}\` *Branch:* \`${{ github.ref_name }}\` *Commit:* \`${{ github.sha }}\` *Environment:* Production *Deployed by:* ${{ github.actor }} [View Workflow](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})" curl -X POST "https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage" \ -H "Content-Type: application/json" \ -d "{ \"chat_id\": \"${TG_CHAT_ID}\", \"text\": \"${MESSAGE}\", \"parse_mode\": \"Markdown\", \"disable_web_page_preview\": true }" env: TG_BOT_TOKEN: ${{ secrets.TG_BOT_TOKEN }} TG_CHAT_ID: ${{ secrets.TG_CHAT_ID }}

#Форматирование сообщений

Telegram поддерживает Markdown и HTML:

- name: Telegram with HTML run: | curl -X POST "https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage" \ -H "Content-Type: application/json" \ -d "{ \"chat_id\": \"${TG_CHAT_ID}\", \"text\": \"<b>🚀 Deploy Complete</b> <i>Repository:</i> ${{ github.repository }} <i>Commit:</i> <code>${{ github.sha }}</code> <i>Status:</i> <b>Success</b>\", \"parse_mode\": \"HTML\" }" env: TG_BOT_TOKEN: ${{ secrets.TG_BOT_TOKEN }} TG_CHAT_ID: ${{ secrets.TG_CHAT_ID }}

#Discord уведомления

#Webhook с embeds

Discord webhooks поддерживают богатые embed сообщения.

- name: Notify Discord if: always() run: | STATUS="${{ job.status }}" if [ "$STATUS" = "success" ]; then COLOR=3066993 # Green TITLE="✅ Deploy Successful" else COLOR=15158332 # Red TITLE="❌ Deploy Failed" fi curl -X POST $DISCORD_WEBHOOK \ -H "Content-Type: application/json" \ -d "{ \"embeds\": [{ \"title\": \"${TITLE}\", \"color\": ${COLOR}, \"fields\": [ {\"name\": \"Repository\", \"value\": \"${{ github.repository }}\", \"inline\": true}, {\"name\": \"Commit\", \"value\": \"\`${{ github.sha }}\`\", \"inline\": true}, {\"name\": \"Environment\", \"value\": \"Production\", \"inline\": true}, {\"name\": \"Deployed by\", \"value\": \"${{ github.actor }}\", \"inline\": true} ], \"footer\": { \"text\": \"GitHub Actions\", \"icon_url\": \"https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png" }, \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\" }] }" env: DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}

#Multiple embeds

- name: Discord with Multiple Embeds run: | curl -X POST $DISCORD_WEBHOOK \ -H "Content-Type: application/json" \ -d "{ \"embeds\": [ { \"title\": \"🚀 Deployment Summary\", \"color\": 3066993, \"description\": \"Production deployment completed successfully\", \"fields\": [ {\"name\": \"Duration\", \"value\": \"5m 32s\", \"inline\": true}, {\"name\": \"Services\", \"value\": \"3\", \"inline\": true} ] }, { \"title\": \"📊 Health Check Results\", \"color\": 3447003, \"fields\": [ {\"name\": \"API\", \"value\": \"✅ Healthy\", \"inline\": true}, {\"name\": \"Database\", \"value\": \"✅ Connected\", \"inline\": true}, {\"name\": \"Cache\", \"value\": \"✅ Operational\", \"inline\": true} ] } ] }" env: DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}

#Email уведомления

#GitLab встроенные notifications

GitLab CI поддерживает встроенные email уведомления:

# .gitlab-ci.yml stages: - build - deploy deploy_production: stage: deploy environment: production script: - ./deploy.sh rules: - if: $CI_COMMIT_BRANCH == "main" notifications: on_success: change on_failure: always recipients: - team@example.com - oncall@example.com

#SMTP через Python

- name: Send Email via SMTP if: failure() run: | python3 - <<EOF import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart import os msg = MIMEMultipart() msg['From'] = os.environ['SMTP_FROM'] msg['To'] = os.environ['SMTP_TO'] msg['Subject'] = f"❌ Deploy Failed - ${{os.environ['CI_PROJECT_NAME']}}" body = f""" Deployment failed in production. Project: ${{os.environ['CI_PROJECT_NAME']}} Branch: ${{os.environ['CI_COMMIT_BRANCH']}} Commit: ${{os.environ['CI_COMMIT_SHA']}} Pipeline: ${{os.environ['CI_PIPELINE_URL']}} Please investigate immediately. """ msg.attach(MIMEText(body, 'plain')) server = smtplib.SMTP(os.environ['SMTP_HOST'], int(os.environ['SMTP_PORT'])) server.starttls() server.login(os.environ['SMTP_USER'], os.environ['SMTP_PASSWORD']) server.send_message(msg) server.quit() print("Email sent successfully") EOF env: SMTP_HOST: ${{ secrets.SMTP_HOST }} SMTP_PORT: ${{ secrets.SMTP_PORT }} SMTP_USER: ${{ secrets.SMTP_USER }} SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD }} SMTP_FROM: noreply@example.com SMTP_TO: team@example.com

#SendGrid API

- name: Send Email via SendGrid if: failure() run: | curl -X POST "https://api.sendgrid.com/v3/mail/send" \ -H "Authorization: Bearer $SENDGRID_API_KEY" \ -H "Content-Type: application/json" \ -d "{ \"personalizations\": [{ \"to\": [{\"email\": \"team@example.com\"}], \"subject\": \"❌ Deploy Failed - ${{ github.repository }}\" }], \"from\": {\"email\": \"noreply@example.com\"}, \"content\": [{ \"type\": \"text/html\", \"value\": \"<h1>Deployment Failed</h1> <p><strong>Repository:</strong> ${{ github.repository }}</p> <p><strong>Commit:</strong> <code>${{ github.sha }}</code></p> <p><a href='${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}'>View Logs</a></p>\" }] }" env: SENDGRID_API_KEY: ${{ secrets.SENDGRID_API_KEY }}

#PagerDuty интеграция

#Events API v2

PagerDuty Events API создаёт incidents с автоматической эскалацией.

- name: Notify PagerDuty on Critical Failure if: failure() && github.ref == 'refs/heads/main' run: | curl -X POST "https://events.pagerduty.com/v2/enqueue" \ -H "Content-Type: application/json" \ -d "{ \"routing_key\": \"$PAGERDUTY_ROUTING_KEY\", \"event_action\": \"trigger\", \"payload\": { \"summary\": \"Production deployment failed - ${{ github.repository }}\", \"severity\": \"critical\", \"source\": \"github-actions\", \"component\": \"deploy-pipeline\", \"group\": \"platform-team\", \"class\": \"deployment\", \"custom_details\": { \"repository\": \"${{ github.repository }}\", \"commit\": \"${{ github.sha }}\", \"branch\": \"${{ github.ref_name }}\", \"workflow\": \"${{ github.workflow }}\", \"run_url\": \"${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\" } }, \"dedup_key\": \"deploy-${{ github.repository }}-${{ github.sha }}\" }" env: PAGERDUTY_ROUTING_KEY: ${{ secrets.PAGERDUTY_ROUTING_KEY }}

#Auto-resolve при успешном redeploy

- name: Resolve PagerDuty Incident if: success() && github.ref == 'refs/heads/main' run: | curl -X POST "https://events.pagerduty.com/v2/enqueue" \ -H "Content-Type: application/json" \ -d "{ \"routing_key\": \"$PAGERDUTY_ROUTING_KEY\", \"event_action\": \"resolve\", \"dedup_key\": \"deploy-${{ github.repository }}-${{ github.sha }}\" }" env: PAGERDUTY_ROUTING_KEY: ${{ secrets.PAGERDUTY_ROUTING_KEY }}

#Incident Management Workflow

#Автоматическое создание Jira задачи

- name: Create Post-Mortem Jira Issue if: failure() && github.ref == 'refs/heads/main' run: | curl -X POST "https://api.atlassian.com/ex/jira/${JIRA_CLOUD_ID}/rest/api/3/issue" \ -H "Authorization: Bearer $JIRA_API_TOKEN" \ -H "Content-Type: application/json" \ -d "{ \"fields\": { \"project\": {\"key\": \"INC\"}, \"summary\": \"[Post-Mortem] Production Deploy Failure - ${{ github.repository }}\", \"description\": { \"type\": \"doc\", \"version\": 1, \"content\": [ { \"type\": \"paragraph\", \"content\": [{\"type\": \"text\", \"text\": \"Deployment failed in production. Please complete post-mortem analysis.\"}] }, { \"type\": \"bulletList\", \"content\": [ {\"type\": \"listItem\", \"content\": [{\"type\": \"paragraph\", \"content\": [{\"type\": \"text\", \"text\": \"Repository: ${{ github.repository }}\"}]}]}, {\"type\": \"listItem\", \"content\": [{\"type\": \"paragraph\", \"content\": [{\"type\": \"text\", \"text\": \"Commit: ${{ github.sha }}\"}]}]}, {\"type\": \"listItem\", \"content\": [{\"type\": \"paragraph\", \"content\": [{\"type\": \"text\", \"text\": \"Time: $(date -u +%Y-%m-%dT%H:%M:%SZ)\"}]}]} ] } ] }, \"issuetype\": {\"name\": \"Incident\"}, \"priority\": {\"name\": \"Highest\"}, \"labels\": [\"post-mortem\", \"production\", \"deploy-failure\"] } }" env: JIRA_CLOUD_ID: ${{ secrets.JIRA_CLOUD_ID }} JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}

#Дедупликация уведомлений

- name: Check for Duplicate Alert id: dedup run: | ALERT_HASH=$(echo -n "${{ github.repository }}-${{ github.sha }}-failure" | sha256sum | cut -d' ' -f1) # Check Redis for existing alert EXISTS=$(curl -s "https://api.upstash.io/redis/${UPSTASH_REDIS_REST_URL}/get/${ALERT_HASH}" \ -H "Authorization: Bearer ${UPSTASH_REDIS_REST_TOKEN}" | jq -r '.result') if [ "$EXISTS" = "null" ]; then echo "should_notify=true" >> $GITHUB_OUTPUT # Set with 1 hour TTL curl -s "https://api.upstash.io/redis/${UPSTASH_REDIS_REST_URL}/set/${ALERT_HASH}/notified/EX/3600" \ -H "Authorization: Bearer ${UPSTASH_REDIS_REST_TOKEN}" else echo "Duplicate alert suppressed" echo "should_notify=false" >> $GITHUB_OUTPUT fi env: UPSTASH_REDIS_REST_URL: ${{ secrets.UPSTASH_REDIS_REST_URL }} UPSTASH_REDIS_REST_TOKEN: ${{ secrets.UPSTASH_REDIS_REST_TOKEN }} - name: Notify on Unique Failure if: steps.dedup.outputs.should_notify == 'true' run: | # Send notification only if not duplicate curl -X POST $SLACK_WEBHOOK \ -H "Content-Type: application/json" \ -d "{\"text\": \"❌ Deploy failed (unique alert)\"}" env: SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}

#Multi-Channel Notifications

#Разные каналы для разных окружений

- name: Select Channel by Environment run: | case "${{ github.environment }}" in production) WEBHOOK=$SLACK_WEBHOOK_PROD CHANNEL="#deploy-prod" ;; staging) WEBHOOK=$SLACK_WEBHOOK_STAGING CHANNEL="#deploy-staging" ;; development) WEBHOOK=$SLACK_WEBHOOK_DEV CHANNEL="#deploy-dev" ;; *) WEBHOOK=$SLACK_WEBHOOK_DEFAULT CHANNEL="#deploy-all" ;; esac echo "webhook=$WEBHOOK" >> $GITHUB_OUTPUT echo "channel=$CHANNEL" >> $GITHUB_OUTPUT id: channel - name: Send Notification run: | curl -X POST ${{ steps.channel.outputs.webhook }} \ -H "Content-Type: application/json" \ -d "{ \"text\": \"Deploy to ${{ github.environment }} completed\", \"channel\": \"${{ steps.channel.outputs.channel }}\" }" env: SLACK_WEBHOOK_PROD: ${{ secrets.SLACK_WEBHOOK_PROD }} SLACK_WEBHOOK_STAGING: ${{ secrets.SLACK_WEBHOOK_STAGING }} SLACK_WEBHOOK_DEV: ${{ secrets.SLACK_WEBHOOK_DEV }}

Далее: Интеграции