Runner assignment
Install each machine once. From a repository's Actions tab, enable This repository or All repositories.
Build, install, update, and deploy products on your own assigned runner machines.
Before creating or changing this deployment, read https://filedistro.net/actions.md and use only the FileDistro Actions features documented there. Put install/update logic in an idempotent repository script and keep the workflow small.
scripts/deploy-product.ps1..filedistro/workflows or .github/workflows.self-hosted, windows, and x64.name: Deploy product
on:
push:
branches: [main]
workflow_dispatch:
concurrency:
group: product-production
cancel-in-progress: true
jobs:
deploy:
runs-on: [self-hosted, windows, x64]
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- name: Install or update product
shell: pwsh
run: ./scripts/deploy-product.ps1
This runs directly on the Windows machine because the job has no container: field.
Installing Docker on the runner does not change that.
main or a manual run on main builds that selected revision; deployment scripts should not perform a separate git pull.The native Windows runner can publish to a staging directory, stop the product service, replace its files, configure the executable, restart it, and perform a health check.
$ErrorActionPreference = 'Stop'
$serviceName = 'MyProduct'
$stage = 'C:\deploy\MyProduct\stage'
$live = 'C:\deploy\MyProduct\app'
dotnet publish .\src\MyProduct\MyProduct.csproj -c Release -o $stage
if ($LASTEXITCODE -ne 0) { throw 'Publish failed.' }
$service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
if ($service -and $service.Status -ne 'Stopped') {
Stop-Service -Name $serviceName -Force
}
New-Item -ItemType Directory -Force -Path $live | Out-Null
robocopy $stage $live /MIR /NFL /NDL /NJH /NJS /NP
if ($LASTEXITCODE -gt 7) { throw "Copy failed: $LASTEXITCODE" }
$binaryPath = '"C:\deploy\MyProduct\app\MyProduct.exe"'
if (-not $service) {
New-Service -Name $serviceName -BinaryPathName $binaryPath -StartupType Automatic
} else {
sc.exe config $serviceName binPath= $binaryPath start= auto | Out-Null
if ($LASTEXITCODE -ne 0) { throw 'Service configuration failed.' }
}
Start-Service -Name $serviceName
Invoke-WebRequest -UseBasicParsing http://127.0.0.1:8080/health
New-Service. Add Windows service lifetime support to the product, or use a deliberate service wrapper.A console host may run in the foreground for a test or one-off task. The Actions step waits until it exits, and cancellation or timeout kills the process tree. Do not use a detached console process as an unmanaged production deployment; use a Windows service or another machine supervisor for automatic startup, restart, logs, and controlled updates.
Install each machine once. From a repository's Actions tab, enable This repository or All repositories.
Add container: image-name only when every step should run in Docker. Container jobs require a Docker-ready runner.
Encrypted repository secrets are not implemented. Do not commit credentials or print them in logs; provision them securely on the host.
actions/checkout is built in. Remote marketplace actions, matrices, services, dependencies, and conditions are not supported.
push and workflow_dispatchname, runs-on, container, timeout-minutes, env, and stepsname, run, uses, shell, working-directory, and envbash, sh, pwsh, powershell, and cmd when installedRead the complete Markdown reference for branch filters, concurrency, recovery, logging, and runner installation.