From eb638b2ce47d6b7017920903637c39c2757effa0 Mon Sep 17 00:00:00 2001 From: gusadmin Date: Tue, 14 Jul 2026 17:28:51 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9C=D0=B5=D1=85=D0=B0=D0=BD=D0=B8=D0=B7?= =?UTF-8?q?=D0=BC=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D0=B8:=20bump-upstream.?= =?UTF-8?q?sh=20+=20provision-windows.ps1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bump-upstream.sh [tag|latest] тянет пины тулчейна из CI-конфигов целевого тега RustDesk -> upstream.txt (не разъезжается с Flutter/ vcpkg/LLVM/FRB). provision-windows.ps1 идемпотентно доводит тулчейн до пинов; build-windows.ps1 зовёт его сам -> бамп+пересборка = 1 команда. Co-Authored-By: Claude Opus 4.8 --- README.md | 17 ++++++- docs/CODEMAP.md | 4 +- scripts/build-windows.ps1 | 4 ++ scripts/bump-upstream.sh | 87 ++++++++++++++++++++++++++++++++++ scripts/provision-windows.ps1 | 89 +++++++++++++++++++++++++++++++++++ upstream.txt | 6 +-- 6 files changed, 201 insertions(+), 6 deletions(-) create mode 100644 scripts/bump-upstream.sh create mode 100644 scripts/provision-windows.ps1 diff --git a/README.md b/README.md index 1c28d84..b307b44 100644 --- a/README.md +++ b/README.md @@ -25,10 +25,23 @@ pwsh -File scripts\build-windows.ps1 Тулчейн (Rust 1.75, LLVM 15.0.6, Flutter 3.24.5, vcpkg@пин) нужно поднять один раз — см. [docs/CODEMAP.md](docs/CODEMAP.md). Первая сборка долгая: vcpkg компилит ffmpeg/aom из исходников. -## Пины +## Пины и обновление версии RustDesk Все версии зафиксированы в [`upstream.txt`](upstream.txt) (правило проекта: никаких `latest`). -Обновление RustDesk = поднять `RUSTDESK_TAG` и сверить остальные пины с новым `flutter-build.yml` апстрима. +Файл **автогенерится** — при бампе апстрима меняется не только тег, но и весь тулчейн +(Flutter/vcpkg/LLVM/FRB апстрим двигает между релизами), поэтому пины тянутся из CI-конфигов +самого целевого тега, а не проставляются вручную. + +**Подтянуть свежую версию и пересобрать под себя:** +```powershell +bash scripts/bump-upstream.sh latest # или конкретный тег: bash scripts/bump-upstream.sh 1.5.0 + # -> перепишет upstream.txt пинами из CI этого тега (с диффом) +pwsh -File scripts/build-windows.ps1 # provision сам доустановит новые Flutter/vcpkg/LLVM -> пересборка +``` +`build-windows.ps1` в начале зовёт [`provision-windows.ps1`](scripts/provision-windows.ps1) — тот +идемпотентно доводит тулчейн до пинов (ставит только отсутствующее/несовпадающее по версии). То есть +один и тот же `build-windows.ps1` работает и для текущей, и для только что бампнутой версии. +В CI бамп = закоммитить обновлённый `upstream.txt` и запустить workflow. ## Платформы diff --git a/docs/CODEMAP.md b/docs/CODEMAP.md index 3286918..85b173c 100644 --- a/docs/CODEMAP.md +++ b/docs/CODEMAP.md @@ -8,7 +8,9 @@ |------|-----------| | `upstream.txt` | Пины: `RUSTDESK_TAG`, версии Rust/LLVM/Flutter, `VCPKG_COMMIT_ID`, `VCPKG_TRIPLET`, Android-пины. Единственный источник версий. | | `scripts/preconfigure.sh` | Патчит `RENDEZVOUS_SERVERS` и `RS_PUB_KEY` в `hbb_common/src/config.rs` клона. Значения из env. Проверяет, что патч применился. | -| `scripts/build-windows.ps1` | Оркестратор локальной Windows-сборки: load env → клон@пин → preconfigure → `python build.py --flutter` → `dist/`. Есть preflight тулчейна. | +| `scripts/bump-upstream.sh` | `[|latest]` → тянет пины тулчейна из CI-конфигов целевого тега RustDesk (flutter-build.yml + bridge.yml) и переписывает `upstream.txt` (с диффом). Так бамп версии не разъезжается с Flutter/vcpkg/LLVM/FRB/NDK. | +| `scripts/provision-windows.ps1` | Идемпотентно доводит тулчейн до пинов (Rust+rustfmt, Flutter, LLVM, vcpkg@коммит). Ставит только отсутствующее/несовпадающее. Зовётся из build-windows.ps1 (skip: `RD_SKIP_PROVISION=1`). | +| `scripts/build-windows.ps1` | Оркестратор Windows-сборки: provision → load env → клон@пин → preconfigure → codegen → vcpkg install → build.py → портативный установщик → `dist/`. | | `config/server.env.example` | Шаблон значений. Реальный `config/server.env` — в `.gitignore`. | | `.gitea/workflows/` | CI: `build-windows.yaml` (раннер `windows:host`), `build-android.yaml` (VM 118). *(в работе)* | | `rustdesk/` | Клон апстрима (gitignored, создаётся сборкой). | diff --git a/scripts/build-windows.ps1 b/scripts/build-windows.ps1 index 0d5fafd..9df23b3 100644 --- a/scripts/build-windows.ps1 +++ b/scripts/build-windows.ps1 @@ -24,6 +24,10 @@ Get-Content (Join-Path $root 'upstream.txt') | Where-Object { $_ -match '^\s*[A- $TAG=$pins['RUSTDESK_TAG']; $REPO=$pins['RUSTDESK_REPO']; $TRIPLET=$pins['VCPKG_TRIPLET'] Write-Host "== RustDesk custom build == tag=$TAG triplet=$TRIPLET" -ForegroundColor Cyan +# Довести тулчейн до пинов (идемпотентно). После bump-upstream.sh доустановит новые Flutter/vcpkg/LLVM. +# RD_SKIP_PROVISION=1 — пропустить (когда точно уверен, что тулчейн актуален). +if (-not $env:RD_SKIP_PROVISION) { & "$PSScriptRoot\provision-windows.ps1" } + # --- пути тулчейна --- $FlutterHome = if ($env:FLUTTER_HOME) { $env:FLUTTER_HOME } else { 'S:\dev\flutter' } $VcpkgRoot = if ($env:VCPKG_ROOT) { $env:VCPKG_ROOT } else { 'S:\dev\vcpkg' } diff --git a/scripts/bump-upstream.sh b/scripts/bump-upstream.sh new file mode 100644 index 0000000..64473da --- /dev/null +++ b/scripts/bump-upstream.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +# Обновляет пины RustDesk-апстрима в upstream.txt под указанный релиз-тег (или latest). +# Тянет версии тулчейна из CI-конфигов САМОГО тега (flutter-build.yml + bridge.yml) — чтобы бамп +# версии RustDesk не разъезжался с Flutter/vcpkg/LLVM/FRB/NDK, которые апстрим меняет между релизами. +# +# Usage: scripts/bump-upstream.sh [|latest] +# без аргумента / latest — берёт последний стабильный релиз rustdesk/rustdesk. +# После бампа: provision-windows.ps1 (если пины изменились) -> build-windows.ps1. +set -euo pipefail + +REPO="rustdesk/rustdesk" +ROOT="$(cd "$(dirname "$0")/.." && pwd)" +UP="$ROOT/upstream.txt" +TAG="${1:-latest}" + +api() { curl -fsSL ${GH_TOKEN:+-H "Authorization: Bearer $GH_TOKEN"} "$@"; } +raw() { curl -fsSL "https://raw.githubusercontent.com/$REPO/$1"; } + +if [ "$TAG" = "latest" ]; then + TAG="$(api "https://api.github.com/repos/$REPO/releases/latest" | grep -o '"tag_name": *"[^"]*"' | head -1 | sed -E 's/.*"tag_name": *"([^"]*)".*/\1/')" +fi +[ -n "$TAG" ] || { echo "не удалось определить тег" >&2; exit 1; } +echo "Целевой тег RustDesk: $TAG" + +FB="$(raw "$TAG/.github/workflows/flutter-build.yml")" || { echo "нет flutter-build.yml в $TAG" >&2; exit 1; } +BR="$(raw "$TAG/.github/workflows/bridge.yml")" || { echo "нет bridge.yml в $TAG" >&2; exit 1; } + +# Вытаскиваем ` KEY: "value" # comment` -> value (без кавычек и комментария). +yenv() { + printf '%s\n' "$1" | grep -E "^[[:space:]]*$2:[[:space:]]*" | head -1 \ + | sed -E "s/^[[:space:]]*$2:[[:space:]]*//; s/#.*$//; s/^\"//; s/\"[[:space:]]*$//; s/[[:space:]]*$//" +} + +RUST_VERSION="$(yenv "$FB" RUST_VERSION)" +LLVM_VERSION="$(yenv "$FB" LLVM_VERSION)" +FLUTTER_VERSION="$(yenv "$FB" FLUTTER_VERSION)" +VCPKG_COMMIT_ID="$(yenv "$FB" VCPKG_COMMIT_ID)" +NDK_VERSION="$(yenv "$FB" NDK_VERSION)" +CARGO_NDK_VERSION="$(yenv "$FB" CARGO_NDK_VERSION)" +ANDROID_FLUTTER_VERSION="$(yenv "$FB" ANDROID_FLUTTER_VERSION)" +FRB_VERSION="$(yenv "$BR" FLUTTER_RUST_BRIDGE_VERSION)" +CARGO_EXPAND_VERSION="$(yenv "$BR" CARGO_EXPAND_VERSION)" + +# Триплет не меняется апстримом — сохраняем текущий (или дефолт). +VCPKG_TRIPLET="$(grep -E '^VCPKG_TRIPLET=' "$UP" 2>/dev/null | cut -d= -f2)"; VCPKG_TRIPLET="${VCPKG_TRIPLET:-x64-windows-static}" + +# Проверяем, что все пины вытащились (иначе апстрим переименовал переменную — не молча ломаемся). +for v in RUST_VERSION LLVM_VERSION FLUTTER_VERSION VCPKG_COMMIT_ID NDK_VERSION CARGO_NDK_VERSION \ + ANDROID_FLUTTER_VERSION FRB_VERSION CARGO_EXPAND_VERSION; do + if [ -z "${!v}" ]; then echo "ОШИБКА: не удалось извлечь $v из CI-конфигов $TAG (апстрим переименовал?)." >&2; exit 1; fi +done + +echo "=== было -> станет ===" +show() { local old; old="$(grep -E "^$1=" "$UP" 2>/dev/null | cut -d= -f2-)"; printf ' %-24s %s -> %s\n' "$1" "${old:-—}" "$2"; } +show RUSTDESK_TAG "$TAG" +show RUST_VERSION "$RUST_VERSION"; show LLVM_VERSION "$LLVM_VERSION"; show FLUTTER_VERSION "$FLUTTER_VERSION" +show VCPKG_COMMIT_ID "$VCPKG_COMMIT_ID"; show FRB_VERSION "$FRB_VERSION"; show CARGO_EXPAND_VERSION "$CARGO_EXPAND_VERSION" +show NDK_VERSION "$NDK_VERSION"; show CARGO_NDK_VERSION "$CARGO_NDK_VERSION"; show ANDROID_FLUTTER_VERSION "$ANDROID_FLUTTER_VERSION" + +cat > "$UP" <|latest] -> provision-windows.ps1 -> build-windows.ps1. + +RUSTDESK_TAG=$TAG +RUSTDESK_REPO=https://github.com/rustdesk/rustdesk.git + +# Тулчейн (Windows x64 flutter-сборка) +RUST_VERSION=$RUST_VERSION +LLVM_VERSION=$LLVM_VERSION +FLUTTER_VERSION=$FLUTTER_VERSION +VCPKG_COMMIT_ID=$VCPKG_COMMIT_ID +VCPKG_TRIPLET=$VCPKG_TRIPLET + +# flutter_rust_bridge codegen (генерит src/bridge_generated.rs) +FRB_VERSION=$FRB_VERSION +CARGO_EXPAND_VERSION=$CARGO_EXPAND_VERSION + +# Android (VM 118) +ANDROID_FLUTTER_VERSION=$ANDROID_FLUTTER_VERSION +CARGO_NDK_VERSION=$CARGO_NDK_VERSION +NDK_VERSION=$NDK_VERSION +EOF + +echo +echo "upstream.txt обновлён на $TAG." +echo "Дальше: pwsh -File scripts/provision-windows.ps1 (доведёт тулчейн до пинов) -> scripts/build-windows.ps1" diff --git a/scripts/provision-windows.ps1 b/scripts/provision-windows.ps1 new file mode 100644 index 0000000..cb38f92 --- /dev/null +++ b/scripts/provision-windows.ps1 @@ -0,0 +1,89 @@ +<# + Идемпотентно доводит Windows-тулчейн до пинов из upstream.txt. + Ставит/обновляет только то, что отсутствует или не совпадает по версии — поэтому после + `bump-upstream.sh` (смена версии RustDesk -> возможно другой Flutter/vcpkg/LLVM) достаточно + прогнать этот скрипт, и сборка соберётся новой версией. + + Ставит на S:\dev (C: тесный). VS Build Tools 2022 (MSVC+CMake) — предполагается уже установленной. + Вызывается автоматически из build-windows.ps1; можно и вручную: pwsh -File scripts\provision-windows.ps1 +#> +[CmdletBinding()] +param() +$ErrorActionPreference = 'Stop' +$root = Split-Path -Parent $PSScriptRoot + +# CIDR в NO_PROXY ломает WinHTTP-загрузчики (vcpkg bootstrap и т.п.); есть прямой инет. +foreach ($p in 'HTTP_PROXY','HTTPS_PROXY','NO_PROXY','ALL_PROXY','http_proxy','https_proxy','no_proxy') { Set-Item "Env:$p" $null -EA SilentlyContinue } + +$pins = @{} +Get-Content (Join-Path $root 'upstream.txt') | Where-Object { $_ -match '^\s*[A-Z]' } | ForEach-Object { + $k,$v = $_ -split '=',2; $pins[$k.Trim()] = $v.Trim() +} +$FlutterHome = if ($env:FLUTTER_HOME) { $env:FLUTTER_HOME } else { 'S:\dev\flutter' } +$VcpkgRoot = if ($env:VCPKG_ROOT) { $env:VCPKG_ROOT } else { 'S:\dev\vcpkg' } +$LlvmRoot = 'S:\dev\LLVM' +New-Item -ItemType Directory -Force 'S:\dev' | Out-Null +Write-Host "== provision-windows == пины из upstream.txt (RustDesk $($pins['RUSTDESK_TAG']))" -ForegroundColor Cyan + +# --- Rust toolchain + rustfmt --- +$rustV = $pins['RUST_VERSION'] +if (-not ((rustup toolchain list) -match [regex]::Escape($rustV))) { + Write-Host "[rust] ставлю $rustV..." -ForegroundColor Yellow + rustup toolchain install "$rustV-x86_64-pc-windows-msvc" | Out-Null +} else { Write-Host "[rust] $rustV уже есть" -ForegroundColor Green } +rustup component add rustfmt --toolchain "$rustV-x86_64-pc-windows-msvc" | Out-Null + +# --- Flutter --- +$flutterV = $pins['FLUTTER_VERSION'] +$have = '' +if (Test-Path "$FlutterHome\bin\flutter.bat") { + $have = (& "$FlutterHome\bin\flutter.bat" --version 2>$null | Select-String -Pattern 'Flutter (\d+\.\d+\.\d+)').Matches.Groups[1].Value +} +if ($have -ne $flutterV) { + Write-Host "[flutter] нужен $flutterV (есть '$have') — скачиваю..." -ForegroundColor Yellow + if (Test-Path $FlutterHome) { Remove-Item -Recurse -Force $FlutterHome } + $zip = "S:\dev\flutter_$flutterV.zip" + Invoke-WebRequest -UseBasicParsing -Uri "https://storage.googleapis.com/flutter_infra_release/releases/stable/windows/flutter_windows_$flutterV-stable.zip" -OutFile $zip + tar -xf $zip -C 'S:\dev' + Remove-Item $zip + & "$FlutterHome\bin\flutter.bat" --version 2>$null | Select-Object -First 1 | Out-Null # прогрев (докачка Dart SDK) +} else { Write-Host "[flutter] $flutterV уже есть" -ForegroundColor Green } + +# --- LLVM (libclang для bindgen/ffigen; VS-бандл его не содержит) --- +$llvmV = $pins['LLVM_VERSION'] +$haveLlvm = '' +if (Test-Path "$LlvmRoot\bin\clang.exe") { + $haveLlvm = (& "$LlvmRoot\bin\clang.exe" --version 2>$null | Select-String -Pattern 'clang version (\d+\.\d+\.\d+)').Matches.Groups[1].Value +} +if ($haveLlvm -ne $llvmV -or -not (Test-Path "$LlvmRoot\bin\libclang.dll")) { + Write-Host "[llvm] нужен $llvmV (есть '$haveLlvm') — ставлю..." -ForegroundColor Yellow + if (Test-Path $LlvmRoot) { Remove-Item -Recurse -Force $LlvmRoot } + $exe = "S:\dev\LLVM-$llvmV-win64.exe" + Invoke-WebRequest -UseBasicParsing -Uri "https://github.com/llvm/llvm-project/releases/download/llvmorg-$llvmV/LLVM-$llvmV-win64.exe" -OutFile $exe + Start-Process -FilePath $exe -ArgumentList '/S',"/D=$LlvmRoot" -Wait + Remove-Item $exe -EA SilentlyContinue + if (-not (Test-Path "$LlvmRoot\bin\libclang.dll")) { throw "LLVM $llvmV установился без libclang.dll" } +} else { Write-Host "[llvm] $llvmV уже есть" -ForegroundColor Green } + +# --- vcpkg на нужном коммите --- +$vcpkgC = $pins['VCPKG_COMMIT_ID'] +if (-not (Test-Path "$VcpkgRoot\.git")) { + Write-Host "[vcpkg] клонирую..." -ForegroundColor Yellow + git clone --quiet https://github.com/microsoft/vcpkg.git $VcpkgRoot +} +$haveC = (git -C $VcpkgRoot rev-parse HEAD 2>$null) +if ($haveC -ne $vcpkgC) { + Write-Host "[vcpkg] checkout $vcpkgC (было $($haveC.Substring(0,[Math]::Min(8,$haveC.Length))))..." -ForegroundColor Yellow + git -C $VcpkgRoot fetch --quiet origin + git -C $VcpkgRoot checkout --quiet $vcpkgC + Remove-Item "$VcpkgRoot\vcpkg.exe" -EA SilentlyContinue # tool перепривяжется под новый коммит +} else { Write-Host "[vcpkg] на нужном коммите" -ForegroundColor Green } +if (-not (Test-Path "$VcpkgRoot\vcpkg.exe")) { + # bootstrap через WinHTTP исторически падает на прокси — тянем нужный vcpkg.exe напрямую (IWR). + $tag = (Get-Content "$VcpkgRoot\scripts\vcpkg-tool-metadata.txt" -Raw | Select-String 'VCPKG_TOOL_RELEASE_TAG=(\S+)').Matches.Groups[1].Value + Write-Host "[vcpkg] тяну vcpkg.exe (tool $tag)..." -ForegroundColor Yellow + Invoke-WebRequest -UseBasicParsing -Uri "https://github.com/microsoft/vcpkg-tool/releases/download/$tag/vcpkg.exe" -OutFile "$VcpkgRoot\vcpkg.exe" + Set-Content "$VcpkgRoot\vcpkg-version.txt" $tag -NoNewline +} + +Write-Host "== provision-windows: тулчейн соответствует пинам ==" -ForegroundColor Cyan diff --git a/upstream.txt b/upstream.txt index ace9262..3392ea5 100644 --- a/upstream.txt +++ b/upstream.txt @@ -1,6 +1,6 @@ # Пины апстрима RustDesk и тулчейна (правило: никаких latest). -# Значения взяты из rustdesk/rustdesk@1.4.9 .github/workflows/flutter-build.yml. -# Обновление апстрима = поднять RUSTDESK_TAG и сверить остальные пины с новым flutter-build.yml. +# Автогенерится scripts/bump-upstream.sh из CI-конфигов целевого тега (flutter-build.yml + bridge.yml). +# Обновить: scripts/bump-upstream.sh [|latest] -> provision-windows.ps1 -> build-windows.ps1. RUSTDESK_TAG=1.4.9 RUSTDESK_REPO=https://github.com/rustdesk/rustdesk.git @@ -12,7 +12,7 @@ FLUTTER_VERSION=3.24.5 VCPKG_COMMIT_ID=120deac3062162151622ca4860575a33844ba10b VCPKG_TRIPLET=x64-windows-static -# flutter_rust_bridge codegen (генерит src/bridge_generated.rs; пины из bridge.yml@1.4.9) +# flutter_rust_bridge codegen (генерит src/bridge_generated.rs) FRB_VERSION=1.80.1 CARGO_EXPAND_VERSION=1.0.95