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

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

`production`, `staging`, approvals, wait timers, deployment branch/tag restrictions, custom protection rules, environment secrets/vars и связь с deployment history.

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

Environments и protection rules

`production`, `staging`, approvals, wait timers, deployment branch/tag restrictions, custom protection rules, environment secrets/vars и связь с deployment history.

Environments и protection rules

Environment в GitHub Actions — это именованная цель деплоя: staging, production, preview, demo-eu, customer-a и так далее. В отличие от обычной переменной окружения, environment — это не строка для shell, а объект GitHub: у него есть protection rules, secrets, variables и история deployments. Когда job указывает environment, GitHub может остановить его перед выполнением деплойных steps, запросить approval, подождать wait timer, проверить branch/tag policy или спросить внешний GitHub App.

name: deploy

on:
  push:
    branches: [main]

jobs:
  deploy-production:
    runs-on: ubuntu-24.04
    environment:
      name: production
      url: https://example.com
    permissions:
      contents: read
      deployments: write
    steps:
      - uses: actions/checkout@v4
      - run: ./scripts/deploy.sh
        env:
          DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
          API_BASE_URL: ${{ vars.API_BASE_URL }}

Здесь production связывает job с настройками environment. url попадёт в deployment history и, для PR-сценариев, может появиться как ссылка «View deployment». Секрет DEPLOY_TOKEN и variable API_BASE_URL берутся именно из environment, если они там заведены. Это продолжение темы Variables, env и secrets, но с важным отличием: environment secrets становятся доступны job только после прохождения protection rules.

flowchart TD A[Workflow run дошёл до deploy job] --> B{Job ссылается на environment?} B -- нет --> C[Job выполняется как обычный job] B -- да --> D[GitHub создаёт deployment object] D --> E{Branch/tag разрешён?} E -- нет --> X[Deployment rejected / job не проходит gate] E -- да --> F{Есть wait timer?} F -- да --> G[Ожидание без billable runner time] F -- нет --> H{Нужен reviewer?} G --> H H -- да --> I[Pending: approve или reject] H -- нет --> J{Custom protection rule?} I -- approved --> J I -- rejected --> X J -- да --> K[GitHub App approve/reject] J -- нет --> L[Job получает environment secrets/vars] K -- approved --> L K -- rejected --> X L --> M[Deploy steps выполняются] M --> N[Deployment status и history обновляются]
flowchart TD
  A[Workflow run дошёл до deploy job] --> B{Job ссылается на environment?}
  B -- нет --> C[Job выполняется как обычный job]
  B -- да --> D[GitHub создаёт deployment object]
  D --> E{Branch/tag разрешён?}
  E -- нет --> X[Deployment rejected / job не проходит gate]
  E -- да --> F{Есть wait timer?}
  F -- да --> G[Ожидание без billable runner time]
  F -- нет --> H{Нужен reviewer?}
  G --> H
  H -- да --> I[Pending: approve или reject]
  H -- нет --> J{Custom protection rule?}
  I -- approved --> J
  I -- rejected --> X
  J -- да --> K[GitHub App approve/reject]
  J -- нет --> L[Job получает environment secrets/vars]
  K -- approved --> L
  K -- rejected --> X
  L --> M[Deploy steps выполняются]
  M --> N[Deployment status и history обновляются]
Порядок gate-проверок перед job, который ссылается на GitHub Actions environment.

Что именно защищает environment

Protection rules работают до того, как job, ссылающийся на environment, продолжит выполнение. Это не то же самое, что if: из Jobs, dependencies и conditions: if: решает, запускать job или step по данным workflow, а environment gate — это отдельная проверка GitHub на границе деплоя.

