Когда часто выкатываешь новые фичи, нужно сообщать о них команде, пользователям и поисковикам. Последнее важно для SEO — Google учитывает, развивается продукт или заброшен.
Делать это вручную после каждого пуша — рутина, на которую быстро забиваешь. Я настроил автоматизацию: при деплое GitHub Actions отправляет уведомление в Telegram и создаёт пост-changelog на сайте.
Что получится
- При пуше на продакшн автоматически отправляется сообщение в Telegram-канал
- Создаётся пост в WordPress с категорией «changelog» на нужном языке
- Можно пропустить уведомления, добавив
[skip-public]в коммит
Формат сообщений:
🏴 Обновление v1.30
— Добавлена авторизация через OAuth
— Исправлен баг с отображением меню
— Обновлены зависимости
Как устроен Git-репозиторий
В ветке main — продакшн-версия сайта. Есть другие ветки, в которых работаю я и другие разработчики. Настроен автодеплой: при пуше в main проект автоматически выкатывается на прод через GitHub Actions.
Именно сюда мы встроим автоматизацию. В тот же workflow добавим шаги, которые соберут все коммиты с последнего деплоя и отправят их в Telegram-канал и на сайт как пост.

Шаг 1: Создаём Telegram-бота
Открываем @BotFather в Telegram и создаём бота командой /newbot. Получаем токен вида:
1234567890:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw
Создаём канал и добавляем бота как администратора. Чтобы получить Chat ID канала:
- Отправляем любое сообщение в канал
- Открываем в браузере:
https://api.telegram.org/bot{TOKEN}/getUpdates - В JSON-ответе ищем
chat.id— это и есть Chat ID канала (начинается с минуса)
Пример ответа:
{
"message": {
"chat": {
"id": -1001234567890,
"title": "My Channel"
}
}
}
Chat ID канала: -1001234567890
Шаг 2: Настраиваем WordPress REST API
Для создания постов через API нужен Application Password:
- Админка WordPress → Пользователи → твой профиль
- Прокручиваем до «Application Passwords»
- Вводим название (например, «GitHub Actions») и нажимаем «Add New»
- Копируем сгенерированный пароль — он показывается один раз.
Шаг 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)

Шаг 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 автоматически:
- Генерирует версию из файла VERSION + номер сборки
- Собирает список коммитов через
git log - Отправляет красивое сообщение в Telegram
- Создаёт пост на сайте в категории changelog
Вся настройка занимает 15-20 минут, а экономит время на каждом релизе.
