fix(release): the second branch is 'beta', not 'pre-release' — was never checkoutable

scripts/gha.ps1's -Branch ValidateSet accepted 'pre-release' and would
`git checkout pre-release` to promote alpha, but no such branch has ever
existed in this repo — only `beta` does (confirmed: `git branch -a`, and
the existing 0.4.6-beta/0.4.7-beta release history was cut from `beta`).
The very first beta release under the new gha.ps1 versioning scheme would
have failed outright on the checkout step.

This naming mismatch had spread through the whole release surface:
  - scripts/gha.ps1: -Branch ValidateSet + all internal checks
  - .github/workflows/release.yml: a dead branch-name check (harmless only
    because the workflow currently triggers on tag-push, not branch-push)
    plus two comments
  - CONTRIBUTING.md / .ru.md: branch-strategy table documented a
    `pre-release` branch that doesn't exist
  - README.md / .ru.md and ostp/src/main.rs: the `ostp update -b <name>`
    CLI help text/docs
  - scripts/install.sh: the channel match the CLI flag feeds into

Renamed all of it to `beta` to match the branch that actually exists.
Left scripts/gha.ps1:21's "semver pre-release identifier" alone — that's
the generic semver spec term, unrelated to the branch name, and got
reverted after a blanket replace briefly clobbered it.

Note: install.sh's alpha/beta self-update paths still assume a rolling
GitHub release tagged literally "alpha"/"beta" exists, which no gha.ps1
release ever publishes (only versioned tags like v0.4.7-beta.3) - that's
a separate, real bug, tracked apart from this rename since fixing it needs
either a floating tag from gha.ps1 or an API-query rewrite of install.sh.
This commit is contained in:
ospab 2026-07-12 02:12:57 +03:00
parent 2660a37249
commit 1c291d9c88
8 changed files with 25 additions and 25 deletions

View File

@ -4,7 +4,7 @@ name: CI/CD
# `run-name` is evaluated at workflow-start, BEFORE any job runs - it cannot # `run-name` is evaluated at workflow-start, BEFORE any job runs - it cannot
# see resolve-channel's computed tag_name (e.g. "0.4.3-alpha"), only the # see resolve-channel's computed tag_name (e.g. "0.4.3-alpha"), only the
# `github.*` context. The old "release version ${{ github.ref_name }}" showed # `github.*` context. The old "release version ${{ github.ref_name }}" showed
# the bare branch name ("alpha"/"pre-release") for every run, which reads # the bare branch name ("alpha"/"beta") for every run, which reads
# exactly like a literal release tag and caused real confusion - the actual # exactly like a literal release tag and caused real confusion - the actual
# release tag has been correct (versioned) all along; only this label lied # release tag has been correct (versioned) all along; only this label lied
# about it. Spell out "channel" so nobody mistakes one for the other again. # about it. Spell out "channel" so nobody mistakes one for the other again.
@ -53,7 +53,7 @@ jobs:
# Tag shape: # Tag shape:
# - real "vX.Y.Z" / "vX.Y.Z-beta.N" tag push -> tag used as-is (stable promotion) # - real "vX.Y.Z" / "vX.Y.Z-beta.N" tag push -> tag used as-is (stable promotion)
# - push to `alpha` -> "{version}-alpha" (rolling, same tag every push) # - push to `alpha` -> "{version}-alpha" (rolling, same tag every push)
# - push to `pre-release` -> "{version}-beta" (rolling, same tag every push) # - push to `beta` -> "{version}-beta" (rolling, same tag every push)
# - workflow_dispatch -> forced by the `channel` input (alpha|beta only) # - workflow_dispatch -> forced by the `channel` input (alpha|beta only)
resolve-channel: resolve-channel:
name: Resolve release channel name: Resolve release channel
@ -89,7 +89,7 @@ jobs:
# channel, then synthesize the rolling tag from Cargo.toml's version. # channel, then synthesize the rolling tag from Cargo.toml's version.
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
CHANNEL="${{ github.event.inputs.channel }}" CHANNEL="${{ github.event.inputs.channel }}"
elif [ "${{ github.ref_name }}" = "pre-release" ]; then elif [ "${{ github.ref_name }}" = "beta" ]; then
CHANNEL="beta" CHANNEL="beta"
else else
CHANNEL="alpha" CHANNEL="alpha"

