ci / rust (push) Canceled after 0s
ci / native-client (push) Canceled after 0s
ci / package-windows-client (push) Canceled after 0s
ci / linux-agent (push) Canceled after 0s
ci / edge-service (push) Canceled after 0s
ci / coturn-pop (push) Canceled after 0s
ci / package-windows-host (push) Canceled after 0s
163 lines
11 KiB
PowerShell
163 lines
11 KiB
PowerShell
[CmdletBinding()]
|
|
param()
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
$repoRoot = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..\..'))
|
|
$targetRoot = Join-Path $repoRoot 'target'
|
|
$artifactsRoot = Join-Path $repoRoot 'artifacts'
|
|
$buildRoot = Join-Path $targetRoot 'package-linux-musl'
|
|
$gnuTar = 'C:\Program Files\Git\usr\bin\tar.exe'
|
|
$gzip = 'C:\Program Files\Git\usr\bin\gzip.exe'
|
|
$fileTool = 'C:\Program Files\Git\usr\bin\file.exe'
|
|
|
|
function Invoke-Checked {
|
|
param([Parameter(Mandatory)][scriptblock]$Command, [Parameter(Mandatory)][string]$Description)
|
|
& $Command
|
|
if ($LASTEXITCODE -ne 0) { throw "$Description failed with exit code $LASTEXITCODE" }
|
|
}
|
|
|
|
function Assert-PathWithin {
|
|
param([Parameter(Mandatory)][string]$Path, [Parameter(Mandatory)][string]$Root)
|
|
$fullPath = [IO.Path]::GetFullPath($Path)
|
|
$prefix = [IO.Path]::GetFullPath($Root).TrimEnd([IO.Path]::DirectorySeparatorChar) + [IO.Path]::DirectorySeparatorChar
|
|
if (-not $fullPath.StartsWith($prefix, [StringComparison]::OrdinalIgnoreCase)) {
|
|
throw "Refusing to modify a path outside $Root"
|
|
}
|
|
}
|
|
|
|
foreach ($tool in @($gnuTar, $gzip, $fileTool)) {
|
|
if (-not (Test-Path -LiteralPath $tool -PathType Leaf)) { throw "Required build tool is missing: $tool" }
|
|
}
|
|
|
|
$ndkRoot = if ($env:ANDROID_NDK_HOME) {
|
|
Split-Path -Parent ([IO.Path]::GetFullPath($env:ANDROID_NDK_HOME))
|
|
} else {
|
|
Join-Path $env:LOCALAPPDATA 'Android\Sdk\ndk'
|
|
}
|
|
$ndk = Get-ChildItem -LiteralPath $ndkRoot -Directory -ErrorAction SilentlyContinue |
|
|
Sort-Object Name -Descending |
|
|
Where-Object { Test-Path -LiteralPath (Join-Path $_.FullName 'toolchains\llvm\prebuilt\windows-x86_64\bin\x86_64-linux-android21-clang.cmd') } |
|
|
Select-Object -First 1
|
|
if ($null -eq $ndk) { throw 'Android NDK LLVM is required for the local musl build.' }
|
|
$ndkBin = Join-Path $ndk.FullName 'toolchains\llvm\prebuilt\windows-x86_64\bin'
|
|
$clang = Join-Path $ndkBin 'x86_64-linux-android21-clang.cmd'
|
|
$llvmAr = Join-Path $ndkBin 'llvm-ar.exe'
|
|
$llvmStrip = Join-Path $ndkBin 'llvm-strip.exe'
|
|
$rustSysroot = (& rustc --print sysroot).Trim()
|
|
if ($LASTEXITCODE -ne 0) { throw 'Unable to locate the active Rust sysroot.' }
|
|
$rustHost = ((& rustc -vV | Select-String '^host: ').Line -replace '^host:\s*', '').Trim()
|
|
$rustLld = Join-Path $rustSysroot "lib\rustlib\$rustHost\bin\rust-lld.exe"
|
|
|
|
Push-Location $repoRoot
|
|
try {
|
|
$metadata = cargo metadata --no-deps --format-version 1 | ConvertFrom-Json
|
|
if ($LASTEXITCODE -ne 0) { throw 'Unable to read Cargo workspace metadata.' }
|
|
$package = $metadata.packages | Where-Object name -eq 'remotedesk-agent-runtime' | Select-Object -First 1
|
|
$version = [string]$package.version
|
|
if ($version -notmatch '^\d+\.\d+\.\d+$') { throw "Invalid package version: $version" }
|
|
|
|
$env:CC_x86_64_unknown_linux_musl = $clang
|
|
$env:AR_x86_64_unknown_linux_musl = $llvmAr
|
|
$env:CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER = $rustLld
|
|
Invoke-Checked -Description 'Static Linux Agent build' -Command {
|
|
cargo build --locked --release --jobs 2 --target x86_64-unknown-linux-musl -p remotedesk-agent-runtime --no-default-features --features gstreamer-h264,wayland-eis
|
|
}
|
|
Assert-PathWithin -Path $buildRoot -Root $targetRoot
|
|
if (Test-Path -LiteralPath $buildRoot) { Remove-Item -LiteralPath $buildRoot -Recurse -Force }
|
|
New-Item -ItemType Directory -Force -Path $buildRoot, $artifactsRoot | Out-Null
|
|
$portableName = "RemoteDesk-Agent-$version-linux-x64"
|
|
$portableRoot = Join-Path $buildRoot $portableName
|
|
New-Item -ItemType Directory -Force -Path (Join-Path $portableRoot 'bin'), `
|
|
(Join-Path $portableRoot 'systemd'), (Join-Path $portableRoot 'config') | Out-Null
|
|
foreach ($binary in @('remotedesk-agentd', 'remotedesk-agent-session', 'remotedesk-shell-session', 'remotedesk-file-session')) {
|
|
$destination = Join-Path $portableRoot "bin\$binary"
|
|
Copy-Item -LiteralPath (Join-Path $targetRoot "x86_64-unknown-linux-musl\release\$binary") -Destination $destination
|
|
Invoke-Checked -Description "Strip $binary" -Command { & $llvmStrip $destination }
|
|
}
|
|
Copy-Item -LiteralPath (Join-Path $PSScriptRoot 'remotedesk-agentd.service') -Destination (Join-Path $portableRoot 'systemd')
|
|
Copy-Item -LiteralPath (Join-Path $PSScriptRoot 'remotedesk-agent-session.service') -Destination (Join-Path $portableRoot 'systemd')
|
|
Copy-Item -LiteralPath (Join-Path $PSScriptRoot 'agent.env') -Destination (Join-Path $portableRoot 'config')
|
|
Copy-Item -LiteralPath (Join-Path $PSScriptRoot 'install.sh') -Destination $portableRoot
|
|
Copy-Item -LiteralPath (Join-Path $PSScriptRoot 'uninstall.sh') -Destination $portableRoot
|
|
Copy-Item -LiteralPath (Join-Path $PSScriptRoot 'README.md') -Destination $portableRoot
|
|
|
|
$hashLines = Get-ChildItem -LiteralPath $portableRoot -Recurse -File | Sort-Object FullName | ForEach-Object {
|
|
$relative = [IO.Path]::GetRelativePath($portableRoot, $_.FullName).Replace('\', '/')
|
|
$hash = (Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash.ToLowerInvariant()
|
|
"$hash $relative"
|
|
}
|
|
$hashLines | Set-Content -LiteralPath (Join-Path $portableRoot 'SHA256SUMS.txt') -Encoding ascii
|
|
|
|
$portableTar = Join-Path $buildRoot "$portableName.tar"
|
|
$portableGzip = "$portableTar.gz"
|
|
$portableDirectories = @($portableName, "$portableName/bin", "$portableName/config", "$portableName/systemd")
|
|
$portableExecutables = @("$portableName/install.sh", "$portableName/uninstall.sh", "$portableName/bin/remotedesk-agentd", "$portableName/bin/remotedesk-agent-session", "$portableName/bin/remotedesk-shell-session", "$portableName/bin/remotedesk-file-session")
|
|
$portableData = @("$portableName/README.md", "$portableName/SHA256SUMS.txt", "$portableName/config/agent.env", "$portableName/systemd/remotedesk-agentd.service", "$portableName/systemd/remotedesk-agent-session.service")
|
|
Push-Location $buildRoot
|
|
try {
|
|
Invoke-Checked -Description 'Portable directory archive' -Command { & $gnuTar --force-local --no-recursion --format=gnu --owner=0 --group=0 --mode=0755 -cf $portableTar @portableDirectories }
|
|
Invoke-Checked -Description 'Portable executable archive' -Command { & $gnuTar --force-local --format=gnu --owner=0 --group=0 --mode=0755 -rf $portableTar @portableExecutables }
|
|
Invoke-Checked -Description 'Portable data archive' -Command { & $gnuTar --force-local --format=gnu --owner=0 --group=0 --mode=0644 -rf $portableTar @portableData }
|
|
} finally { Pop-Location }
|
|
Invoke-Checked -Description 'Portable gzip compression' -Command { & $gzip -n -f $portableTar }
|
|
$portableOutput = Join-Path $artifactsRoot "$portableName.tar.gz"
|
|
Move-Item -LiteralPath $portableGzip -Destination $portableOutput -Force
|
|
|
|
$debianRoot = Join-Path $buildRoot 'debian-root'
|
|
New-Item -ItemType Directory -Force -Path (Join-Path $debianRoot 'DEBIAN'), `
|
|
(Join-Path $debianRoot 'usr\bin'), (Join-Path $debianRoot 'usr\libexec'), `
|
|
(Join-Path $debianRoot 'usr\lib\systemd\system'), (Join-Path $debianRoot 'usr\lib\systemd\user'), `
|
|
(Join-Path $debianRoot 'etc\remotedesk'), (Join-Path $debianRoot 'usr\share\doc\remotedesk-agent') | Out-Null
|
|
Copy-Item -LiteralPath (Join-Path $portableRoot 'bin\remotedesk-agentd') -Destination (Join-Path $debianRoot 'usr\bin')
|
|
Copy-Item -LiteralPath (Join-Path $portableRoot 'bin\remotedesk-agent-session') -Destination (Join-Path $debianRoot 'usr\bin')
|
|
Copy-Item -LiteralPath (Join-Path $portableRoot 'bin\remotedesk-shell-session') -Destination (Join-Path $debianRoot 'usr\libexec')
|
|
Copy-Item -LiteralPath (Join-Path $portableRoot 'bin\remotedesk-file-session') -Destination (Join-Path $debianRoot 'usr\libexec')
|
|
Copy-Item -LiteralPath (Join-Path $portableRoot 'systemd\remotedesk-agentd.service') -Destination (Join-Path $debianRoot 'usr\lib\systemd\system')
|
|
Copy-Item -LiteralPath (Join-Path $portableRoot 'systemd\remotedesk-agent-session.service') -Destination (Join-Path $debianRoot 'usr\lib\systemd\user')
|
|
Copy-Item -LiteralPath (Join-Path $portableRoot 'config\agent.env') -Destination (Join-Path $debianRoot 'etc\remotedesk')
|
|
Copy-Item -LiteralPath (Join-Path $portableRoot 'README.md') -Destination (Join-Path $debianRoot 'usr\share\doc\remotedesk-agent\README.md')
|
|
$control = (Get-Content -LiteralPath (Join-Path $PSScriptRoot 'debian\control') -Raw).Replace('@VERSION@', $version).Replace('@ARCH@', 'amd64')
|
|
$control = $control.Replace(', gstreamer1.0-plugins-base, gstreamer1.0-plugins-good, gstreamer1.0-plugins-bad, gstreamer1.0-plugins-ugly', '')
|
|
[IO.File]::WriteAllText((Join-Path $debianRoot 'DEBIAN\control'), $control.Replace("`r`n", "`n"), [Text.UTF8Encoding]::new($false))
|
|
foreach ($script in @('postinst', 'prerm', 'postrm')) {
|
|
Copy-Item -LiteralPath (Join-Path $PSScriptRoot "debian\$script") -Destination (Join-Path $debianRoot "DEBIAN\$script")
|
|
}
|
|
|
|
$debParts = Join-Path $buildRoot 'deb-parts'
|
|
New-Item -ItemType Directory -Force -Path $debParts | Out-Null
|
|
[IO.File]::WriteAllText((Join-Path $debParts 'debian-binary'), "2.0`n", [Text.Encoding]::ASCII)
|
|
$controlTar = Join-Path $debParts 'control.tar'
|
|
Push-Location (Join-Path $debianRoot 'DEBIAN')
|
|
try {
|
|
Invoke-Checked -Description 'DEB control archive' -Command { & $gnuTar --force-local --format=gnu --owner=0 --group=0 --mode=0644 -cf $controlTar control }
|
|
Invoke-Checked -Description 'DEB maintainer scripts' -Command { & $gnuTar --force-local --format=gnu --owner=0 --group=0 --mode=0755 -rf $controlTar postinst prerm postrm }
|
|
} finally { Pop-Location }
|
|
Invoke-Checked -Description 'DEB control compression' -Command { & $gzip -n -f $controlTar }
|
|
$dataTar = Join-Path $debParts 'data.tar'
|
|
$execFiles = @('./usr/bin/remotedesk-agentd', './usr/bin/remotedesk-agent-session', './usr/libexec/remotedesk-shell-session', './usr/libexec/remotedesk-file-session')
|
|
$dataFiles = @('./usr/lib/systemd/system/remotedesk-agentd.service', './usr/lib/systemd/user/remotedesk-agent-session.service', './etc/remotedesk/agent.env', './usr/share/doc/remotedesk-agent/README.md')
|
|
Push-Location $debianRoot
|
|
try {
|
|
Invoke-Checked -Description 'DEB executable payload' -Command { & $gnuTar --force-local --format=gnu --owner=0 --group=0 --mode=0755 -cf $dataTar @execFiles }
|
|
Invoke-Checked -Description 'DEB data payload' -Command { & $gnuTar --force-local --format=gnu --owner=0 --group=0 --mode=0644 -rf $dataTar @dataFiles }
|
|
} finally { Pop-Location }
|
|
Invoke-Checked -Description 'DEB data compression' -Command { & $gzip -n -f $dataTar }
|
|
$debOutput = Join-Path $artifactsRoot "remotedesk-agent_${version}_amd64-musl.deb"
|
|
Push-Location $debParts
|
|
try {
|
|
Invoke-Checked -Description 'DEB ar archive' -Command { & $llvmAr rc $debOutput debian-binary control.tar.gz data.tar.gz }
|
|
} finally { Pop-Location }
|
|
|
|
foreach ($output in @($portableOutput, $debOutput)) {
|
|
$hash = (Get-FileHash -LiteralPath $output -Algorithm SHA256).Hash.ToLowerInvariant()
|
|
"$hash $([IO.Path]::GetFileName($output))" | Set-Content -LiteralPath "$output.sha256" -Encoding ascii
|
|
Write-Output "Package: $output"
|
|
Write-Output "SHA256: $hash"
|
|
}
|
|
} finally {
|
|
Remove-Item Env:CC_x86_64_unknown_linux_musl -ErrorAction SilentlyContinue
|
|
Remove-Item Env:AR_x86_64_unknown_linux_musl -ErrorAction SilentlyContinue
|
|
Remove-Item Env:CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER -ErrorAction SilentlyContinue
|
|
Pop-Location
|
|
}
|