Learn (Almost) Anything
КаталогСкачать курс

Автоматизация в GitHub

Автоматизация GitHub Releases, changelog, semantic version tags, generated notes, assets, release-triggered workflows и защита релизного процесса.

ruЭнциклопедия33 урока6 модулей9
GitHub actionsАвтоматизация в GitHubМодель workflowсостояние и артефактыматрицы и runtimeрелизы и environmentsПереиспользование и собственные actionsgovernance и эксплуатацияgithubactions

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]
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]
Типичный поток release automation: от проверенного commit до опубликованного релиза и downstream-действий.

Два нормальных паттерна

Первый паттерн — 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 без нужды.

Набор release assets показывает, что релиз обычно состоит не только из исходного архива, но и из готовых бинарников, checksums и SBOM.

Минимальный набор для 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.

ИнтерактивDraft-first release#int-1
Шаг 1 из 61. Проверить вход
Релиз стартует от доверенного ref: protected branch, protected tag или вручную выбранная версия. CI уже должен был проверить commit и собрать artifacts.
Короткий walkthrough процесса, который подходит для immutable releases и релизов с assets.

Частые ошибки

Первая ошибка — создавать 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

Внешние справки: GitHub Docs по about releases, managing releases, automatically generated release notes, release events, GITHUB_TOKEN, REST API releases и immutable releases.

Быстрое повторение #rc-1

Почему release automation лучше строить вокруг уже проверенного immutable входа: tag, image digest или CI artifact?

Показать ответ

Так release будет привязан к версии, которую реально проверяли. Если release job пересобирает всё заново без связи с CI, он может выпустить не тот артефакт, который проходил тесты.

Источники

  1. About releases - GitHub Docs
  2. Managing releases in a repository - GitHub Docs
  3. Automatically generated release notes - GitHub Docs
  4. Events that trigger workflows - GitHub Docs
  5. Use GITHUB_TOKEN for authentication in workflows - GitHub Docs
  6. REST API endpoints for releases - GitHub Docs
  7. Immutable releases - GitHub Docs
  8. Verifying the integrity of a release - GitHub Docs
  9. Releasing and maintaining actions - GitHub Docs