View File

@ -74,10 +74,10 @@ The repository runs three long-lived branches, in increasing order of stability:
| Branch | Role | | Branch | Role |
|---|---| |---|---|
| `alpha` | Active development. All feature work and fixes land here first. | | `alpha` | Active development. All feature work and fixes land here first. |
| `pre-release` | Periodically fast-forwarded from `alpha` once it's had some soak time. Ships as the `{version}-beta` release channel. | | `beta` | Periodically fast-forwarded from `alpha` once it's had some soak time. Ships as the `{version}-beta` release channel. |
| `master` | Fast-forwarded from `pre-release` when it's proven stable. Real, tagged releases (`vX.Y.Z`) are cut from here. | | `master` | Fast-forwarded from `beta` when it's proven stable. Real, tagged releases (`vX.Y.Z`) are cut from here. |
`pre-release` and `master` are **never** committed to directly - they only ever move forward by fast-forwarding from the branch below them. This means promotion is always a plain `git merge` with zero conflicts by construction: don't `git merge`/rebase feature work directly onto `pre-release` or `master`. `beta` and `master` are **never** committed to directly - they only ever move forward by fast-forwarding from the branch below them. This means promotion is always a plain `git merge` with zero conflicts by construction: don't `git merge`/rebase feature work directly onto `beta` or `master`.
**Contributor PRs target `alpha`**, not `master`. **Contributor PRs target `alpha`**, not `master`.
@ -148,7 +148,7 @@ Multiple unrelated changes belong in separate commits, not one bundled commit -
```bash ```bash
git push origin feat/your-feature-name git push origin feat/your-feature-name
``` ```
2. Open a Pull Request (PR) targeting the `alpha` branch (see [Branch Strategy](#branch-strategy) - `master` only receives fast-forwards from `pre-release`, never direct PRs). 2. Open a Pull Request (PR) targeting the `alpha` branch (see [Branch Strategy](#branch-strategy) - `master` only receives fast-forwards from `beta`, never direct PRs).
3. In your PR description, explain the rationale behind your changes, what was fixed/added, and how it was tested. 3. In your PR description, explain the rationale behind your changes, what was fixed/added, and how it was tested.
4. Verify that GitHub Actions CI runs successfully on your PR. 4. Verify that GitHub Actions CI runs successfully on your PR.

View File

@ -74,10 +74,10 @@
| Ветка | Роль | | Ветка | Роль |
|---|---| |---|---|
| `alpha` | Активная разработка. Вся новая работа и фиксы попадают сюда первыми. | | `alpha` | Активная разработка. Вся новая работа и фиксы попадают сюда первыми. |
| `pre-release` | Периодически перематывается вперёд (fast-forward) от `alpha`, когда та немного «отлежалась». Собирается в канал релиза `{версия}-beta`. | | `beta` | Периодически перематывается вперёд (fast-forward) от `alpha`, когда та немного «отлежалась». Собирается в канал релиза `{версия}-beta`. |
| `master` | Перематывается вперёд от `pre-release`, когда та доказала стабильность. Настоящие тегированные релизы (`vX.Y.Z`) режутся отсюда. | | `master` | Перематывается вперёд от `beta`, когда та доказала стабильность. Настоящие тегированные релизы (`vX.Y.Z`) режутся отсюда. |
В `pre-release` и `master` **никогда** не коммитят напрямую - они только перематываются вперёд от ветки уровнем ниже. Это значит, что промоушен - всегда обычный `git merge` без единого конфликта по построению: не мержите/не ребейзьте свою фичу прямо в `pre-release` или `master`. В `beta` и `master` **никогда** не коммитят напрямую - они только перематываются вперёд от ветки уровнем ниже. Это значит, что промоушен - всегда обычный `git merge` без единого конфликта по построению: не мержите/не ребейзьте свою фичу прямо в `beta` или `master`.
**PR от контрибьюторов нацелены на `alpha`**, не на `master`. **PR от контрибьюторов нацелены на `alpha`**, не на `master`.
@ -149,7 +149,7 @@ obfuscation_key/psk), чтобы он был индивидуальным для
```bash ```bash
git push origin feat/имя-вашей-фичи git push origin feat/имя-вашей-фичи
``` ```
2. Создайте Pull Request (PR) в ветку `alpha` основного репозитория (см. [Стратегия веток](#стратегия-веток) - `master` получает только fast-forward от `pre-release`, PR туда не принимаются напрямую). 2. Создайте Pull Request (PR) в ветку `alpha` основного репозитория (см. [Стратегия веток](#стратегия-веток) - `master` получает только fast-forward от `beta`, PR туда не принимаются напрямую).
3. Подробно опишите внесенные изменения: какая проблема решается, как проводилось тестирование и на каких платформах проверялась сборка. 3. Подробно опишите внесенные изменения: какая проблема решается, как проводилось тестирование и на каких платформах проверялась сборка.
4. Убедитесь, что автоматическое тестирование (GitHub Actions CI) завершилось успешно. 4. Убедитесь, что автоматическое тестирование (GitHub Actions CI) завершилось успешно.

View File

@ -192,7 +192,7 @@ Commands:
links Print client share links from the server config links Print client share links from the server config
import <URL> Import a share link into the config file import <URL> Import a share link into the config file
update Update OSTP to the latest release update Update OSTP to the latest release
-b, --branch <NAME> Release channel: stable, pre-release, alpha (default: stable) -b, --branch <NAME> Release channel: stable, beta, alpha (default: stable)
-v, --version <VER> Update to an exact version instead of the channel's latest -v, --version <VER> Update to an exact version instead of the channel's latest
migrate Force-migrate the configuration file to the current format migrate Force-migrate the configuration file to the current format
proxy-env Print shell export commands for the local SOCKS proxy proxy-env Print shell export commands for the local SOCKS proxy

View File

@ -181,7 +181,7 @@ ostp [--config <PATH>] [КОМАНДА]
links Вывести client-share-ссылки из серверного конфига links Вывести client-share-ссылки из серверного конфига
import <URL> Импортировать share-ссылку в конфиг import <URL> Импортировать share-ссылку в конфиг
update Обновить OSTP до актуального релиза update Обновить OSTP до актуального релиза
-b, --branch <NAME> Канал релиза: stable, pre-release, alpha (по умолчанию stable) -b, --branch <NAME> Канал релиза: stable, beta, alpha (по умолчанию stable)
-v, --version <VER> Обновиться на точную версию вместо последней в канале -v, --version <VER> Обновиться на точную версию вместо последней в канале
migrate Принудительно мигрировать конфиг к текущему формату migrate Принудительно мигрировать конфиг к текущему формату
proxy-env Вывести shell-команды для локального SOCKS-прокси proxy-env Вывести shell-команды для локального SOCKS-прокси

View File

@ -54,7 +54,7 @@ enum Commands {
Uninstall, Uninstall,
/// Update OSTP: re-run the install script to fetch and install the latest version /// Update OSTP: re-run the install script to fetch and install the latest version
Update { Update {
/// Release branch to update from (stable, pre-release, alpha) /// Release branch to update from (stable, beta, alpha)
#[arg(short = 'b', long, default_value = "stable")] #[arg(short = 'b', long, default_value = "stable")]
branch: String, branch: String,
/// Exact release version to update to (e.g. 0.4.1 or 0.4.1-beta.3), /// Exact release version to update to (e.g. 0.4.1 or 0.4.1-beta.3),

View File

@ -24,7 +24,7 @@
Promoting to beta/master first fast-forwards that branch to `alpha` Promoting to beta/master first fast-forwards that branch to `alpha`
(--ff-only this always succeeds cleanly as long as nobody ever commits (--ff-only this always succeeds cleanly as long as nobody ever commits
directly to pre-release/master, per CONTRIBUTING.md's branch strategy), so directly to beta/master, per CONTRIBUTING.md's branch strategy), so
a release always ships alpha's latest, not a stale branch. Switching to a a release always ships alpha's latest, not a stale branch. Switching to a
channel for the first time in a cycle resets THAT channel's iteration channel for the first time in a cycle resets THAT channel's iteration
counter to 1 (a fresh promotion starts its own count; it doesn't inherit counter to 1 (a fresh promotion starts its own count; it doesn't inherit
@ -50,7 +50,7 @@
parameter is the only thing that fixes it. Do not rename this back. parameter is the only thing that fixes it. Do not rename this back.
.PARAMETER Branch .PARAMETER Branch
Which branch/channel to release from: master, pre-release (beta), or alpha. Which branch/channel to release from: master, beta, or alpha.
Defaults to whatever was used last time (see .release-state.json). Defaults to whatever was used last time (see .release-state.json).
.EXAMPLE .EXAMPLE
@ -63,8 +63,8 @@
ships v0.4.2-alpha.1. ships v0.4.2-alpha.1.
.EXAMPLE .EXAMPLE
.\scripts\gha.ps1 -Branch pre-release .\scripts\gha.ps1 -Branch beta
Promotes alpha -> pre-release (beta channel), resets beta_iteration to 1 Promotes alpha -> beta (beta channel), resets beta_iteration to 1
(or bumps it if already mid-beta), ships v{target}-beta.{N}. (or bumps it if already mid-beta), ships v{target}-beta.{N}.
.EXAMPLE .EXAMPLE
@ -74,7 +74,7 @@
[CmdletBinding()] [CmdletBinding()]
param( param(
[string]$NewVersion, [string]$NewVersion,
[ValidateSet('master', 'pre-release', 'alpha')] [ValidateSet('master', 'beta', 'alpha')]
[string]$Branch [string]$Branch
) )
@ -133,11 +133,11 @@ if ($IsNewTarget) {
# Entering a channel that wasn't active last run (a promotion) starts # Entering a channel that wasn't active last run (a promotion) starts
# THAT channel's count fresh — it doesn't inherit alpha's iteration number. # THAT channel's count fresh — it doesn't inherit alpha's iteration number.
$BranchChanged = ($ResolvedBranch -ne $PrevBranch) $BranchChanged = ($ResolvedBranch -ne $PrevBranch)
if ($BranchChanged -and $ResolvedBranch -eq "pre-release") { $BetaIter = 0 } if ($BranchChanged -and $ResolvedBranch -eq "beta") { $BetaIter = 0 }
if ($BranchChanged -and $ResolvedBranch -eq "alpha") { $AlphaIter = 0 } if ($BranchChanged -and $ResolvedBranch -eq "alpha") { $AlphaIter = 0 }
} }
$Channel = switch ($ResolvedBranch) { "alpha" { "alpha" }; "pre-release" { "beta" }; "master" { "stable" } } $Channel = switch ($ResolvedBranch) { "alpha" { "alpha" }; "beta" { "beta" }; "master" { "stable" } }
if ($Channel -eq "alpha") { $AlphaIter++ } if ($Channel -eq "alpha") { $AlphaIter++ }
elseif ($Channel -eq "beta") { $BetaIter++ } elseif ($Channel -eq "beta") { $BetaIter++ }
@ -230,7 +230,7 @@ git commit -m $commitMsg | Out-Null
# -- Push. release.yml triggers ONLY on "v*" tag pushes (no branch trigger), - # -- Push. release.yml triggers ONLY on "v*" tag pushes (no branch trigger), -
# -- so the tag push is what actually starts the build; the branch push is - # -- so the tag push is what actually starts the build; the branch push is -
# -- just so the promotion chain (alpha -> pre-release -> master) itself - # -- just so the promotion chain (alpha -> beta -> master) itself -
# -- keeps moving forward for the next --ff-only. - # -- keeps moving forward for the next --ff-only. -
Write-Step "Tagging $Tag and pushing $ResolvedBranch + tag" Write-Step "Tagging $Tag and pushing $ResolvedBranch + tag"
git tag $Tag git tag $Tag

View File

@ -118,9 +118,9 @@ else
if [ "$TARGET_BRANCH" == "alpha" ]; then if [ "$TARGET_BRANCH" == "alpha" ]; then
echo "Fetching alpha release..." echo "Fetching alpha release..."
LATEST_RELEASE="alpha" LATEST_RELEASE="alpha"
elif [ "$TARGET_BRANCH" == "pre-release" ]; then elif [ "$TARGET_BRANCH" == "beta" ]; then
echo "Fetching pre-release..." echo "Fetching beta release..."
LATEST_RELEASE="pre-release" LATEST_RELEASE="beta"
else else
echo "Fetching latest stable release..." echo "Fetching latest stable release..."
LATEST_RELEASE=$(curl -s "https://api.github.com/repos/${GITHUB_REPO}/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') LATEST_RELEASE=$(curl -s "https://api.github.com/repos/${GITHUB_REPO}/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')