Compare commits
2 Commits
70287140ec
...
feat/new_u
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b76734652 | ||
|
|
5e7fb58049 |
@@ -14,6 +14,12 @@ concurrency:
|
|||||||
group: ${{ gitea.workflow }}-${{ gitea.ref }}
|
group: ${{ gitea.workflow }}-${{ gitea.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
# CI собирает/тестирует ТОЛЬКО headless-вариант: приложение без графического окна
|
||||||
|
# (internal/app/ui_noui.go). UI (Fyne-окно) требует cgo и C-компилятора, поэтому
|
||||||
|
# собирается локально и публикуется скриптом scripts/build-publish-ui.ps1.
|
||||||
|
env:
|
||||||
|
CGO_ENABLED: '0'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -22,11 +28,11 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/setup-go@v5
|
- uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.23'
|
go-version: '1.25'
|
||||||
check-latest: true
|
check-latest: true
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: go test ./... -v -count=1 -timeout 120s 2>&1
|
run: go test ./... -v -count=1 -timeout 300s 2>&1
|
||||||
|
|
||||||
- name: Vet
|
- name: Vet
|
||||||
run: go vet ./...
|
run: go vet ./...
|
||||||
@@ -34,27 +40,22 @@ jobs:
|
|||||||
build-and-package:
|
build-and-package:
|
||||||
if: always()
|
if: always()
|
||||||
needs: test
|
needs: test
|
||||||
strategy:
|
# Только linux: headless-бинарь для сервера. Windows-бинарь (с UI, cgo)
|
||||||
matrix:
|
# публикуется локально через scripts/build-publish-ui.ps1.
|
||||||
goos: [linux, windows]
|
|
||||||
goarch: [amd64]
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/setup-go@v5
|
- uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.23'
|
go-version: '1.25'
|
||||||
check-latest: true
|
check-latest: true
|
||||||
|
|
||||||
- name: Build binary
|
- name: Build binary
|
||||||
run: |
|
run: |
|
||||||
FILENAME="ratatoskr-${{ matrix.goos }}-${{ matrix.goarch }}"
|
FILENAME="ratatoskr-linux-amd64"
|
||||||
if [ "${{ matrix.goos }}" = "windows" ]; then
|
|
||||||
FILENAME="${FILENAME}.exe"
|
|
||||||
fi
|
|
||||||
VERSION="commit-$(echo '${{ gitea.sha }}' | cut -c1-7)"
|
VERSION="commit-$(echo '${{ gitea.sha }}' | cut -c1-7)"
|
||||||
GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} \
|
GOOS=linux GOARCH=amd64 \
|
||||||
go build -ldflags="-s -w -X main.version=${VERSION} -X main.updateToken=${{ secrets.TC_UPDATE_TOKEN }}" -o "${FILENAME}" ./cmd/ratatoskr/
|
go build -ldflags="-s -w -X main.version=${VERSION} -X main.updateToken=${{ secrets.TC_UPDATE_TOKEN }}" -o "${FILENAME}" ./cmd/ratatoskr/
|
||||||
echo "FILENAME=${FILENAME}" >> "${GITEA_ENV}"
|
echo "FILENAME=${FILENAME}" >> "${GITEA_ENV}"
|
||||||
echo "VERSION=${VERSION}" >> "${GITEA_ENV}"
|
echo "VERSION=${VERSION}" >> "${GITEA_ENV}"
|
||||||
|
|||||||
9
.gitignore
vendored
9
.gitignore
vendored
@@ -4,6 +4,12 @@
|
|||||||
*.out
|
*.out
|
||||||
ratatoskr
|
ratatoskr
|
||||||
|
|
||||||
|
# Publish companions (scripts/build-publish-ui.ps1)
|
||||||
|
ratatoskr-*.exe.sha256
|
||||||
|
ratatoskr-*.exe.version
|
||||||
|
ratatoskr-*.sha256
|
||||||
|
ratatoskr-*.version
|
||||||
|
|
||||||
# Go build/test artifacts
|
# Go build/test artifacts
|
||||||
/testbin/
|
/testbin/
|
||||||
*.test
|
*.test
|
||||||
@@ -14,6 +20,9 @@ ratatoskr
|
|||||||
!/.env.example
|
!/.env.example
|
||||||
secrets/
|
secrets/
|
||||||
|
|
||||||
|
# Local Gitea credentials for scripts/build-publish-ui.ps1
|
||||||
|
scripts/.gitea-creds
|
||||||
|
|
||||||
# Local config (not tracked — use config.yaml.example)
|
# Local config (not tracked — use config.yaml.example)
|
||||||
config.yaml
|
config.yaml
|
||||||
|
|
||||||
|
|||||||
23
.serena/memories/toolchain/cgo-winlibs-gcc.md
Normal file
23
.serena/memories/toolchain/cgo-winlibs-gcc.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# C-тулчейн для cgo-сборки (Fyne/GLFW) на этой машине
|
||||||
|
|
||||||
|
WinLibs (BrechtSanders.WinLibs.POSIX.UCRT) установлен через winget как
|
||||||
|
portable (zip) в:
|
||||||
|
`C:\Users\darkg\AppData\Local\Microsoft\WinGet\Packages\BrechtSanders.WinLibs.POSIX.UCRT_Microsoft.Winget.Source_8wekyb3d8bbwe\mingw64\bin`
|
||||||
|
|
||||||
|
- gcc 16.1.0, target `x86_64-w64-mingw32`, рантайм `x86_64-ucrt-posix-seh`.
|
||||||
|
- Установлен портативно — НЕ регистрируется в PATH автоматически.
|
||||||
|
- PATH добавлен в `HKCU\Environment` (WinLibs bin первым), но в новых
|
||||||
|
PowerShell-процессах opencode окружение НЕ перечитывается, поэтому в каждой
|
||||||
|
команде, где нужен cgo, добавлять вручную:
|
||||||
|
$p = "...\mingw64\bin"; $env:Path = "$p;$env:Path"; $env:CGO_ENABLED = "1"
|
||||||
|
|
||||||
|
Важно: на машине есть clang-msvc/i686 (D:\Program Files\LLVM, D:\Program
|
||||||
|
Files (x86)\LLVM) — он НЕ подходит для cgo (msvc-таргет + 32bit). Поэтому
|
||||||
|
gcc должен идти первым в PATH.
|
||||||
|
|
||||||
|
Для сборки окна: `CGO_ENABLED=1 go build ./...` (компилирует ui_cgo.go и
|
||||||
|
internal/ui/desktop). Без cgo окно не собирается — приложение headless
|
||||||
|
(ui_noui.go), флаг `--noui` в cmd/ratatoskr/main.go.
|
||||||
|
|
||||||
|
Для запуска GUI нужен реальный TG-конфиг (telegram.token/chat_id), иначе app
|
||||||
|
падает на init.
|
||||||
57
README.md
57
README.md
@@ -3,7 +3,9 @@
|
|||||||
Ratatoskr на Go — **оркестратор в единый статический бинарь** + субагенты через
|
Ratatoskr на Go — **оркестратор в единый статический бинарь** + субагенты через
|
||||||
[opencode](https://opencode.ai) как внешний процесс. Переезд с Python-версии:
|
[opencode](https://opencode.ai) как внешний процесс. Переезд с Python-версии:
|
||||||
все подсистемы (диалог, воркер, автообновление) собраны в один исполняемый
|
все подсистемы (диалог, воркер, автообновление) собраны в один исполняемый
|
||||||
файл без runtime-зависимостей (`CGO_ENABLED=0`), что упрощает доставку и деплой.
|
файл, что упрощает доставку и деплой. Бинарь по умолчанию headless
|
||||||
|
(`CGO_ENABLED=0`); графическое окно (Fyne) — опционально, собирается с cgo
|
||||||
|
(только локально, см. «Локальная сборка UI-бинаря»).
|
||||||
|
|
||||||
## Структура
|
## Структура
|
||||||
|
|
||||||
@@ -58,10 +60,40 @@ GOFLAGS ?= -ldflags="-s -w -X main.version=commit-$(GIT_SHA) -X main.updateToken
|
|||||||
- `main.updateToken` = токен read:package для автообновления (см. ниже). Если не задан
|
- `main.updateToken` = токен read:package для автообновления (см. ниже). Если не задан
|
||||||
(`UPDATE_TOKEN ?= ""`) — пустая встройка, тогда обновление берёт `update.token` из конфига.
|
(`UPDATE_TOKEN ?= ""`) — пустая встройка, тогда обновление берёт `update.token` из конфига.
|
||||||
|
|
||||||
|
**Обычный `make build`/`make cross` окно НЕ включает** — Fyne-окно требует cgo и
|
||||||
|
C-компилятора. Headless-бинарь (без окна) собирается и в CI, и локально; UI-бинарь
|
||||||
|
с окном — только локально (см. ниже).
|
||||||
|
|
||||||
|
### Локальная сборка UI-бинаря (Windows, Fyne-окно) + публикация в Gitea
|
||||||
|
|
||||||
|
CI headless: `CGO_ENABLED=0` и публикует только `ratatoskr-linux-amd64`
|
||||||
|
(см. `.gitea/workflows/ci.yaml`). Windows-бинарь с окном собирается на Windows-машине
|
||||||
|
и публикуется скриптом:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1) Секреты (git-ignored): скопировать и заполнить
|
||||||
|
cp scripts/.gitea-creds.example scripts/.gitea-creds
|
||||||
|
# GITEA_TOKEN=write:packages-токен
|
||||||
|
# UPDATE_TOKEN=read:package-токен
|
||||||
|
# GIT_MAIN_URL=http://gitea.hal9000.home
|
||||||
|
|
||||||
|
# 2) Убедиться, что gcc (MinGW) в PATH и CGO_ENABLED=1 — см. память
|
||||||
|
# `mem:toolchain/cgo-winlibs-gcc`
|
||||||
|
|
||||||
|
# 3) Запустить (HEAD должен быть тем коммитом, что в main):
|
||||||
|
powershell -ExecutionPolicy Bypass -File scripts/build-publish-ui.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
Скрипт собирает `ratatoskr-windows-amd64.exe` с `-X main.version=commit-<sha7>` и
|
||||||
|
`-X main.updateToken=...`, пишет companion-файлы `.version`/`.sha256` и публикует все
|
||||||
|
три в `.../generic/ratatoskr/commit-<sha7>/`. В конце сам перечитывает `.sha256`/`.version`
|
||||||
|
из Gitea и сверяет (контракт U4) — как проверка в разделе «Валидация опубликованной версии».
|
||||||
|
|
||||||
**Как на самом деле публикуется рабочий бинарь:** локальный `go build` токен НЕ вшивает
|
**Как на самом деле публикуется рабочий бинарь:** локальный `go build` токен НЕ вшивает
|
||||||
(значение секрета есть только у CI). Запушь `main` — CI (см. ниже) сам соберёт оба бинаря
|
(значение секрета есть только у CI и в git-ignored `scripts/.gitea-creds`). Запушь `main` —
|
||||||
со вшитым `TC_UPDATE_TOKEN` и загрузит их в Gitea Packages. Так соблюдён least-privilege:
|
CI сам соберёт headless-linux со вшитым `TC_UPDATE_TOKEN` и загрузит его в Gitea Packages;
|
||||||
read-токен не светится на хосте разработки.
|
Windows-бинарь с UI публикуется локальным скриптом (токен read:package в `scripts/.gitea-creds`).
|
||||||
|
Так соблюдён least-privilege: read-токен не светится в репозитории/на хосте CI.
|
||||||
|
|
||||||
### Проверки перед сборкой
|
### Проверки перед сборкой
|
||||||
|
|
||||||
@@ -78,13 +110,17 @@ make run # build + ./ratatoskr -config config.yaml
|
|||||||
|
|
||||||
## CI (.gitea/workflows/ci.yaml)
|
## CI (.gitea/workflows/ci.yaml)
|
||||||
|
|
||||||
- **Job `test`**: checkout → setup-go → `go test ./...` → `go vet ./...`.
|
- **Job `test`**: checkout → setup-go 1.25 → `go test ./...` → `go vet ./...`.
|
||||||
- **Job `build-and-package`** (matrix linux/amd64 + windows/amd64, без артефактов):
|
Работает в headless-режиме (`CGO_ENABLED=0`, без Fyne/glfw).
|
||||||
собирает бинарь со вшитым `-X main.updateToken=${secrets.TC_UPDATE_TOKEN}` и
|
- **Job `build-and-package`** (linux/amd64, без артефактов): собирает **headless**-бинарь
|
||||||
|
`ratatoskr-linux-amd64` со вшитым `-X main.updateToken=${secrets.TC_UPDATE_TOKEN}` и
|
||||||
**публикует в Gitea Packages** — только на `main`, сразу в версию `commit-<sha7>/`
|
**публикует в Gitea Packages** — только на `main`, сразу в версию `commit-<sha7>/`
|
||||||
(псевдо-версия `latest` НЕ используется — см. автообновление). Плюс companion-файлы
|
(псевдо-версия `latest` НЕ используется — см. автообновление). Плюс companion-файлы
|
||||||
`<file>.version` и `<file>.sha256`.
|
`<file>.version` и `<file>.sha256`.
|
||||||
|
|
||||||
|
**Windows-бинарь с UI в CI НЕ собирается** (нужен cgo + C-компилятор). Он собирается
|
||||||
|
и публикуется локально скриптом `scripts/build-publish-ui.ps1` (см. «Локальная сборка UI-бинаря»).
|
||||||
|
|
||||||
Секреты/vars: `TC_GITEA_TOKEN` (write:packages), `TC_UPDATE_TOKEN` (read:package),
|
Секреты/vars: `TC_GITEA_TOKEN` (write:packages), `TC_UPDATE_TOKEN` (read:package),
|
||||||
`GIT_MAIN_URL`.
|
`GIT_MAIN_URL`.
|
||||||
|
|
||||||
@@ -199,9 +235,12 @@ update:
|
|||||||
### Как опубликовать новую версию
|
### Как опубликовать новую версию
|
||||||
|
|
||||||
1. Внеси правки, коммитни, запуши в `main`.
|
1. Внеси правки, коммитни, запуши в `main`.
|
||||||
2. CI соберёт оба бинаря со вшитым `TC_UPDATE_TOKEN` и опубликует в
|
2. CI соберёт `ratatoskr-linux-amd64` (headless) со вшитым `TC_UPDATE_TOKEN` и опубликует в
|
||||||
`.../generic/ratatoskr/commit-<sha7>/` (бинарь + `.version` + `.sha256`).
|
`.../generic/ratatoskr/commit-<sha7>/` (бинарь + `.version` + `.sha256`).
|
||||||
3. На обновляемой машине: бот сам уведомит о новой версии → `/update`.
|
3. Если в этой версии есть изменения UI — дополнительно собрать и опубликовать
|
||||||
|
Windows-бинарь с окном: `scripts/build-publish-ui.ps1` (добавит
|
||||||
|
`ratatoskr-windows-amd64.exe` в ту же версию).
|
||||||
|
4. На обновляемой машине: бот сам уведомит о новой версии → `/update`.
|
||||||
|
|
||||||
Проверку автообновления после публикации гоняет владелец на своей
|
Проверку автообновления после публикации гоняет владелец на своей
|
||||||
Windows-машине (не прогоняется агентом).
|
Windows-машине (не прогоняется агентом).
|
||||||
|
|||||||
6
scripts/.gitea-creds.example
Normal file
6
scripts/.gitea-creds.example
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Секреты для scripts/build-publish-ui.ps1 — НЕ коммитить (git-ignored).
|
||||||
|
# Скопируйте этот файл в scripts/.gitea-creds и заполните реальные значения.
|
||||||
|
# Формат: по одной `ключ=значение` на строку, строки с # — комментарии.
|
||||||
|
GITEA_TOKEN=write:packages-токен
|
||||||
|
UPDATE_TOKEN=read:package-токен
|
||||||
|
GIT_MAIN_URL=http://gitea.hal9000.home
|
||||||
109
scripts/build-publish-ui.ps1
Normal file
109
scripts/build-publish-ui.ps1
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
<#
|
||||||
|
build-publish-ui.ps1 — локальная сборка Windows-бинаря с UI (Fyne) и публикация в Gitea Packages.
|
||||||
|
|
||||||
|
Почему локально: Fyne-окно требует cgo + C-компилятор (MinGW/gcc), которых нет в CI.
|
||||||
|
CI собирает ТОЛЬКО headless-linux (см. .gitea/workflows/ci.yaml). Windows-бинарь
|
||||||
|
с графическим окном собирается на Windows-машине Камиля и публикуется скриптом ниже
|
||||||
|
в ту же версию commit-<sha7>, что и CI, с теми же companion-файлами (.version/.sha256),
|
||||||
|
чтобы автообновление (U4 checksum, ResolveLatest) работало без изменений.
|
||||||
|
|
||||||
|
Требования:
|
||||||
|
- Go с доступным C-компилятором (CGO_ENABLED=1). WinLibs gcc: см. память
|
||||||
|
`mem:toolchain/cgo-winlibs-gcc` — bin нужно добавить в PATH перед запуском.
|
||||||
|
- Файл scripts/.gitea-creds (git-ignored, см. ниже) с токенами.
|
||||||
|
Формат (по одной `ключ=значение` на строку):
|
||||||
|
GITEA_TOKEN=write:packages-токен
|
||||||
|
UPDATE_TOKEN=read:package-токен
|
||||||
|
GIT_MAIN_URL=http://gitea.hal9000.home
|
||||||
|
- Ветка уже запушена в `main` (VERSION = commit-<sha7> от текущего HEAD).
|
||||||
|
|
||||||
|
Пример:
|
||||||
|
powershell -ExecutionPolicy Bypass -File scripts/build-publish-ui.ps1
|
||||||
|
#>
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||||
|
$RepoRoot = Split-Path -Parent $ScriptDir
|
||||||
|
$CredsFile = Join-Path $ScriptDir ".gitea-creds"
|
||||||
|
$Package = "ratatoskr"
|
||||||
|
$Owner = "kamelion"
|
||||||
|
$Filename = "ratatoskr-windows-amd64.exe"
|
||||||
|
|
||||||
|
Set-Location $RepoRoot
|
||||||
|
|
||||||
|
# --- 0. Проверка C-тулчейна ---
|
||||||
|
if ($env:CGO_ENABLED -eq "0") { Write-Error "CGO_ENABLED=0 — нужен C-компилятор (MinGW). Уберите его из env." }
|
||||||
|
if (-not (Get-Command gcc -ErrorAction SilentlyContinue)) {
|
||||||
|
Write-Host "gcc не найден в PATH. Пример (WinLibs):"
|
||||||
|
Write-Host ' $p = "<...>\mingw64\bin"; $env:Path = "$p;$env:Path"'
|
||||||
|
Write-Error "C-компилятор gcc не найден."
|
||||||
|
}
|
||||||
|
Write-Host "[ok] gcc: $((gcc --version | Select-Object -First 1))"
|
||||||
|
|
||||||
|
# --- 1. Чтение секретов ---
|
||||||
|
if (-not (Test-Path $CredsFile)) {
|
||||||
|
Write-Error "Нет файла секретов: $CredsFile`nФормат: GITEA_TOKEN=... / UPDATE_TOKEN=... / GIT_MAIN_URL=..."
|
||||||
|
}
|
||||||
|
$creds = @{}
|
||||||
|
Get-Content $CredsFile | ForEach-Object {
|
||||||
|
$line = $_.Trim()
|
||||||
|
if ($line -and -not $line.StartsWith("#")) {
|
||||||
|
$kv = $line.Split("=", 2)
|
||||||
|
if ($kv.Count -eq 2) { $creds[$kv[0].Trim()] = $kv[1].Trim() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$giteaToken = $creds["GITEA_TOKEN"]
|
||||||
|
$updateToken = $creds["UPDATE_TOKEN"]
|
||||||
|
$giteaUrl = $creds["GIT_MAIN_URL"]
|
||||||
|
if (-not $giteaToken) { Write-Error "В $CredsFile нет GITEA_TOKEN (нужен write:packages)." }
|
||||||
|
if (-not $giteaUrl) { Write-Error "В $CredsFile нет GIT_MAIN_URL." }
|
||||||
|
|
||||||
|
# --- 2. Версия = commit-<sha7> текущего HEAD (совпадает с именованием CI) ---
|
||||||
|
$sha = (git rev-parse --short HEAD).Trim()
|
||||||
|
if (-not $sha) { Write-Error "git rev-parse --short HEAD не дал хэш." }
|
||||||
|
$Version = "commit-$sha"
|
||||||
|
Write-Host "[build] VERSION=$Version FILENAME=$Filename"
|
||||||
|
|
||||||
|
# --- 3. Сборка (cgo + UI) ---
|
||||||
|
$env:CGO_ENABLED = "1"
|
||||||
|
$out = Join-Path $RepoRoot $Filename
|
||||||
|
$ldflags = "-s -w -X main.version=${Version} -X main.updateToken=${updateToken}"
|
||||||
|
Write-Host "[build] go build -ldflags=... -o $Filename"
|
||||||
|
$goArgs = @("build", "-ldflags=$ldflags", "-o", $out, "./cmd/ratatoskr/")
|
||||||
|
go $goArgs
|
||||||
|
if ($LASTEXITCODE -ne 0) { Write-Error "go build завершился с кодом $LASTEXITCODE" }
|
||||||
|
|
||||||
|
# --- 4. Companion-файлы (.version, .sha256) ---
|
||||||
|
$sha256Hex = (Get-FileHash -Algorithm SHA256 $out).Hash.ToLower()
|
||||||
|
$verFile = "$out.version"
|
||||||
|
$sumFile = "$out.sha256"
|
||||||
|
Set-Content -Path $verFile -Value $Version -NoNewline -Encoding ascii
|
||||||
|
Set-Content -Path $sumFile -Value $sha256Hex -NoNewline -Encoding ascii
|
||||||
|
Write-Host "[ok] bin: $out ($([math]::Round((Get-Item $out).Length/1MB,1)) MB)"
|
||||||
|
Write-Host "[ok] sha256: $sha256Hex"
|
||||||
|
|
||||||
|
# --- 5. Публикация в Gitea Packages ---
|
||||||
|
$api = "$giteaUrl/api/packages/$Owner/generic/$Package/$Version"
|
||||||
|
$files = @($Filename, "$Filename.version", "$Filename.sha256")
|
||||||
|
foreach ($f in $files) {
|
||||||
|
Write-Host "[put] $api/$f"
|
||||||
|
curl.exe -sS -X PUT `
|
||||||
|
-H "Authorization: token $giteaToken" `
|
||||||
|
-H "Content-Type: application/octet-stream" `
|
||||||
|
"$api/$f" `
|
||||||
|
--data-binary "@$f"
|
||||||
|
if ($LASTEXITCODE -ne 0) { Write-Error "curl PUT $f завершился с кодом $LASTEXITCODE" }
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- 6. Самопроверка: читаем .sha256 обратно и сверяем (контракт U4) ---
|
||||||
|
Write-Host "[verify] перечитываю $Filename.sha256 из Gitea..."
|
||||||
|
$remoteSum = (curl.exe -sS -H "Authorization: token $giteaToken" "$api/$Filename.sha256").Trim()
|
||||||
|
if ($remoteSum -ne $sha256Hex) {
|
||||||
|
Write-Error "Проверка не сошлась: remote=$remoteSum local=$sha256Hex"
|
||||||
|
}
|
||||||
|
$remoteVer = (curl.exe -sS -H "Authorization: token $giteaToken" "$api/$Filename.version").Trim()
|
||||||
|
if ($remoteVer -ne $Version) {
|
||||||
|
Write-Error "Версия не сошлась: remote=$remoteVer local=$Version"
|
||||||
|
}
|
||||||
|
Write-Host "[ok] опубликовано и проверено: $Version/$Filename (+.version, +.sha256)"
|
||||||
Reference in New Issue
Block a user