ci: parallelize GitHub releases and fix WSL path resolution
This commit is contained in:
6 files changed
+288
-59
No files matched your search
@@ -144,6 +144,14 @@ Implementation notes:
|
||||
|
||||
## CI (GitHub)
|
||||
|
||||
- `.github/workflows/release.yml` builds router binaries, UI, x86-64 CC and
|
||||
ARM64 CC in parallel. CC uses matching Ubuntu 24.04 runners and native Cargo;
|
||||
Cross is used only for the ARMv7-musl router binaries. A final job downloads
|
||||
their artifacts, packages CC bundles and publishes after every build succeeds.
|
||||
- GitHub's native GNU binaries inherit its runner's glibc requirements. Use the
|
||||
Gitea bundles for older deployment hosts, checking that its build actually
|
||||
used Zig's configured baseline. Gitea retains one job for `--once` runners.
|
||||
|
||||
- Defined in `.github/workflows/ci.yml` on pushes/PRs to `main` or `master`:
|
||||
- **`rust` job:** `cargo fmt --check`, `clippy -D warnings`, `cargo test --workspace` on `ubuntu-latest`.
|
||||
- **`ui` job:** under `ui/`, `pnpm install --frozen-lockfile`, then `pnpm run typecheck`, `format:check`, and `build` (mirrors what you need before packaging the control-plane bundle). GitHub sets `CI=true` for the runner; pnpm uses lockfile `ui/pnpm-lock.yaml` for cache.
|
||||
|
||||
@@ -67,6 +67,12 @@ From Windows PowerShell, using the WSL wrapper:
|
||||
|
||||
Path control (binary and config are independent):
|
||||
|
||||
When called from PowerShell inside WSL, absolute POSIX paths pass through
|
||||
unchanged. Windows paths are converted using the selected distro's `wslpath`.
|
||||
Relative runner home, binary and config paths resolve from the current PowerShell
|
||||
directory. Conversion also supports paths that have not been created yet.
|
||||
The helper, runner home and config paths must be accessible in that distro.
|
||||
|
||||
```powershell
|
||||
./scripts/act_runner_wsl.ps1 -Action status `
|
||||
-RunnerBin /home/lda/gitea-runner/act_runner `
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
param(
|
||||
[ValidateSet("update", "register", "start", "stop", "status")]
|
||||
[string]$Action = "start",
|
||||
[string]$Distro = $(if ($env:WAKEY_WSL_DISTRO) { $env:WAKEY_WSL_DISTRO } else { "FedoraLinux-43" }),
|
||||
[string]$Distro = $( $env:WAKEY_WSL_DISTRO ?? "FedoraLinux-43" ),
|
||||
[string]$RunnerHome,
|
||||
[string]$RunnerBin = "/home/lda/gitea-runner/act_runner",
|
||||
[string]$ConfigPath,
|
||||
@@ -22,7 +22,7 @@ if (-not (Test-Path $scriptWin)) {
|
||||
throw "Missing Fedora runner helper: $scriptWin"
|
||||
}
|
||||
|
||||
$scriptLinux = (& wsl.exe -d $Distro -e wslpath -a "$scriptWin").Trim()
|
||||
$scriptLinux = ConvertTo-WslPath -WindowsPath $scriptWin -Distro $Distro
|
||||
if (-not $scriptLinux) {
|
||||
throw "Failed to resolve WSL path for $scriptWin"
|
||||
}
|
||||
@@ -30,21 +30,19 @@ if (-not $scriptLinux) {
|
||||
if (-not $RunnerHome) {
|
||||
$repoRootWin = Split-Path -Parent $PSScriptRoot
|
||||
$defaultRunnerHomeWin = Join-Path $repoRootWin "ar_data/wsl_runner"
|
||||
$RunnerHome = (& wsl.exe -d $Distro -e wslpath -a "$defaultRunnerHomeWin").Trim()
|
||||
if (-not $RunnerHome) {
|
||||
throw "Failed to resolve WSL runner home for $defaultRunnerHomeWin"
|
||||
}
|
||||
$RunnerHome = $defaultRunnerHomeWin
|
||||
}
|
||||
|
||||
if (-not $ConfigPath) {
|
||||
$repoRootWin = Split-Path -Parent $PSScriptRoot
|
||||
$defaultConfigWin = Join-Path $repoRootWin "ar_data/wsl_runner/config.yaml"
|
||||
$ConfigPath = (& wsl.exe -d $Distro -e wslpath -a "$defaultConfigWin").Trim()
|
||||
if (-not $ConfigPath) {
|
||||
throw "Failed to resolve WSL config path for $defaultConfigWin"
|
||||
}
|
||||
$ConfigPath = $defaultConfigWin
|
||||
}
|
||||
|
||||
$RunnerHome = ConvertTo-WslPath -Path $RunnerHome -Distro $Distro
|
||||
$RunnerBin = ConvertTo-WslPath -Path $RunnerBin -Distro $Distro
|
||||
$ConfigPath = ConvertTo-WslPath -Path $ConfigPath -Distro $Distro
|
||||
|
||||
$parts = @("bash", (Quote-ShArg $scriptLinux), (Quote-ShArg $Action), "--runner-home", (Quote-ShArg $RunnerHome))
|
||||
$parts += @("--runner-bin", (Quote-ShArg $RunnerBin), "--config-path", (Quote-ShArg $ConfigPath))
|
||||
if ($ServerUrl) { $parts += @("--server-url", (Quote-ShArg $ServerUrl)) }
|
||||
|
||||
+38
-1
@@ -27,8 +27,15 @@ function Test-IsWsl {
|
||||
return $false
|
||||
}
|
||||
|
||||
# With -Distro, resolve local relative paths from the PowerShell working
|
||||
# directory and convert Windows paths with the distro's mount configuration.
|
||||
# Without it, keep the existing mapping used by SCP callers, including remote destinations.
|
||||
function ConvertTo-WslPath {
|
||||
param([string]$WindowsPath)
|
||||
param(
|
||||
[Alias('Path')]
|
||||
[string]$WindowsPath,
|
||||
[string]$Distro
|
||||
)
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($WindowsPath)) {
|
||||
return $WindowsPath
|
||||
@@ -39,6 +46,36 @@ function ConvertTo-WslPath {
|
||||
return $WindowsPath
|
||||
}
|
||||
|
||||
# wslpath expects a Windows input here. Use the selected distro's mount
|
||||
# configuration when requested, while keeping existing POSIX paths intact.
|
||||
if ($Distro) {
|
||||
# Absolute Windows paths can be supplied even from Linux PowerShell.
|
||||
# Relative inputs use the filesystem provider without requiring a file
|
||||
# to exist, which is important for a new runner home/config.
|
||||
if ($WindowsPath -notmatch '^[A-Za-z]:[\\/]|^\\\\') {
|
||||
$provider = $null
|
||||
$drive = $null
|
||||
$WindowsPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath(
|
||||
$WindowsPath, [ref]$provider, [ref]$drive)
|
||||
if ($provider.Name -ne 'FileSystem') {
|
||||
throw "WSL paths must use the filesystem provider"
|
||||
}
|
||||
if ($WindowsPath.StartsWith('/')) {
|
||||
return $WindowsPath
|
||||
}
|
||||
}
|
||||
$output = & wsl.exe -d $Distro -e wslpath -a "$WindowsPath"
|
||||
$exitCode = $LASTEXITCODE
|
||||
if ($exitCode -ne 0) {
|
||||
throw "wslpath failed for '$WindowsPath' in '$Distro' (exit $exitCode)"
|
||||
}
|
||||
$converted = ($output -join "`n").Trim()
|
||||
if (-not $converted) {
|
||||
throw "wslpath returned no path for '$WindowsPath' in '$Distro'"
|
||||
}
|
||||
return $converted
|
||||
}
|
||||
|
||||
# Handle Windows path (e.g., C:\path\to\file -> /mnt/c/path/to/file)
|
||||
if ($WindowsPath -match '^([A-Z]):(.*)$') {
|
||||
$drive = $matches[1].ToLower()
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env pwsh
|
||||
# Run with pwsh -NoProfile -File scripts/tests/wsl_paths.ps1.
|
||||
$ErrorActionPreference = 'Stop'
|
||||
. "$PSScriptRoot/../lib.ps1"
|
||||
|
||||
# Intercept WSL so these tests never start or register a real runner.
|
||||
$global:WakeyWslTest = @{
|
||||
Calls = [System.Collections.Generic.List[object]]::new()
|
||||
ExitCode = 0
|
||||
# Fake conversion response, chosen to exercise a path containing spaces.
|
||||
Output = '/mnt/c/runner home/config.yaml'
|
||||
}
|
||||
function global:wsl.exe {
|
||||
$global:WakeyWslTest.Calls.Add(@($args))
|
||||
$global:LASTEXITCODE = $global:WakeyWslTest.ExitCode
|
||||
if ($args[3] -eq 'wslpath') { $global:WakeyWslTest.Output }
|
||||
}
|
||||
|
||||
foreach ($path in @('/home/lda/repo/scripts/helper.sh', '/mnt/c/runner home/config.yaml')) {
|
||||
$result = ConvertTo-WslPath -WindowsPath $path -Distro TestDistro
|
||||
if ($result -cne $path) { throw "POSIX path changed: $result" }
|
||||
}
|
||||
if ($global:WakeyWslTest.Calls.Count -ne 0) { throw 'POSIX paths invoked wslpath' }
|
||||
|
||||
foreach ($path in @('C:\runner home\config.yaml', 'C:/runner home/config.yaml', '\\server\share\runner home\config.yaml')) {
|
||||
$global:WakeyWslTest.Calls.Clear()
|
||||
$result = ConvertTo-WslPath -WindowsPath $path -Distro TestDistro
|
||||
if ($result -cne '/mnt/c/runner home/config.yaml') { throw 'Mock Windows conversion failed' }
|
||||
$call = $global:WakeyWslTest.Calls[0]
|
||||
if (($call[0..4] -join ' ') -cne '-d TestDistro -e wslpath -a' -or $call[5] -cne $path) {
|
||||
throw 'Distro or Windows path was not passed intact'
|
||||
}
|
||||
}
|
||||
if ((ConvertTo-WslPath 'D:\runner\config.yaml') -cne '/mnt/d/runner/config.yaml') {
|
||||
throw 'Existing drive conversion changed'
|
||||
}
|
||||
foreach ($path in @('root@router:/root/.bin/', 'relative/file')) {
|
||||
if ((ConvertTo-WslPath $path) -cne $path) { throw 'Existing SCP path handling changed' }
|
||||
}
|
||||
|
||||
# Resolve missing relative paths from the PS location, including dot segments.
|
||||
$temp = Join-Path ([System.IO.Path]::GetTempPath()) "wakey-wsl-paths-$([guid]::NewGuid())"
|
||||
New-Item -ItemType Directory -Path $temp | Out-Null
|
||||
Push-Location $temp
|
||||
try {
|
||||
foreach ($relative in @('new folder/config.yaml', '.\new folder\config.yaml', 'nested/../new folder/config.yaml')) {
|
||||
$expected = Join-Path $temp 'new folder/config.yaml'
|
||||
$global:WakeyWslTest.Calls.Clear()
|
||||
$result = ConvertTo-WslPath -Path $relative -Distro TestDistro
|
||||
if ($IsWindows) {
|
||||
if ($global:WakeyWslTest.Calls[0][5] -cne $expected) { throw 'Relative Windows path was not resolved before conversion' }
|
||||
} elseif ($result -cne $expected -or $global:WakeyWslTest.Calls.Count -ne 0) {
|
||||
throw "Relative POSIX path was not resolved: $result"
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Pop-Location
|
||||
Remove-Item -Recurse -Force $temp
|
||||
}
|
||||
|
||||
foreach ($case in @(
|
||||
@{ ExitCode = 1; Output = '' },
|
||||
@{ ExitCode = 1; Output = '/mnt/c/bad' },
|
||||
@{ ExitCode = 0; Output = '' }
|
||||
)) {
|
||||
$global:WakeyWslTest.ExitCode = $case.ExitCode
|
||||
$global:WakeyWslTest.Output = $case.Output
|
||||
$caught = $false
|
||||
try { ConvertTo-WslPath -WindowsPath 'C:\bad' -Distro TestDistro | Out-Null }
|
||||
catch { $caught = $_.Exception.Message -like 'wslpath *' }
|
||||
if (-not $caught) { throw 'Failed/empty wslpath result was accepted' }
|
||||
}
|
||||
|
||||
if (-not $IsWindows) {
|
||||
$global:WakeyWslTest.Calls.Clear()
|
||||
$global:WakeyWslTest.ExitCode = 0
|
||||
& "$PSScriptRoot/../act_runner_wsl.ps1" -Action status -Distro TestDistro
|
||||
if ($global:WakeyWslTest.Calls.Count -ne 1 -or $global:WakeyWslTest.Calls[0][3] -ne 'bash') {
|
||||
throw 'POSIX wrapper paths should invoke only the runner command'
|
||||
}
|
||||
$command = $global:WakeyWslTest.Calls[0][5]
|
||||
if ($command -notlike '*act_runner_fedora.sh*' -or $command -notlike '*ar_data/wsl_runner/config.yaml*') {
|
||||
throw 'Wrapper did not resolve default paths'
|
||||
}
|
||||
$global:WakeyWslTest.Calls.Clear()
|
||||
$global:WakeyWslTest.Output = '/mnt/c/runner home/config.yaml'
|
||||
& "$PSScriptRoot/../act_runner_wsl.ps1" -Action status -Distro TestDistro `
|
||||
-RunnerHome 'new runner home' -RunnerBin 'bin/act_runner' -ConfigPath 'C:\runner home\config.yaml'
|
||||
if ($global:WakeyWslTest.Calls.Count -ne 2 -or $global:WakeyWslTest.Calls[0][3] -ne 'wslpath') {
|
||||
throw 'Explicit Windows config should be converted once before running bash'
|
||||
}
|
||||
$command = $global:WakeyWslTest.Calls[1][5]
|
||||
foreach ($path in @((Join-Path (Get-Location).Path 'new runner home'), (Join-Path (Get-Location).Path 'bin/act_runner'), '/mnt/c/runner home/config.yaml')) {
|
||||
if (-not $command.Contains((Quote-ShArg $path))) { throw "Explicit path missing from runner command: $path" }
|
||||
}
|
||||
}
|
||||
Write-Host 'WSL path tests passed'
|
||||
Reference in new issue
Block a user