Skip to content

Run server on Windows #9

Run server on Windows

Run server on Windows #9

Workflow file for this run

name: Run server on Windows
on:
workflow_dispatch:
jobs:
WindowsServer-x86:
runs-on: windows-latest
timeout-minutes: 60
env:
# Wolfram
WOLFRAM_SYSTEM_ID: Windows-x86-64-v7
WOLFRAMENGINE_INSTALL_MSI_DOWNLOAD_URL: https://files.wolframcdn.com/packages/winget/14.0.0.0/WolframEngine_14.0.0_WIN.msi
WOLFRAMENGINE_CACHE_KEY: WolframEngine-U
WOLFRAMENGINE_INSTALLATION_SUBDIRECTORY: WolframEngine
steps:
- name: Check out repository
uses: actions/checkout@v4
with:
token: ${{ secrets.GH_TOKEN }}
- name: Cache/restore Wolfram Engine install
id: cache-restore
uses: actions/cache@v4
env:
WOLFRAMENGINE_INSTALLATION_DIRECTORY: '${{ runner.temp }}\${{ env.WOLFRAMENGINE_INSTALLATION_SUBDIRECTORY }}'
with:
path: ${{ env.WOLFRAMENGINE_INSTALLATION_DIRECTORY }}
key: wolframengine-${{ env.WOLFRAM_SYSTEM_ID }}-${{ env.WOLFRAMENGINE_CACHE_KEY }}
- name: Download and install Wolfram Engine
if: steps.cache-restore.outputs.cache-hit != 'true'
env:
WOLFRAMENGINE_INSTALLATION_DIRECTORY: '${{ runner.temp }}\${{ env.WOLFRAMENGINE_INSTALLATION_SUBDIRECTORY }}'
WOLFRAMENGINE_INSTALL_MSI_PATH: '${{ runner.temp }}\WolframEngine-Install.msi'
WOLFRAMENGINE_INSTALL_LOG_PATH: '${{ runner.temp }}\WolframEngine-Install.log'
shell: pwsh
run: |
echo 'Downloading Wolfram Engine installer...'
$msiFile = '${{ env.WOLFRAMENGINE_INSTALL_MSI_PATH }}'
$logFile = '${{ env.WOLFRAMENGINE_INSTALL_LOG_PATH }}'
Import-Module BitsTransfer
Start-BitsTransfer '${{ env.WOLFRAMENGINE_INSTALL_MSI_DOWNLOAD_URL }}' $msiFile
echo 'Installing Wolfram Engine...'
$MSIArguments = @(
"/i", ('"{0}"' -f $msiFile),
'INSTALLLOCATION="${{ env.WOLFRAMENGINE_INSTALLATION_DIRECTORY }}"',
"/qn", "/norestart", "/L*v", $logFile
)
Start-Process "msiexec.exe" -ArgumentList $MSIArguments -Wait -NoNewWindow
echo 'Installed Wolfram Engine.'
- name: Install Caddy (Chocolatey) and export path
shell: pwsh
run: |
choco install caddy -y --no-progress
$real = Join-Path $env:ProgramData "chocolatey\lib\caddy\tools\caddy.exe"
if (-not (Test-Path $real)) {
$real = Get-ChildItem -Path (Join-Path $env:ProgramData "chocolatey\lib\caddy\tools") -Recurse -Filter "caddy*.exe" |
Select-Object -ExpandProperty FullName -First 1
}
if (-not $real) { throw "Could not locate real caddy.exe under Chocolatey lib." }
# Make it available to later steps
"CADDY_EXE=$real" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
Write-Host "Using Caddy at $real"
- name: Start local proxy (Caddy) on :3000
shell: pwsh
run: |
$caddy = $env:CADDY_EXE
$caddyfile = Join-Path $env:RUNNER_TEMP "Caddyfile"
$lines = @(
':3000',
'',
'# WebSocket service 1',
'route /ws* {',
' reverse_proxy 127.0.0.1:4001',
'}',
'',
'# WebSocket service 2',
'route /ws2* {',
' reverse_proxy 127.0.0.1:4002',
'}',
'',
'# Everything else to the HTTP app',
'route /* {',
' reverse_proxy 127.0.0.1:4000',
'}'
)
$cfg = $lines -join "`r`n"
Set-Content -Path $caddyfile -Value $cfg -Encoding utf8
$caddyOut = Join-Path $env:RUNNER_TEMP "caddy.out.log"
$caddyErr = Join-Path $env:RUNNER_TEMP "caddy.err.log"
$proc = Start-Process -FilePath $caddy -ArgumentList @("run","--config",$caddyfile) `
-RedirectStandardOutput $caddyOut -RedirectStandardError $caddyErr -PassThru -WindowStyle Hidden
Set-Content -Path (Join-Path $env:RUNNER_TEMP "caddy.pid") -Value $proc.Id
Start-Sleep -Seconds 1
Write-Host "=== Caddy STDOUT (tail) ==="
Get-Content $caddyOut -Tail 50
Write-Host "=== Caddy STDERR (tail) ==="
Get-Content $caddyErr -Tail 50
- name: Download cloudflared (Quick Tunnel)
shell: pwsh
run: |
$cf = Join-Path $env:RUNNER_TEMP "cloudflared.exe"
Invoke-WebRequest -Uri "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-windows-amd64.exe" -OutFile $cf
Write-Host "cloudflared at $cf"
- name: Start Quick Tunnel (→ http://127.0.0.1:3000)
shell: pwsh
run: |
$cf = Join-Path $env:RUNNER_TEMP "cloudflared.exe"
$out = Join-Path $env:RUNNER_TEMP "cloudflared.out.log"
$err = Join-Path $env:RUNNER_TEMP "cloudflared.err.log"
$proc = Start-Process -FilePath $cf -ArgumentList @("tunnel","--url","http://127.0.0.1:3000") `
-RedirectStandardOutput $out -RedirectStandardError $err -PassThru -WindowStyle Hidden
Set-Content -Path (Join-Path $env:RUNNER_TEMP "cloudflared.pid") -Value $proc.Id
# Live tail so the trycloudflare URL appears once cloudflared emits it
Start-Job -Name "tail-cloudflared-out" -ScriptBlock { param($p) Get-Content -Path $p -Wait } -ArgumentList $out | Out-Null
Start-Job -Name "tail-cloudflared-err" -ScriptBlock { param($p) Get-Content -Path $p -Wait } -ArgumentList $err | Out-Null
Start-Sleep -Seconds 3
Write-Host "==== cloudflared (initial tails) ===="
Get-Content $out -Tail 80
Get-Content $err -Tail 40
- name: Start Wolfram server (your app)
env:
WOLFRAMENGINE_INSTALLATION_DIRECTORY: '${{ runner.temp }}\${{ env.WOLFRAMENGINE_INSTALLATION_SUBDIRECTORY }}'
# If you use the entitlement secret, keep this line; otherwise remove it:
WOLFRAMINIT: "-pwfile !cloudlm.wolfram.com -entitlement ${{ secrets.WOLFRAM_LICENSE_ENTITLEMENT_ID }}"
shell: pwsh
run: |
# Put Wolfram on PATH
$env:Path += ';' + (Join-Path $env:WOLFRAMENGINE_INSTALLATION_DIRECTORY '')
Write-Host "==== Starting Wolfram server (console output below) ===="
# Your script should start services on 4000/4001/4002 as needed.
& wolfram -script ./Scripts/start.wls http 4000 ws 4001 ws2 4002 wsprefix ws ws2prefix ws2
$exitCode = $LASTEXITCODE
Write-Host "==== Wolfram server exited with code $exitCode ===="
if ($exitCode -ne 0) {
throw "Wolfram server process exited with non-zero code: $exitCode"
}
- name: Cleanup (stop tunnel & proxy)
if: always()
shell: pwsh
run: |
# Stop cloudflared
$cfPidFile = Join-Path $env:RUNNER_TEMP "cloudflared.pid"
if (Test-Path $cfPidFile) {
$pid = Get-Content $cfPidFile
try { Stop-Process -Id $pid -Force -ErrorAction Stop } catch {}
Remove-Item $cfPidFile -Force
}
# Stop Caddy
$caddyPidFile = Join-Path $env:RUNNER_TEMP "caddy.pid"
if (Test-Path $caddyPidFile) {
$pid = Get-Content $caddyPidFile
try { Stop-Process -Id $pid -Force -ErrorAction Stop } catch {}
Remove-Item $caddyPidFile -Force
}
# Stop tail job
$job = Get-Job -Name "tail-cloudflared" -ErrorAction SilentlyContinue
if ($job -and $job.State -eq 'Running') { Stop-Job $job -Force }
if ($job) { Receive-Job $job -Keep | Out-Null; Remove-Job $job -Force }