Release automation
Автоматизация GitHub Releases, changelog, semantic version tags, generated notes, assets, release-triggered workflows и защита релизного процесса.
Release automation
Release automation — это слой CD, который превращает «мы готовы выпустить версию» в воспроизводимый процесс: создать semver tag, собрать release notes, приложить assets, опубликовать GitHub Release и запустить следующие workflow. В отличие от Deployment workflows, здесь центр не сам deploy в staging или production, а выпуск версии как артефакта истории проекта.
GitHub Release основан на Git tag: tag указывает на конкретную точку в истории, а release добавляет к нему описание, assets, статус prerelease/latest и страницу для пользователей. Поэтому release automation лучше строить вокруг immutable входа: v1.8.0, v1.8.1, v2.0.0-rc.1, image digest или уже собранный artifact из Artifacts и reports. Если release workflow сам пересобирает всё заново без связи с CI, он легко отрывается от версии, которую реально проверяли.
flowchart TD A[Merge в main] --> B[CI: test и build] B --> C[Создать tag v1.8.0] C --> D[Release workflow] D --> E[Generate notes из PR и labels] D --> F[Загрузить assets] E --> G[Publish GitHub Release] F --> G G --> H[release: published] H --> I[Publish packages / deploy / notify]
flowchart TD A[Merge в main] --> B[CI: test и build] B --> C[Создать tag v1.8.0] C --> D[Release workflow] D --> E[Generate notes из PR и labels] D --> F[Загрузить assets] E --> G[Publish GitHub Release] F --> G G --> H[release: published] H --> I[Publish packages / deploy / notify]
Два нормальных паттерна
Первый паттерн — tag-driven release. Кто-то или отдельный workflow создаёт tag v*.*.*; release workflow стартует на push.tags, собирает release page и assets. Это хорошо для библиотек, CLI, desktop builds и container releases.
name: release
on:
push:
tags: ['v*.*.*']
permissions:
contents: write
jobs:
create-release:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Build distributable
run: |
npm ci
npm test
npm run build
tar -czf app-${GITHUB_REF_NAME}.tar.gz dist/
- name: Create GitHub Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release create "$GITHUB_REF_NAME" \
app-${GITHUB_REF_NAME}.tar.gz \
--title "$GITHUB_REF_NAME" \
--generate-notesКлючевые детали: contents: write нужен, потому что job создаёт release в репозитории; GH_TOKEN даёт gh доступ к GitHub API; GITHUB_REF_NAME на tag-trigger будет вроде v1.8.0. Такой workflow прост, но для серьёзного production лучше не пересобирать dist/ внутри release job, а скачать artifact, который уже прошёл CI.
Второй паттерн — release-published workflow. Команда вручную готовит draft release, прикладывает assets, проверяет notes и нажимает Publish. После этого отдельный workflow реагирует на release: published и делает действия после публикации: publish package, deploy docs, отправить уведомление, запустить promotion. Это естественно связано с Packages и container images.
name: after-release
on:
release:
types: [published]
permissions:
contents: read
packages: write
jobs:
publish-package:
runs-on: ubuntu-24.04
if: ${{ !github.event.release.prerelease }}
steps:
- uses: actions/checkout@v4
- run: ./scripts/publish-package.sh "$TAG"
env:
TAG: ${{ github.event.release.tag_name }}
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}release event имеет разные activity types: published, unpublished, created, edited, deleted, prereleased, released. На практике для автоматизации почти всегда безопаснее подписываться на published: GitHub отдельно предупреждает, что prereleased не сработает для prerelease, опубликованного из draft, а published сработает и для stable, и для prerelease. Если prerelease надо пропустить, добавьте if: ${{ !github.event.release.prerelease }}.
Generated notes и .github/release.yml
GitHub умеет генерировать release notes: список merged PR, contributors и ссылку на full changelog. Это не заменяет человеческий changelog для сложного продукта, но резко снижает ручную работу. Качество notes зависит от labels: если PR размечены как feature, bug, dependencies, documentation, output становится полезным; если labels случайные, release notes превращаются в шум.
Настройка живёт в .github/release.yml:
changelog:
exclude:
labels:
- ignore-for-release
authors:
- dependabot
categories:
- title: Features
labels:
- feature
- enhancement
- title: Fixes
labels:
- bug
- fix
- title: Dependencies
labels:
- dependencies
- title: Other changes
labels:
- '*'Эта конфигурация особенно хорошо работает вместе с Marketplace actions и pinning, Dependabot и conventional labels. Но не пытайтесь полностью делегировать смысл релиза автогенерации: breaking changes, migration notes, security fixes и known issues часто нужно писать явно.
Semantic version tags
Для большинства проектов достаточно SemVer-формы vMAJOR.MINOR.PATCH: v1.4.0 для backwards-compatible feature, v1.4.1 для bugfix, v2.0.0 для breaking change. Для prerelease используют формы вроде v2.0.0-rc.1. GitHub сам может определять latest release по semantic versioning, если вы не переопределяете это вручную.
У custom actions есть отдельная практика: кроме точного tag v1.4.2 поддерживают плавающие tags v1 и иногда v1.4, чтобы пользователи могли писать uses: owner/action@v1. Это удобно, но требует дисциплины. Если включены immutable releases, published release tag и assets нельзя менять; GitHub рекомендует для immutable release сначала создавать draft, прикладывать все assets и только потом публиковать. Для обычных приложений проще правило: release tag не двигать вообще. Ошиблись — выпускайте v1.4.3, а не переписывайте v1.4.2.
Assets: что прикладывать к release
Release assets — это файлы, которые пользователь или следующий workflow может скачать: binary, archive, checksum, SBOM, installer, generated docs. GitHub автоматически даёт source archive zip/tarball для tag, но это не то же самое, что собранный продукт. Если вы выпускаете CLI, приложите бинарники и checksum. Если container image — лучше писать digest в notes и публиковать image через Packages и container images, а не загружать Docker tarball без нужды.
Минимальный набор для CLI-релиза может выглядеть так:
gh release create "$TAG" \
"dist/mycli-linux-amd64" \
"dist/mycli-darwin-arm64" \
"dist/checksums.txt" \
--title "$TAG" \
--notes-file RELEASE_NOTES.mdЕсли важна supply chain integrity, смотрите в сторону immutable releases, provenance, checksum verification и минимальных Permissions и GITHUB_TOKEN. Immutable release защищает tag и assets от изменения после публикации; локальный asset можно проверять через gh release verify-asset.
Защита релизного процесса
Release workflow обычно имеет больше прав, чем CI: он пишет releases, packages, иногда деплоит. Поэтому его надо защищать как production path. Базовый набор: tag pattern v*.*.*, protected tags или rulesets, review перед созданием release, permissions на уровне job, pinning сторонних actions, concurrency для публикации и запрет на secrets в workflow, который выполняет untrusted code.
Не смешивайте release automation с pull_request_target. Релиз должен идти из доверенного ref: protected branch, protected tag или вручную опубликованный release. Всё, что работает с package tokens, cloud credentials или environment secrets, должно следовать той же логике, что Secure use и threat model и Environments и protection rules.
Частые ошибки
Первая ошибка — создавать release от каждого push в main. Это превращает release history в лог CI, а не в историю версий. Для каждого merge есть commit; release нужен там, где появляется версия для пользователей или downstream-систем.
Вторая — публиковать assets после release event в отдельном job, когда включена immutability. Если release становится immutable сразу после публикации, assets должны быть приложены до Publish, то есть через draft-first процесс.
Третья — считать generated notes changelog-ом продукта. Автогенерация хорошо собирает факты, но плохо объясняет последствия. Для breaking changes нужна ручная секция: что сломалось, кому надо мигрировать, какой минимальный безопасный путь обновления.
See also
- Deployment workflows — как release превращается в deploy, promotion или rollback.
- Environments и protection rules — approval, wait timers и environment secrets для deploy после релиза.
- Packages и container images — публикация npm, Maven, NuGet, PyPI, Docker и GitHub Packages.
- Permissions и GITHUB_TOKEN — минимальные права для jobs, которые создают releases и packages.
- Events и filters —
push.tags,release,workflow_dispatchи activity types. - Marketplace actions и pinning — как безопасно использовать сторонние release actions.
- Monitoring и troubleshooting — где смотреть release-triggered runs, logs и причины пропущенных events.
Внешние справки: GitHub Docs по about releases, managing releases, automatically generated release notes, release events, GITHUB_TOKEN, REST API releases и immutable releases.
Источники
- About releases - GitHub Docs
- Managing releases in a repository - GitHub Docs
- Automatically generated release notes - GitHub Docs
- Events that trigger workflows - GitHub Docs
- Use GITHUB_TOKEN for authentication in workflows - GitHub Docs
- REST API endpoints for releases - GitHub Docs
- Immutable releases - GitHub Docs
- Verifying the integrity of a release - GitHub Docs
- Releasing and maintaining actions - GitHub Docs
