# Каналы релизов {#release-channels}

Сервер Tuist и сервер кэша Kura поставляются через три канала образов GHCR с разными гарантиями стабильности. Рекомендуемая установка — **stable**, обновления выходят раз в неделю: версия не меняется при каждом слиянии функции в `main`, поэтому обновление больше не означает получение пакета несвязанных изменений. Ранние пользователи по-прежнему могут запускать сборки для каждого коммита на канале **canary**, а канал **release candidate** позволяет предварительно протестировать будущую ветку до её перехода в стабильную.

И сервер, и Kura следуют одному еженедельному графику и выпускаются синхронно с [графиком релизов Tuist CLI](/en/cli/release-channels).

## Каналы {#the-channels}

| Канал | Формат версии | Частота | Обновляет `:latest`? |
| --- | --- | --- | --- |
| Canary | `X.Y.0-canary.N` (например, `1.351.0-canary.5`) | Каждый коммит в `main` | Нет, требуется явное согласие |
| Release candidate | `X.Y.0-rc.N` (например, `1.351.0-rc.1`) | Отделение от `main` каждый понедельник, тестирование ~1 неделю | Нет, требуется явное согласие |
| Stable | `X.Y.Z` (например, `1.350.2`, `1.351.0`) | Повышается каждый понедельник после успешного тестирования | **Да** |

Сборки Canary и release-candidate публикуются как предварительные релизы GitHub. Любой инструмент, исключающий предварительные релизы при разрешении `:latest`, будет их пропускать, поэтому вы попадёте на один из них только при явном запросе.

### Canary {#canary}

Каждый коммит в `main` публикует образ canary. Canary всегда представляет **следующую невыпущенную минорную версию**: как только ветка отделяется для релиза, `main` переходит к следующей минорной версии (например, с `1.350.0-canary.42` на `1.351.0-canary.1`). Canary — правильный канал для staging-среды, которая зеркально отражает production и даёт самый ранний сигнал о регрессиях, или для проверки того, что исправление, которое вы сообщили, работает как ожидается, прежде чем оно попадёт в stable.

```
ghcr.io/tuist/tuist:1.351.0-canary.5
ghcr.io/tuist/kura:0.55.0-canary.5
```

### Release candidate {#release-candidate}

Когда минорная версия готова к выпуску, её ветка замораживается на защищённой ветке `releases/server-<major>.<minor>.x` (или `releases/kura-<major>.<minor>.x`) и публикуется как `X.Y.0-rc.1`. Ветка заморожена по функциям; в неё включаются только критические исправления и исправления регрессий, и каждое принятое исправление увеличивает номер release candidate (`-rc.2`, `-rc.3` и так далее). После успешного завершения периода тестирования ветка повышается до stable в следующий понедельник.

```
ghcr.io/tuist/tuist:1.351.0-rc.1
ghcr.io/tuist/kura:0.55.0-rc.1
```

### Stable {#stable}

Stable — рекомендуемый канал, на который ссылается вся документация. Стабильная минорная версия (`X.Y.0`) публикуется только после успешного тестирования release candidate и **не** обновляется при слиянии новых функций в `main`. Патчи (`X.Y.1`, `X.Y.2` и так далее) в стабильной ветке содержат только обратно портированные исправления, никогда — новые функции. `:latest` обновляется только при повышении до stable.

```
ghcr.io/tuist/tuist:1.351.0
ghcr.io/tuist/kura:0.55.0
ghcr.io/tuist/tuist:latest
ghcr.io/tuist/kura:latest
```

## Понедельничный поезд {#the-monday-train}

Каждый понедельник в 06:00 UTC релизные поезда трёх компонентов запускаются синхронно:

1. **06:00 UTC** — запускаются задачи повышения. Каждая повышает новейшую ветку release-candidate, которая ещё не стала stable (обычно это ветка, отделённая в предыдущий понедельник), и ничего не делает, если таких нет.
2. **После завершения каждого повышения** — задача release-candidate отделяет следующую ветку от `main`, поэтому свежеотделённая ветка никогда не повышается в том же запуске.

Неудачное повышение задерживает отделение: выбирается только самая высокая ветка release-candidate выше последней stable, поэтому отделение следующей ветки поверх неудачи оставило бы непоставленную ветку без внимания. В следующий понедельник задержанная ветка автоматически повторяется.

## Закрепление канала {#pinning-a-channel}

Закрепите нужный тег в манифесте развёртывания, значениях Helm или файле Docker Compose. Пример с использованием Helm-чарта:

```yaml
server:
  image:
    repository: ghcr.io/tuist/tuist
    tag: "1.350.2"          # Pinned to a stable patch
    # tag: "1.351.0-rc.1"   # Or opt into a release candidate to soak it
    # tag: "1.351.0-canary.5" # Or opt into a specific canary build

kuraRuntime:
  image:
    repository: ghcr.io/tuist/kura
    tag: "0.54.0"           # Same three channels apply to Kura
```

`:latest` для обоих `ghcr.io/tuist/tuist` и `ghcr.io/tuist/kura` отслеживает новейшую stable, обновляемую только при понедельничном повышении. Закрепление `:latest` даёт вам еженедельный стабильный ритм без необходимости обновлять тег; закрепление конкретной версии даёт полный контроль над тем, когда вы обновляетесь.

## Рекомендуемая стратегия {#recommended-strategy}

Каналы существуют, чтобы вы могли разделить «получение новейших исправлений» и «получение новейших функций». Безопасный вариант с минимальными усилиями:

1. **Закрепите production на стабильной минорной ветке**, например `ghcr.io/tuist/tuist:1.351`. Эта ветка получает только обратно портированные исправления, никогда — новые функции, поэтому ежедневные обновления остаются низкорисковыми. Обновляйте закрепление, когда будете готовы перейти на следующую минорную версию.
2. **Запустите staging-среду на canary или на конкретном теге release-candidate.** Staging перехватывает регрессии, которые иначе достигли бы ваших пользователей, и чем ближе staging отслеживает `main`, тем раньше вы их находите. Staging-среда на текущей ветке release-candidate — хороший компромисс: она тестирует именно те байты, которые станут stable в следующий понедельник.
3. **Следите за [журналом изменений Server](/changelog), чтобы узнать, что действительно было выпущено.** Каждое повышение до stable анонсируется там со списком pull request’ов, которые вошли в релиз.

Если вы хотите, чтобы новые функции автоматически попадали в production по мере их стабилизации, оставьте production на `:latest`. Имейте в виду, что тег обновляется еженедельно в понедельник утром, поэтому планируйте окно развёртывания соответствующим образом.

## Обратное портирование {#backports}

В любой момент активно поддерживаются две стабильные ветки Server (и Kura): текущая ветка получает регрессии и исправления безопасности через запросы на обратное портирование, а предыдущая — только критические исправления и исправления безопасности. Более старые ветки не получают обратного портирования; обновитесь до поддерживаемой ветки, чтобы получать исправления. Когда новая ветка повышается до stable, текущая ветка становится «предыдущей», а ветка, которая была «предыдущей», перестаёт получать обратное портирование.

Обратное портирование выпускается по требованию как патч-релизы `X.Y.(Z+1)`. Они никогда не сдвигают `:latest`.
