Skip to content

docs: connect project metadata to public website #2013

docs: connect project metadata to public website

docs: connect project metadata to public website #2013

name: Windows baseline
on:
pull_request:
branches: [main]
push:
branches: [main]
# Nightly full storage suite (PR/push keep curated OS-sensitive gates only).
schedule:
- cron: '17 6 * * *'
workflow_dispatch:
inputs:
full_storage:
description: 'Run full packages/storage suite on Windows (slow, evidence lane)'
type: boolean
default: false
concurrency:
group: windows-baseline-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
permissions:
contents: read
jobs:
changes:
runs-on: ubuntu-latest
outputs:
windows: ${{ steps.plan.outputs.windows }}
windows_runtime: ${{ steps.plan.outputs.windows_runtime }}
windows_storage: ${{ steps.plan.outputs.windows_storage }}
# Full suite is never selected by path plan — only schedule / dispatch.
windows_storage_full: ${{ steps.full.outputs.windows_storage_full }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- id: plan
name: Select affected Windows surfaces
env:
BASE_SHA: ${{ github.event_name == 'push' && github.event.before || github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event_name == 'push' && github.sha || github.event.pull_request.head.sha }}
run: |
# schedule / manual dispatch have no meaningful PR base; use full
# surface selection so the job still runs install+smoke+gates.
if [[ "${{ github.event_name }}" == "schedule" || "${{ github.event_name }}" == "workflow_dispatch" ]]; then
node scripts/ci-test-plan.mjs --full >> "$GITHUB_OUTPUT"
elif [[ "$BASE_SHA" =~ ^0+$ ]] || ! git cat-file -e "${BASE_SHA}^{commit}"; then
node scripts/ci-test-plan.mjs --full >> "$GITHUB_OUTPUT"
else
node scripts/ci-test-plan.mjs --base "$BASE_SHA" --head "$HEAD_SHA" >> "$GITHUB_OUTPUT"
fi
- id: full
name: Decide full storage suite
run: |
if [[ "${{ github.event_name }}" == "schedule" ]]; then
echo "windows_storage_full=true" >> "$GITHUB_OUTPUT"
elif [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ inputs.full_storage }}" == "true" ]]; then
echo "windows_storage_full=true" >> "$GITHUB_OUTPUT"
else
echo "windows_storage_full=false" >> "$GITHUB_OUTPUT"
fi
windows_baseline:
needs: changes
if: needs.changes.outputs.windows == 'true'
name: windows_baseline (non-blocking)
runs-on: windows-latest
timeout-minutes: 45
continue-on-error: true
env:
WINDOWS_BASELINE_LOG_DIR: artifacts/windows-baseline
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: '24'
cache: npm
- name: Create log directory
shell: pwsh
run: New-Item -ItemType Directory -Force $env:WINDOWS_BASELINE_LOG_DIR | Out-Null
- name: Capture process baseline
shell: pwsh
run: |
$processes = @(
Get-CimInstance Win32_Process |
Where-Object { $_.Name -in @('node.exe', 'electron.exe') } |
ForEach-Object {
[pscustomobject]@{
ProcessId = $_.ProcessId
ParentProcessId = $_.ParentProcessId
Name = $_.Name
CreationDate = $_.CreationDate.ToUniversalTime().ToString('o')
CommandLine = $_.CommandLine
}
}
)
[pscustomobject]@{
CapturedAtUtc = [DateTime]::UtcNow.ToString('o')
Processes = $processes
} | ConvertTo-Json -Depth 4 |
Set-Content "$env:WINDOWS_BASELINE_LOG_DIR/process-baseline.json"
- id: install
name: Install dependencies
continue-on-error: true
shell: pwsh
run: |
npm.cmd ci *> "$env:WINDOWS_BASELINE_LOG_DIR/install.log"
$exitCode = $LASTEXITCODE
Get-Content "$env:WINDOWS_BASELINE_LOG_DIR/install.log"
exit $exitCode
- id: build
name: Build test artifacts
if: always() && steps.install.outcome == 'success'
continue-on-error: true
shell: pwsh
run: |
npm.cmd run build:test *> "$env:WINDOWS_BASELINE_LOG_DIR/build.log"
$exitCode = $LASTEXITCODE
Get-Content "$env:WINDOWS_BASELINE_LOG_DIR/build.log"
exit $exitCode
- id: inventory
name: Check Windows skip inventory
if: always() && steps.install.outcome == 'success'
continue-on-error: true
shell: pwsh
run: |
npm.cmd run windows:inventory *> "$env:WINDOWS_BASELINE_LOG_DIR/inventory.log"
$exitCode = $LASTEXITCODE
Get-Content "$env:WINDOWS_BASELINE_LOG_DIR/inventory.log"
exit $exitCode
- id: smoke
name: Run CLI and Electron startup smoke
if: always() && steps.build.outcome == 'success'
continue-on-error: true
shell: pwsh
run: |
npm.cmd --workspace @maka/desktop run build:smoke *> "$env:WINDOWS_BASELINE_LOG_DIR/smoke-build.log"
$exitCode = $LASTEXITCODE
Get-Content "$env:WINDOWS_BASELINE_LOG_DIR/smoke-build.log"
if ($exitCode -ne 0) { exit $exitCode }
npm.cmd run smoke:windows:dist *> "$env:WINDOWS_BASELINE_LOG_DIR/smoke.log"
$exitCode = $LASTEXITCODE
Get-Content "$env:WINDOWS_BASELINE_LOG_DIR/smoke.log"
exit $exitCode
- id: runtime_pty_input
name: Run Runtime PTY input gates
if: always() && steps.build.outcome == 'success' && needs.changes.outputs.windows_runtime == 'true'
continue-on-error: true
timeout-minutes: 5
shell: pwsh
run: |
node.exe --test --test-force-exit --test-timeout=15000 --test-reporter=tap --test-concurrency=1 --test-name-pattern="semantic text and Enter actions|terminal mode parsed before the control cut" packages/runtime/dist/__tests__/shell-run-manager.test.js 2>&1 |
Tee-Object -FilePath "$env:WINDOWS_BASELINE_LOG_DIR/runtime-pty-input.log"
$exitCode = $LASTEXITCODE
$output = Get-Content "$env:WINDOWS_BASELINE_LOG_DIR/runtime-pty-input.log"
if ($exitCode -eq 0 -and ($output -notcontains '# tests 2' -or $output -notcontains '# pass 2')) {
Write-Error 'Runtime PTY input gate did not run exactly two passing tests'
exit 1
}
exit $exitCode
# Full packages/storage test:dist is ~10 minutes on windows-latest and
# mostly duplicates the Linux unit lane. Baseline keeps process/path/
# lock-sensitive gates here. Release-blocking crash evidence belongs to
# windows-recovery.yml, so this diagnostic lane does not duplicate it.
# Bump concurrency carefully — several suites spawn child processes and
# fight for disk under high fan-out.
- id: storage
name: Run Windows storage path and lock gates
if: always() && steps.build.outcome == 'success' && needs.changes.outputs.windows_storage == 'true'
continue-on-error: true
timeout-minutes: 12
shell: pwsh
run: |
$storageGates = @(
'packages/storage/dist/__tests__/root-authority.test.js',
'packages/storage/dist/__tests__/sqlite-recovery-concurrency.test.js',
'packages/storage/dist/__tests__/artifact-writer-lock.test.js',
'packages/storage/dist/__tests__/write-queue.test.js',
'packages/storage/dist/__tests__/marker-file.test.js',
'packages/storage/dist/__tests__/workspace-root.test.js',
'packages/storage/dist/__tests__/managed-workspace-owner.test.js',
'packages/storage/dist/__tests__/workspace-identity.test.js'
)
node.exe --test --test-concurrency=2 --test-force-exit --test-timeout=60000 `
@storageGates `
2>&1 | Tee-Object -FilePath "$env:WINDOWS_BASELINE_LOG_DIR/storage.log"
exit $LASTEXITCODE
# Full suite is evidence-only: nightly + manual dispatch. Do not run on
# ordinary PRs — Linux unit already covers the package, and the full
# Windows wall clock is ~10 minutes.
- id: storage_full
name: Capture full storage suite baseline
if: always() && steps.build.outcome == 'success' && needs.changes.outputs.windows_storage_full == 'true'
continue-on-error: true
timeout-minutes: 25
shell: pwsh
run: |
node.exe scripts/run-workspace-tests-parallel.mjs --concurrency=1 --workspaces=packages/storage *> "$env:WINDOWS_BASELINE_LOG_DIR/storage-full.log"
$exitCode = $LASTEXITCODE
Get-Content "$env:WINDOWS_BASELINE_LOG_DIR/storage-full.log"
exit $exitCode
- id: processes
name: Audit residual job processes
if: always()
continue-on-error: true
shell: pwsh
run: |
. ./scripts/windows-process-identity.ps1
$baseline = Get-Content "$env:WINDOWS_BASELINE_LOG_DIR/process-baseline.json" -Raw |
ConvertFrom-Json
$baselineKeys = [System.Collections.Generic.HashSet[string]]::new(
[System.StringComparer]::Ordinal
)
foreach ($process in @($baseline.Processes)) {
[void]$baselineKeys.Add((Get-WindowsProcessIdentityKey $process))
}
$allProcesses = @(
Get-CimInstance Win32_Process |
ForEach-Object {
[pscustomobject]@{
ProcessId = $_.ProcessId
ParentProcessId = $_.ParentProcessId
Name = $_.Name
CreationDate = $_.CreationDate.ToUniversalTime().ToString('o')
CommandLine = $_.CommandLine
}
}
)
$leaks = @(
$allProcesses | Where-Object {
$_.Name -in @('node.exe', 'electron.exe') -and
-not $baselineKeys.Contains((Get-WindowsProcessIdentityKey $_))
}
)
ConvertTo-Json -InputObject $leaks -Depth 3 |
Set-Content "$env:WINDOWS_BASELINE_LOG_DIR/residual-processes.json"
if ($leaks.Count -eq 0) {
Write-Output 'No residual job-created Node or Electron processes.'
exit 0
}
$treeProcessIds = [System.Collections.Generic.HashSet[int]]::new()
foreach ($process in $leaks) {
[void]$treeProcessIds.Add($process.ProcessId)
}
do {
$addedDescendant = $false
foreach ($process in $allProcesses) {
if (
$treeProcessIds.Contains($process.ParentProcessId) -and
$treeProcessIds.Add($process.ProcessId)
) {
$addedDescendant = $true
}
}
} while ($addedDescendant)
$ownedTree = @(
$allProcesses | Where-Object { $treeProcessIds.Contains($_.ProcessId) }
)
ConvertTo-Json -InputObject $ownedTree -Depth 3 |
Set-Content "$env:WINDOWS_BASELINE_LOG_DIR/residual-process-tree.json"
$leaks | Format-List | Out-String | Tee-Object -FilePath "$env:WINDOWS_BASELINE_LOG_DIR/residual-processes.log"
foreach ($process in $leaks) {
& taskkill.exe /PID $process.ProcessId /T /F 2>&1 |
Add-Content "$env:WINDOWS_BASELINE_LOG_DIR/process-cleanup.log"
}
Start-Sleep -Seconds 1
$remainingById = @{}
Get-CimInstance Win32_Process |
ForEach-Object {
$key = Get-WindowsProcessIdentityKey $_
$remainingById[$key] = $_
}
$unreaped = @(
$ownedTree | Where-Object {
$remainingById.ContainsKey((Get-WindowsProcessIdentityKey $_))
}
)
ConvertTo-Json -InputObject $unreaped -Depth 3 |
Set-Content "$env:WINDOWS_BASELINE_LOG_DIR/residual-processes-after-cleanup.json"
if ($unreaped.Count -gt 0) {
Write-Error "Failed to reap $($unreaped.Count) process(es) from the residual job tree."
exit 1
}
Write-Error "Found $($leaks.Count) residual job root(s) and reaped their $($ownedTree.Count)-process tree."
exit 1
- name: Publish baseline summary
if: always()
shell: pwsh
run: |
@"
## Windows baseline
This lane is intentionally non-blocking while the Phase 1 backlog is being reduced.
| Check | Outcome |
|---|---|
| Install | ${{ steps.install.outcome }} |
| Build | ${{ steps.build.outcome }} |
| Skip inventory | ${{ steps.inventory.outcome }} |
| CLI / Electron smoke | ${{ steps.smoke.outcome }} |
| Storage path/lock gates | ${{ steps.storage.outcome }} |
| Runtime PTY input | ${{ steps.runtime_pty_input.outcome }} |
| Full storage suite (nightly/manual) | ${{ steps.storage_full.outcome }} |
| Residual processes | ${{ steps.processes.outcome }} |
Download the `windows-baseline` artifact for complete logs.
"@ >> $env:GITHUB_STEP_SUMMARY
- name: Upload Windows baseline logs
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: windows-baseline
path: artifacts/windows-baseline
if-no-files-found: warn
retention-days: 14