Публикация Changelog на автопилоте: GitHub Commits → Telegram + WordPress

Когда часто выкатываешь новые фичи, нужно сообщать о них команде, пользователям и поисковикам. Последнее важно для SEO — Google учитывает, развивается продукт или заброшен.

Делать это вручную после каждого пуша — рутина, на которую быстро забиваешь. Я настроил автоматизацию: при деплое GitHub Actions отправляет уведомление в Telegram и создаёт пост-changelog на сайте.

Что получится

  • При пуше на продакшн автоматически отправляется сообщение в Telegram-канал
  • Создаётся пост в WordPress с категорией «changelog» на нужном языке
  • Можно пропустить уведомления, добавив [skip-public] в коммит

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

🏴 Обновление v1.30

— Добавлена авторизация через OAuth
— Исправлен баг с отображением меню
— Обновлены зависимости

Как устроен Git-репозиторий

В ветке main — продакшн-версия сайта. Есть другие ветки, в которых работаю я и другие разработчики. Настроен автодеплой: при пуше в main проект автоматически выкатывается на прод через GitHub Actions.

Именно сюда мы встроим автоматизацию. В тот же workflow добавим шаги, которые соберут все коммиты с последнего деплоя и отправят их в Telegram-канал и на сайт как пост.

Публикация Changelog на автопилоте: GitHub Commits → Telegram + WordPress

Шаг 1: Создаём Telegram-бота

Открываем @BotFather в Telegram и создаём бота командой /newbot. Получаем токен вида:

1234567890:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw

Создаём канал и добавляем бота как администратора. Чтобы получить Chat ID канала:

  1. Отправляем любое сообщение в канал
  2. Открываем в браузере: https://api.telegram.org/bot{TOKEN}/getUpdates
  3. В JSON-ответе ищем chat.id — это и есть Chat ID канала (начинается с минуса)

Пример ответа:

{
  "message": {
    "chat": {
      "id": -1001234567890,
      "title": "My Channel"
    }
  }
}

Chat ID канала: -1001234567890

Шаг 2: Настраиваем WordPress REST API

Для создания постов через API нужен Application Password:

  1. Админка WordPress → Пользователи → твой профиль
  2. Прокручиваем до «Application Passwords»
  3. Вводим название (например, «GitHub Actions») и нажимаем «Add New»
  4. Копируем сгенерированный пароль — он показывается один раз.

Шаг 3: Добавляем секреты в GitHub

В репозитории: Settings → Secrets and variables → Actions → New repository secret. Добавляем:

TELEGRAM_BOT_TOKEN    — токен бота
TELEGRAM_CHAT_ID      — ID канала (с минусом, например -1001234567890)
WP_USER               — логин администратора WordPress
WP_APP_PASSWORD       — Application Password
WP_SITE_URL           — адрес сайта (https://example.com)
Публикация Changelog на автопилоте: GitHub Commits → Telegram + WordPress

Шаг 4: Создаём файл версии

В корне репозитория создаём файл VERSION с базовой версией:

1.0

GitHub Actions автоматически добавит номер сборки: 1.42, 1.43 и т.д.

Шаг 5: GitHub Actions Workflow

Создаём файл .github/workflows/deploy.yml:

name: Deploy

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Нужно для git log

      - name: Generate version
        id: version
        run: |
          BASE_VERSION=$(cat VERSION)
          FULL_VERSION="${BASE_VERSION}.${{ github.run_number }}"
          echo "version=$FULL_VERSION" >> $GITHUB_OUTPUT

      - name: Send to Telegram
        if: ${{ !contains(github.event.head_commit.message, '[skip-public]') }}
        env:
          TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
          TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
        run: |
          COMMITS=$(git log --pretty=format:"— %s" ${{ github.event.before }}..${{ github.sha }} --no-merges)
          
          if [ -z "$COMMITS" ]; then
            echo "No commits to report"
            exit 0
          fi
          
          VERSION="${{ steps.version.outputs.version }}"
          MESSAGE=$(printf "🏴 Обновление v%s\n\n%s" "$VERSION" "$COMMITS")
          
          curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
            -d chat_id="${TELEGRAM_CHAT_ID}" \
            -d text="$MESSAGE"

      - name: Create changelog post
        if: ${{ !contains(github.event.head_commit.message, '[skip-public]') }}
        env:
          WP_USER: ${{ secrets.WP_USER }}
          WP_APP_PASSWORD: ${{ secrets.WP_APP_PASSWORD }}
          WP_SITE_URL: ${{ secrets.WP_SITE_URL }}
        run: |
          COMMITS=$(git log --pretty=format:"— %s" ${{ github.event.before }}..${{ github.sha }} --no-merges)
          
          if [ -z "$COMMITS" ]; then
            exit 0
          fi
          
          VERSION="${{ steps.version.outputs.version }}"
          TITLE="Обновление v${VERSION}"
          
          # Получаем или создаём категорию changelog
          CAT_ID=$(curl -s -u "${WP_USER}:${WP_APP_PASSWORD}" \
            "${WP_SITE_URL}/wp-json/wp/v2/categories?slug=changelog" | jq -r '.[0].id // empty')
          
          if [ -z "$CAT_ID" ]; then
            CAT_ID=$(curl -s -u "${WP_USER}:${WP_APP_PASSWORD}" \
              -X POST "${WP_SITE_URL}/wp-json/wp/v2/categories" \
              -H "Content-Type: application/json" \
              -d '{"name":"Changelog","slug":"changelog"}' | jq -r '.id')
          fi
          
          # Создаём пост
          curl -s -u "${WP_USER}:${WP_APP_PASSWORD}" \
            -X POST "${WP_SITE_URL}/wp-json/wp/v2/posts" \
            -H "Content-Type: application/json" \
            -d "$(jq -n \
              --arg title "$TITLE" \
              --arg content "$COMMITS" \
              --argjson categories "[$CAT_ID]" \
              '{title: $title, content: $content, status: "publish", categories: $categories}')"

Polylang: мультиязычность

Сайт моего продукта сделан на WordPress и он мультиязычный — для этого использую плагин Polylang Pro. Поэтому при создании поста нужно указать, на каком языке написаны коммиты.

Polylang добавляет поле lang в REST API. Передаём его в JSON-запросе:

curl -X POST ".../wp-json/wp/v2/posts" \
  -d '{
    "title": "Обновление v1.30",
    "content": "— коммит 1",
    "lang": "ru"
  }'

Слаг языка (ru, en) смотрим в админке: Languages → Languages → столбец Code.

В перспективе changelog можно автоматически переводить на все языки сайта с помощью нейросетей — но это уже тема для отдельной статьи.

Пропуск уведомлений

Иногда нужно запушить технические изменения без публичного уведомления. Добавляем [skip-public] в текст коммита:

git commit -m "Рефакторинг конфига [skip-public]"
git push origin main

GitHub Actions проверяет условие !contains(github.event.head_commit.message, '[skip-public]') и пропускает шаги отправки уведомлений.

Итого

Теперь каждый пуш в main автоматически:

  1. Генерирует версию из файла VERSION + номер сборки
  2. Собирает список коммитов через git log
  3. Отправляет красивое сообщение в Telegram
  4. Создаёт пост на сайте в категории changelog

Вся настройка занимает 15-20 минут, а экономит время на каждом релизе.

keyboard_arrow_up