2026-06-16 18:53:25 +01:00
param (
[ string ] $SshTarget = " yggdrasil " ,
[ string ] $RepoRoot = " E:\Projects\repixelizer " ,
[ string ] $CultLibRoot = " E:\Projects\CultLib " ,
[ string ] $AppUser = " repixelizer " ,
[ string ] $RemoteAppHome = " /srv/repixelizer " ,
[ string ] $RemoteTarballName = " repixelizer-source.tar " ,
[ string ] $RemoteCultLibTarballName = " repixelizer-cultlib.tar " ,
[ string ] $DeployScript = " E:\Projects\gamecult-ops\scripts\deploy-repixelizer-gui.sh " ,
2026-06-16 23:44:37 +01:00
[ string ] $CheckScript = " E:\Projects\gamecult-ops\scripts\check-repixelizer-gui.sh " ,
[ string ] $UpstreamRemote = " origin " ,
[ string ] $UpstreamBranch = " main " ,
[ string ] $CultLibUpstreamRemote = " origin " ,
[ string ] $CultLibUpstreamBranch = " main "
2026-06-16 18:53:25 +01:00
)
$ErrorActionPreference = " Stop "
2026-07-04 22:38:43 +01:00
if ( $env:IDUNN_ACTUATOR -ne " 1 " -or $env:IDUNN_COMMAND_AUTHORITY -ne " idunn-daemon " ) {
2026-06-17 00:16:07 +01:00
throw " This deployment script is an Idunn actuator. Agents must configure Idunn release targets and let Idunn run deployment; do not invoke deploy scripts manually. "
}
2026-06-16 18:53:25 +01:00
foreach ( $path in @ ( $RepoRoot , $CultLibRoot , $DeployScript , $CheckScript ) ) {
if ( -not ( Test-Path -LiteralPath $path ) ) {
throw " Required path not found: $path "
}
}
2026-06-16 23:44:37 +01:00
$sourceRef = " $UpstreamRemote / $UpstreamBranch "
$cultLibSourceRef = " $CultLibUpstreamRemote / $CultLibUpstreamBranch "
git -C $RepoRoot fetch - -prune $UpstreamRemote $UpstreamBranch
if ( $LASTEXITCODE -ne 0 ) { throw " git fetch failed for $RepoRoot $sourceRef " }
git -C $CultLibRoot fetch - -prune $CultLibUpstreamRemote $CultLibUpstreamBranch
if ( $LASTEXITCODE -ne 0 ) { throw " git fetch failed for $CultLibRoot $cultLibSourceRef " }
$repixelizerCommit = ( git -C $RepoRoot rev-parse $sourceRef ) . Trim ( )
2026-06-16 18:53:25 +01:00
if ( [ string ] :: IsNullOrWhiteSpace ( $repixelizerCommit ) ) {
throw " Could not determine Repixelizer git revision. "
}
2026-06-16 23:44:37 +01:00
$cultLibCommit = ( git -C $CultLibRoot rev-parse $cultLibSourceRef ) . Trim ( )
2026-06-16 18:53:25 +01:00
if ( [ string ] :: IsNullOrWhiteSpace ( $cultLibCommit ) ) {
throw " Could not determine CultLib git revision. "
}
$scratch = Join-Path " E:\Projects\Odin\scratch\idunn-deploy " " yggdrasil-repixelizer "
$sourceTarPath = Join-Path $scratch $RemoteTarballName
$cultLibTarPath = Join-Path $scratch $RemoteCultLibTarballName
$manifestPath = Join-Path $scratch " deployment-manifest.txt "
New-Item -ItemType Directory -Force -Path $scratch | Out-Null
2026-06-16 23:44:37 +01:00
git -C $RepoRoot archive - -format = tar - -output = $sourceTarPath $sourceRef
2026-06-16 18:53:25 +01:00
if ( $LASTEXITCODE -ne 0 ) {
2026-06-16 23:44:37 +01:00
throw " git archive failed for $RepoRoot $sourceRef "
2026-06-16 18:53:25 +01:00
}
if ( Test-Path -LiteralPath $cultLibTarPath ) {
Remove-Item -LiteralPath $cultLibTarPath -Force
}
2026-06-16 23:44:37 +01:00
git -C $CultLibRoot archive - -format = tar - -output = $cultLibTarPath $cultLibSourceRef packages / cultcache-py
2026-06-16 18:53:25 +01:00
if ( $LASTEXITCODE -ne 0 ) {
2026-06-16 23:44:37 +01:00
throw " CultLib tar build failed for $CultLibRoot $cultLibSourceRef "
2026-06-16 18:53:25 +01:00
}
$sourceHash = ( Get-FileHash $sourceTarPath -Algorithm SHA256 ) . Hash . ToLowerInvariant ( )
$cultLibHash = ( Get-FileHash $cultLibTarPath -Algorithm SHA256 ) . Hash . ToLowerInvariant ( )
$deployedAt = [ DateTimeOffset ] :: UtcNow . ToString ( " O " )
@ (
" schema=gamecult.idunn.deployment_manifest.v1 "
" appId=yggdrasil-repixelizer "
" repoRoot= $RepoRoot "
2026-06-16 23:44:37 +01:00
" upstreamRemote= $UpstreamRemote "
" upstreamBranch= $UpstreamBranch "
" sourceRef= $sourceRef "
2026-06-16 18:53:25 +01:00
" gitCommit= $repixelizerCommit "
" artifact= $RemoteTarballName "
" sha256= $sourceHash "
" cultLibRepoRoot= $CultLibRoot "
2026-06-16 23:44:37 +01:00
" cultLibUpstreamRemote= $CultLibUpstreamRemote "
" cultLibUpstreamBranch= $CultLibUpstreamBranch "
" cultLibSourceRef= $cultLibSourceRef "
2026-06-16 18:53:25 +01:00
" cultLibGitCommit= $cultLibCommit "
" cultLibArtifact= $RemoteCultLibTarballName "
" cultLibSha256= $cultLibHash "
" deployedAtUtc= $deployedAt "
) | Set-Content -Encoding ASCII -LiteralPath $manifestPath
$remoteDeploy = " /home/gamecultadmin/ $( [ IO.Path ] :: GetFileName ( $DeployScript ) ) "
$remoteCheck = " /home/gamecultadmin/ $( [ IO.Path ] :: GetFileName ( $CheckScript ) ) "
$remoteSourceTarball = " /home/gamecultadmin/ $RemoteTarballName "
$remoteCultLibTarball = " /home/gamecultadmin/ $RemoteCultLibTarballName "
$remoteManifest = " /home/gamecultadmin/yggdrasil-repixelizer-deployment-manifest.txt "
$remoteRunner = " /home/gamecultadmin/run-yggdrasil-repixelizer-deploy.sh "
$targetSourceTarball = " $RemoteAppHome / $RemoteTarballName "
$targetCultLibTarball = " $RemoteAppHome / $RemoteCultLibTarballName "
$targetManifest = " $RemoteAppHome /deployment-manifest.txt "
$sftpBatchPath = Join-Path $scratch " yggdrasil-repixelizer-upload.sftp "
$runnerPath = Join-Path $scratch " run-yggdrasil-repixelizer-deploy.sh "
$runnerScript = @"
#!/usr/bin/env bash
set -euo pipefail
sudo -n install -d -o '$AppUser' -g '$AppUser' '$RemoteAppHome'
sudo -n install -o '$AppUser' -g '$AppUser' -m 600 '$remoteSourceTarball' '$targetSourceTarball'
sudo -n install -o '$AppUser' -g '$AppUser' -m 600 '$remoteCultLibTarball' '$targetCultLibTarball'
sudo -n install -m 644 '$remoteManifest' '$targetManifest'
chmod + x '$remoteDeploy' '$remoteCheck'
2026-07-04 22:38:43 +01:00
sudo -n env GAMECULT_IDUNN_REMOTE_ACTUATOR = 1 IDUNN_COMMAND_AUTHORITY = idunn-daemon bash '$remoteDeploy'
2026-06-16 18:53:25 +01:00
check_ok = 0
for i in `$ ( seq 1 30 ) ; do
if sudo -n bash '$remoteCheck' ; then
check_ok = 1
break
fi
sleep 2
done
if [ " `$ check_ok " -ne 1 ] ; then
sudo -n bash '$remoteCheck'
exit 1
fi
" @.Replace( " ` r ` n " , " ` n " )
[ System.IO.File ] :: WriteAllText ( $runnerPath , $runnerScript , [ System.Text.Encoding ] :: ASCII )
@ (
" put "" $sourceTarPath "" "" $remoteSourceTarball "" "
" put "" $cultLibTarPath "" "" $remoteCultLibTarball "" "
" put "" $DeployScript "" "" $remoteDeploy "" "
" put "" $CheckScript "" "" $remoteCheck "" "
" put "" $manifestPath "" "" $remoteManifest "" "
" put "" $runnerPath "" "" $remoteRunner "" "
) | Set-Content -Encoding ASCII -LiteralPath $sftpBatchPath
try {
& sftp . exe -b $sftpBatchPath $SshTarget
if ( $LASTEXITCODE -ne 0 ) {
throw " sftp upload failed for yggdrasil-repixelizer "
}
& ssh . exe -o BatchMode = yes -o ConnectTimeout = 10 $SshTarget " chmod +x ' $remoteRunner ' && bash ' $remoteRunner ' "
$remoteExit = $LASTEXITCODE
& ssh . exe -o BatchMode = yes -o ConnectTimeout = 10 $SshTarget " rm -f ' $remoteRunner ' "
if ( $remoteExit -ne 0 ) {
throw " remote deploy/check failed for yggdrasil-repixelizer "
}
}
finally {
Remove-Item -LiteralPath $runnerPath -Force -ErrorAction SilentlyContinue
Remove-Item -LiteralPath $sftpBatchPath -Force -ErrorAction SilentlyContinue
}
Write-Host " yggdrasil-repixelizer deployed with CultLib snapshot. "
Write-Host " repixelizerCommit= $repixelizerCommit "
Write-Host " cultLibCommit= $cultLibCommit "
Write-Host " artifactSha256= $sourceHash "
Write-Host " cultLibSha256= $cultLibHash "