Основные встроенные rules:

  • Required reviewers — один из указанных пользователей или teams должен approve job. Можно запретить self-review, чтобы автор запуска не мог сам пропустить production.
  • Wait timer — задержка перед продолжением job. Диапазон в GitHub Docs: от 1 минуты до 43 200 минут, то есть 30 дней; это время не считается как billable runner time.
  • Deployment branches and tags — allowlist refs, которым разрешено деплоить в environment. Например, main для production, release/* для release branches или отдельные tag patterns.
  • Admin bypass policy — по умолчанию админы могут bypass protection rules, но для строгого production это можно запретить.
  • Custom deployment protection rules — GitHub App получает событие и approve/reject деплой на основании внешней системы: change management, observability, incident status, security gate.

Практичная модель такая: staging обычно защищают слабее, production — сильнее. Например, staging может принимать push из main без approval, но production требует reviewer, запрещает self-review, разрешает только tags v* или branch main, а ещё использует concurrency, чтобы два production-деплоя не шли одновременно. Последняя часть уже относится к Deployment workflows, но environment — место, где этот workflow получает организационный контроль.

Environment secrets и variables

Environment secrets удобны для credentials, которые отличаются по целям деплоя: STAGING_SSH_KEY, PRODUCTION_SSH_KEY, cloud role, webhook token, kubeconfig replacement. Но лучше не плодить имена вида PROD_TOKEN, STAGING_TOKEN на уровне repository secrets, если можно хранить один и тот же DEPLOY_TOKEN в разных environments. Workflow остаётся одинаковым, меняется только target.

jobs:
  deploy:
    runs-on: ubuntu-24.04
    environment: ${{ inputs.target }}
    steps:
      - run: ./deploy --target "$TARGET"
        env:
          TARGET: ${{ inputs.target }}
          DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
          PUBLIC_ORIGIN: ${{ vars.PUBLIC_ORIGIN }}

Environment variables читаются через vars, а не через env. Это хорошо подходит для несекретной конфигурации: PUBLIC_ORIGIN, REGION, SERVICE_NAME, SENTRY_ENVIRONMENT. Для секретов остаётся secrets. Правило безопасности из Permissions и GITHUB_TOKEN сохраняется: даже если environment gate настроен хорошо, permissions у job всё равно должны быть минимальными.

Важная тонкость: если workflow ссылается на environment, которого ещё нет, GitHub может создать environment с этим именем автоматически, но без настроенных protection rules и secrets. Для production лучше создать environment вручную в Settings → Environments или через API и заранее настроить политики. Имена environments не чувствительны к регистру, но в репозитории должны быть уникальны.

Branch/tag restrictions: не путать с event filters

Фильтры из Events и filters решают, запустится ли workflow вообще. Deployment branch/tag rule решает, может ли уже запущенный workflow деплоить в конкретный environment. Обычно нужны оба слоя.

on:
  push:
    branches: [main]
    tags: ['v*']
  workflow_dispatch:
    inputs:
      target:
        type: choice
        options: [staging, production]

jobs:
  deploy:
    runs-on: ubuntu-24.04
    environment: ${{ github.ref_type == 'tag' && 'production' || 'staging' }}
    steps:
      - run: ./deploy.sh

Если production environment разрешает только tags v*, случайный ручной запуск с feature branch не пройдёт production gate даже при ошибке в YAML. Это полезная страховка от человеческих и конфигурационных ошибок.

Deployments и история

Когда job ссылается на environment, GitHub создаёт deployment object и deployment status objects: environment name, состояние job, URL, связанный commit, PR/branch, workflow logs. Это превращает Actions из «набора логов» в историю доставок: что сейчас активно в production, какой commit был выкачен, откуда он пришёл и где смотреть логи.

Если job нужен только для доступа к environment secrets/vars, но не является настоящим деплоем, можно указать deployment: false:

jobs:
  smoke-with-prod-config:
    runs-on: ubuntu-24.04
    environment:
      name: production
      deployment: false
    steps:
      - run: ./scripts/smoke.sh
        env:
          API_TOKEN: ${{ secrets.READONLY_PROD_TOKEN }}

Это не создаёт deployment object, но job всё равно получает environment secrets и variables после прохождения правил. Ограничение: custom deployment protection rules не совместимы с deployment: false, потому что им нужен deployment flow, который они approve или reject.

ИнтерактивЖизненный цикл production gate#int-1
Шаг 1 из 51. Job выбирает environment
Workflow доходит до job с `environment: production`. С этого момента применяются правила именно environment `production`, а не просто условия YAML.
jobs:
  deploy:
    runs-on: ubuntu-24.04
    environment: production
Короткий walkthrough: что GitHub делает с deploy job, когда у environment есть protection rules.

Custom rules: когда approval должен быть машинным

Manual approval хорошо работает для маленькой команды, но плохо масштабируется, если production можно выпускать десятки раз в день. Custom deployment protection rule — это GitHub App, который подписывается на deployment protection rule event, получает payload, проверяет внешнее условие и отправляет approval или rejection обратно в GitHub.

Типичные внешние gates: нет активного инцидента в ServiceNow, error rate в Datadog ниже порога, canary в Honeycomb выглядит нормально, Sentry release health не просел, change request уже одобрен. Это не замена тестам из CI pipeline, а последний контекстный gate перед средой. Тесты отвечают «артефакт собран и проверен?», protection rule отвечает «сейчас можно катить именно сюда?».

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

Первая ошибка — считать environment просто способом хранить secrets. Тогда production secrets становятся доступны любому workflow, который умеет сослаться на production. Нужны reviewers, branch/tag restrictions и аккуратные permissions.

Вторая — требовать approval на каждом staging-деплое. В итоге команда начинает bypass rules или отключает gates. Для staging лучше автоматизировать, а ручную проверку оставить на production, regulated environments или опасные операции.

Третья — смешивать promotion и rebuild. Если production job заново собирает код после staging, история deployments говорит «в production ушёл commit X», но не гарантирует, что это тот же artifact. Обычно надёжнее собрать artifact в CI, проверить его, а потом передавать дальше через Artifacts и reports и deploy jobs.

See also

Внешние справки: GitHub Docs по deployment environments, managing environments, deploying to an environment, deployments and environments reference, reviewing deployments, custom protection rules, secure use и deployment history.

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

Почему environment: production в job GitHub Actions — это не просто переменная окружения для shell?

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

Это ссылка на объект GitHub environment: у него есть protection rules, secrets, variables и deployment history. GitHub может остановить job перед деплойными шагами и пропустить её только после нужных проверок.

Источники

  1. Managing environments for deployment - GitHub Docs
  2. Deployments and environments - GitHub Docs
  3. Reviewing deployments - GitHub Docs
  4. Deploying to a specific environment - GitHub Docs
  5. Secure use reference - GitHub Docs
  6. Creating custom deployment protection rules - GitHub Docs
  7. Viewing deployment history - GitHub Docs