Files
MeshCore/ci/build-local.ps1

184 lines
7.8 KiB
PowerShell
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#Requires -Version 5.1
<#
.SYNOPSIS
Локальная сборка прошивок MeshCore под Windows с публикацией в Gitea.
.DESCRIPTION
Запускает ci/build-firmwares.sh (тот же путь сборки, что и в CI: build.sh, merge-bin,
uf2) через Git Bash, а готовые файлы из out/ при необходимости прикрепляет к релизу
в Gitea. Сам сервер при этом не нагружается — на него уходит только загрузка файлов.
Зачем: на VPS всего 1 CPU, полный набор прошивок собирается там часами. Локально —
быстрее, а результат удобно раздать через релиз Gitea.
.PARAMETER Targets
Список env через запятую. Пусто — набор устройств форка из ci/build-firmwares.sh.
.PARAMETER Match
Подстрока имени env: собрать все подходящие (например, promicro).
.PARAMETER Version
FIRMWARE_VERSION — попадает в имена файлов (по умолчанию local).
.PARAMETER Publish
Создать релиз в Gitea и прикрепить к нему файлы из out/.
.PARAMETER Tag
Тег для релиза (обязателен с -Publish). Если тега в репозитории нет — он будет создан
от текущего коммита.
.PARAMETER Public
Опубликовать релиз сразу. Без этого флага создаётся черновик.
.PARAMETER Token
Токен Gitea с правом write:repository. По умолчанию берётся из переменной GITEA_TOKEN.
.EXAMPLE
.\ci\build-local.ps1 -Match promicro -Version v1.0.0
.EXAMPLE
.\ci\build-local.ps1 -Version v1.0.0 -Publish -Tag companion-v1.0.0
#>
param(
[string]$Targets = '',
[string]$Match = '',
[string]$Version = 'local',
[switch]$Publish,
[string]$Tag = '',
[switch]$Public,
[switch]$SkipBuild,
[string]$Token = $env:GITEA_TOKEN,
[string]$GiteaUrl = 'https://git.meshinfo.ru',
[string]$Repo = 'shade/MeshCore'
)
$ErrorActionPreference = 'Stop'
$root = Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path)
Push-Location $root
try {
# --- ищем Git Bash -------------------------------------------------------
$bash = @(
"$env:ProgramFiles\Git\bin\bash.exe",
"${env:ProgramFiles(x86)}\Git\bin\bash.exe",
"$env:LOCALAPPDATA\Programs\Git\bin\bash.exe"
) | Where-Object { Test-Path $_ } | Select-Object -First 1
if (-not $bash) { $bash = (Get-Command bash -ErrorAction SilentlyContinue).Source }
if (-not $bash) { throw 'Git Bash не найден — установите Git for Windows' }
Write-Host "Git Bash: $bash"
# --- ищем рабочий python3 для build.sh ----------------------------------
# В Git Bash путь должен быть в unix-виде: C:\Tools\python.exe -> /c/Tools/python.exe
$pythonCandidates = @(
"$env:USERPROFILE\.platformio\penv\Scripts\python.exe",
'C:\Espressif\tools\python\python.exe'
)
$python = $pythonCandidates | Where-Object { Test-Path $_ } | Select-Object -First 1
if (-not $python) {
$cmd = Get-Command python -ErrorAction SilentlyContinue
if ($cmd) { $python = $cmd.Source }
}
if (-not $python) { throw 'Не найден python.exe (нужен для build.sh)' }
$pythonUnix = '/' + $python.Substring(0, 1).ToLower() + $python.Substring(2).Replace('\', '/')
Write-Host "python3 для build.sh: $pythonUnix"
# --- pio должен быть доступен и для bash ---------------------------------
$pioDir = Join-Path $env:USERPROFILE '.platformio\penv\Scripts'
if ((Test-Path (Join-Path $pioDir 'pio.exe')) -and ($env:PATH -notlike "*$pioDir*")) {
$env:PATH = "$pioDir;$env:PATH"
}
$pioCheck = & $bash -c 'command -v pio' 2>$null
if (-not $pioCheck) { throw 'PlatformIO (pio) не найден в PATH — установите PlatformIO Core' }
Write-Host "pio: $pioCheck"
# --- сборка --------------------------------------------------------------
$env:FIRMWARE_VERSION = $Version
$env:TARGETS = $Targets
$env:MATCH = $Match
$env:PYTHON3 = $pythonUnix
# out/ чистим, иначе в релиз попадут файлы прошлых сборок
$outDir = Join-Path $root 'out'
$buildExit = 0
if ($SkipBuild) {
Write-Host ''
Write-Host 'сборка пропущена (-SkipBuild): публикую то, что уже лежит в out/' -ForegroundColor Yellow
}
else {
if (Test-Path $outDir) { Get-ChildItem $outDir -File | Remove-Item -Force }
Write-Host ''
Write-Host "=== сборка (версия $Version) ===" -ForegroundColor Cyan
& $bash 'ci/build-firmwares.sh'
$buildExit = $LASTEXITCODE
}
$files = @(Get-ChildItem $outDir -File -ErrorAction SilentlyContinue)
Write-Host ''
Write-Host "файлов в out/: $($files.Count)"
$files | ForEach-Object { ' {0} {1:N0} байт' -f $_.Name, $_.Length }
if ($buildExit -ne 0) { Write-Warning "часть env не собралась (код $buildExit)" }
# --- публикация релиза ---------------------------------------------------
if ($Publish) {
if (-not $Tag) { throw 'С -Publish нужно указать -Tag, например -Tag companion-v1.0.0' }
if (-not $Token) { throw 'Нужен токен Gitea: -Token <токен> или переменная окружения GITEA_TOKEN' }
if ($files.Count -eq 0) { throw 'В out/ нет файлов — публиковать нечего' }
$api = "$GiteaUrl/api/v1/repos/$Repo"
$headers = @{ Authorization = "token $Token"; 'Content-Type' = 'application/json' }
# тег создаём, если его ещё нет (на текущем коммите).
# В Gitea тег создаётся через POST /tags (у /git/refs нет метода POST).
$tagExists = $true
try { Invoke-RestMethod -Method Get -Uri "$api/tags/$Tag" -Headers $headers | Out-Null }
catch { $tagExists = $false }
if (-not $tagExists) {
$sha = (git -C $root rev-parse HEAD).Trim()
$body = @{ tag_name = $Tag; target = $sha } | ConvertTo-Json -Compress
Invoke-RestMethod -Method Post -Uri "$api/tags" -Headers $headers -Body $body | Out-Null
Write-Host "создан тег $Tag на коммите $($sha.Substring(0,8))"
}
else {
Write-Host "тег $Tag уже существует"
}
$draft = if ($Public) { 'false' } else { 'true' }
$releaseBody = @{
tag_name = $Tag
name = $Tag
draft = ($draft -eq 'true')
prerelease = $false
target_commitish = 'main'
} | ConvertTo-Json -Compress -Depth 3
try {
$release = Invoke-RestMethod -Method Post -Uri "$api/releases" -Headers $headers -Body $releaseBody
Write-Host "релиз #$($release.id) создан ($(if ($Public) { 'опубликован' } else { 'черновик' }))"
}
catch {
throw "Не удалось создать релиз: $($_.Exception.Message)"
}
foreach ($f in $files) {
& curl.exe -sS -X POST "$api/releases/$($release.id)/assets?name=$($f.Name)" `
-H "Authorization: token $Token" -F "attachment=@$($f.FullName)" | Out-Null
if ($LASTEXITCODE -ne 0) { Write-Warning "не загрузился: $($f.Name)" }
else { Write-Host " прикреплён $($f.Name)" }
}
Write-Host ''
Write-Host "Релиз: $GiteaUrl/$Repo/releases" -ForegroundColor Green
}
else {
Write-Host ''
Write-Host 'Файлы готовы в out/. Чтобы прикрепить их к релизу Gitea, добавьте -Publish -Tag <тег>' -ForegroundColor Yellow
}
exit $buildExit
}
finally {
Pop-Location
}