f373c0c24b
P0 bugs: - Invoke-CIJob.ps1: skip --depth 1 when $Commit specified (shallow clone + checkout specific commit was silently failing) - Get-BuildArtifacts.ps1: check .Length -eq 0 not rounded sizeKB (false fail on artifacts smaller than 50 bytes) - build-nsis.yml: upgrade upload-artifact v3 -> v4 (v3 deprecated) P0 security: - Remove hardcoded default password CIBuild!ChangeMe2026 from all scripts, README, TODO; prompt Read-Host -AsSecureString at runtime instead - Setup-TemplateVM.ps1: replace `net user $u $p /add` (password in argv / audit log 4688) with New-LocalUser + local ConvertTo-SecureString - Prepare-TemplateSetup.ps1: save and restore WSMan AllowUnencrypted + TrustedHosts in finally block (was permanently mutating host WinRM config) - Setup-TemplateVM.ps1: remove duplicate MaxMemoryPerShellMB (winrm set + Set-Item both setting same value) P1 doc (stale Host-Only / VMnet11 era): - Setup-TemplateVM.ps1: rewrite NETWORK REQUIREMENT block + final steps (system uses VMnet8 NAT permanently, not VMnet11 Host-Only) - Invoke-CIJob.ps1 Phase 1 comment: correct network model - ARCHITECTURE.md: remove Git from toolchain list (not installed); clarify zip-transfer rationale (no PAT in VM, not network isolation) - BEST-PRACTICES.md: rewrite Step 8 as NAT topology verification P1 minor: - Invoke-RemoteBuild.ps1: remove wasted first New-Item (created then immediately removed and recreated) - Wait-VMReady.ps1: remove unused $elapsed; simplify try/catch around native command (exit codes don't throw) - Install-Runner.ps1: add deprecation notice pointing to Setup-Host.ps1 P2 operational: - Add scripts/Cleanup-OrphanedBuildVMs.ps1 with -WhatIf support - Get-BuildArtifacts.ps1 -IncludeLogs: add -Recurse (msbuild logs in subdir) - Add gitea/workflows/lint.yml (PSScriptAnalyzer on .ps1 push/PR) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
208 lines
8.2 KiB
PowerShell
208 lines
8.2 KiB
PowerShell
#Requires -RunAsAdministrator
|
|
#Requires -Version 5.1
|
|
<#
|
|
.SYNOPSIS
|
|
Downloads, registers, and installs act_runner as a Windows service.
|
|
|
|
.NOTES
|
|
DEPRECATED — use Setup-Host.ps1 instead.
|
|
Setup-Host.ps1 handles the full host bootstrap including act_runner service
|
|
installation in a single idempotent script. Install-Runner.ps1 is kept for
|
|
reference but may drift from Setup-Host.ps1 over time.
|
|
|
|
.DESCRIPTION
|
|
1. Downloads the act_runner binary from the specified URL (or Gitea releases).
|
|
2. Registers the runner with the Gitea instance using a registration token.
|
|
3. Installs it as a Windows service that auto-starts with the system.
|
|
|
|
Prerequisites:
|
|
- Run as Administrator
|
|
- NSSM (Non-Sucking Service Manager) must be installed and in PATH,
|
|
OR use the built-in sc.exe method (creates a wrapper via PowerShell).
|
|
- The Gitea instance must be reachable from this host.
|
|
|
|
.PARAMETER GiteaURL
|
|
Base URL of your Gitea instance. Example: http://192.168.1.50:3000
|
|
|
|
.PARAMETER RegistrationToken
|
|
Runner registration token from Gitea:
|
|
Admin Panel → Settings → Actions → Runners → "Create Runner Token"
|
|
|
|
.PARAMETER InstallDir
|
|
Directory where act_runner will be installed.
|
|
Default: F:\CI\act_runner
|
|
|
|
.PARAMETER RunnerName
|
|
Display name for this runner in the Gitea UI.
|
|
Default: local-windows-runner
|
|
|
|
.PARAMETER ActRunnerVersion
|
|
Version tag to download. Default: latest (resolves via GitHub API).
|
|
Example: v0.2.11
|
|
|
|
.PARAMETER ServiceName
|
|
Windows service name. Default: act_runner
|
|
|
|
.EXAMPLE
|
|
.\Install-Runner.ps1 `
|
|
-GiteaURL "http://192.168.1.50:3000" `
|
|
-RegistrationToken "abc123xyz"
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Mandatory)]
|
|
[string] $GiteaURL,
|
|
|
|
[Parameter(Mandatory)]
|
|
[string] $RegistrationToken,
|
|
|
|
[string] $InstallDir = 'F:\CI\act_runner',
|
|
|
|
[string] $RunnerName = 'local-windows-runner',
|
|
|
|
[string] $ActRunnerVersion = 'latest',
|
|
|
|
[string] $ServiceName = 'act_runner'
|
|
)
|
|
|
|
Set-StrictMode -Version Latest
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
# ── Resolve download URL ──────────────────────────────────────────────────────
|
|
if ($ActRunnerVersion -eq 'latest') {
|
|
Write-Host "[Install-Runner] Resolving latest act_runner version from Gitea releases..."
|
|
try {
|
|
$releaseInfo = Invoke-RestMethod -Uri 'https://dl.gitea.com/act_runner/version.json' -UseBasicParsing
|
|
$ActRunnerVersion = $releaseInfo.latest
|
|
}
|
|
catch {
|
|
Write-Warning "Could not resolve latest version automatically. Set -ActRunnerVersion explicitly."
|
|
Write-Warning "Find releases at: https://gitea.com/gitea/act_runner/releases"
|
|
throw
|
|
}
|
|
}
|
|
|
|
$downloadUrl = "https://dl.gitea.com/act_runner/${ActRunnerVersion}/act_runner-${ActRunnerVersion}-windows-amd64.exe"
|
|
$binaryPath = Join-Path $InstallDir 'act_runner.exe'
|
|
$configPath = Join-Path $InstallDir 'config.yaml'
|
|
|
|
Write-Host "[Install-Runner] Version : $ActRunnerVersion"
|
|
Write-Host "[Install-Runner] Install dir: $InstallDir"
|
|
Write-Host "[Install-Runner] Service : $ServiceName"
|
|
|
|
# ── Create install directory ──────────────────────────────────────────────────
|
|
if (-not (Test-Path $InstallDir)) {
|
|
New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
|
|
Write-Host "[Install-Runner] Created directory: $InstallDir"
|
|
}
|
|
|
|
# ── Download act_runner binary ────────────────────────────────────────────────
|
|
if (Test-Path $binaryPath) {
|
|
Write-Host "[Install-Runner] act_runner.exe already exists — skipping download."
|
|
Write-Host " Delete $binaryPath to force re-download."
|
|
}
|
|
else {
|
|
Write-Host "[Install-Runner] Downloading from: $downloadUrl"
|
|
Invoke-WebRequest -Uri $downloadUrl -OutFile $binaryPath -UseBasicParsing
|
|
Write-Host "[Install-Runner] Downloaded: $binaryPath"
|
|
}
|
|
|
|
# ── Copy config.yaml if not already present ───────────────────────────────────
|
|
$repoConfigPath = Join-Path $PSScriptRoot 'config.yaml'
|
|
if (-not (Test-Path $configPath)) {
|
|
if (Test-Path $repoConfigPath) {
|
|
Copy-Item $repoConfigPath $configPath
|
|
Write-Host "[Install-Runner] Copied config.yaml from repo to $configPath"
|
|
Write-Host " Review and update paths in $configPath before proceeding."
|
|
}
|
|
else {
|
|
Write-Warning "[Install-Runner] config.yaml not found at $repoConfigPath"
|
|
Write-Warning " Generating default config and registering without custom config."
|
|
# Generate default config
|
|
Push-Location $InstallDir
|
|
& $binaryPath generate-config | Out-File $configPath -Encoding UTF8
|
|
Pop-Location
|
|
}
|
|
}
|
|
else {
|
|
Write-Host "[Install-Runner] Using existing config.yaml: $configPath"
|
|
}
|
|
|
|
# ── Register runner with Gitea ────────────────────────────────────────────────
|
|
$stateFile = Join-Path $InstallDir '.runner'
|
|
if (Test-Path $stateFile) {
|
|
Write-Host "[Install-Runner] Runner already registered (.runner state file exists)."
|
|
Write-Host " Delete $stateFile to re-register."
|
|
}
|
|
else {
|
|
Write-Host "[Install-Runner] Registering runner with Gitea at $GiteaURL..."
|
|
Push-Location $InstallDir
|
|
try {
|
|
& $binaryPath register `
|
|
--no-interactive `
|
|
--instance $GiteaURL `
|
|
--token $RegistrationToken `
|
|
--name $RunnerName `
|
|
--labels 'windows-build:host,dotnet:host,msbuild:host' `
|
|
--config $configPath
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "act_runner register exited with code $LASTEXITCODE"
|
|
}
|
|
}
|
|
finally {
|
|
Pop-Location
|
|
}
|
|
Write-Host "[Install-Runner] Runner registered successfully."
|
|
}
|
|
|
|
# ── Install as Windows service ────────────────────────────────────────────────
|
|
$existingService = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
|
|
|
|
if ($existingService) {
|
|
Write-Host "[Install-Runner] Service '$ServiceName' already exists."
|
|
Write-Host " Stopping and updating..."
|
|
Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue
|
|
}
|
|
|
|
# Build service command (act_runner daemon with explicit config)
|
|
$serviceCmd = "`"$binaryPath`" daemon --config `"$configPath`""
|
|
|
|
if ($existingService) {
|
|
# Update existing service binary path
|
|
sc.exe config $ServiceName binpath= $serviceCmd | Out-Null
|
|
}
|
|
else {
|
|
# Create new service
|
|
New-Service `
|
|
-Name $ServiceName `
|
|
-BinaryPathName $serviceCmd `
|
|
-DisplayName 'Gitea act_runner (CI/CD)' `
|
|
-Description 'Gitea Actions runner for ephemeral VMware build VMs' `
|
|
-StartupType Automatic | Out-Null
|
|
Write-Host "[Install-Runner] Service created: $ServiceName"
|
|
}
|
|
|
|
# Configure service recovery: restart on failure
|
|
sc.exe failure $ServiceName reset= 86400 actions= restart/5000/restart/10000/restart/30000 | Out-Null
|
|
|
|
# Start the service
|
|
Start-Service -Name $ServiceName
|
|
Write-Host "[Install-Runner] Service '$ServiceName' started."
|
|
|
|
# ── Verify ────────────────────────────────────────────────────────────────────
|
|
Start-Sleep -Seconds 3
|
|
$svc = Get-Service -Name $ServiceName
|
|
if ($svc.Status -eq 'Running') {
|
|
Write-Host "[Install-Runner] act_runner is running as a Windows service."
|
|
Write-Host "[Install-Runner] Check Gitea Admin → Settings → Actions → Runners to confirm it appears Online."
|
|
}
|
|
else {
|
|
Write-Warning "[Install-Runner] Service status: $($svc.Status). Check Windows Event Log for errors."
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host "Installation complete."
|
|
Write-Host " Binary : $binaryPath"
|
|
Write-Host " Config : $configPath"
|
|
Write-Host " Service : $ServiceName (startup: Automatic)"
|