Dependency audit / audit (push) Canceled after 0s
CI / plan (push) Canceled after 0s
Gitoxide helper admission / macos-latest (push) Canceled after 0s
Gitoxide helper admission / ubuntu-latest (push) Canceled after 0s
Gitoxide helper admission / windows-latest (push) Canceled after 0s
Runtime Host peer admission / quality (push) Canceled after 0s
Windows recovery / windows_recovery (push) Canceled after 0s
CI / heavy (push) Canceled after 0s
CI / test (push) Canceled after 0s
195 lines
8.9 KiB
YAML
195 lines
8.9 KiB
YAML
# Licensed to the Apache Software Foundation (ASF) under one
|
|
# or more contributor license agreements. See the NOTICE file
|
|
# distributed with this work for additional information
|
|
# regarding copyright ownership. The ASF licenses this file
|
|
# to you under the Apache License, Version 2.0 (the
|
|
# "License"); you may not use this file except in compliance
|
|
# with the License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing,
|
|
# software distributed under the License is distributed on an
|
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
# KIND, either express or implied. See the License for the
|
|
# specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
name: Windows recovery
|
|
|
|
# The paths below are a pre-filter, not this lane's real input. The real input
|
|
# is the import closure of the crash and owner-death recovery authorities in
|
|
# storage, runtime and Runtime Host, which reaches well past any list worth
|
|
# hand-maintaining. So they name those workspaces and every workspace they hold
|
|
# a TypeScript project reference to, plus the manifests, patches and scripts
|
|
# the unconditional install and clean steps consume. That keeps a change there
|
|
# reported before merge, and the nightly run covers the transitive edits the
|
|
# list cannot match.
|
|
#
|
|
# GitHub evaluates a path filter against the first 300 files of the diff only,
|
|
# so a pull request wider than that can skip the filter outright. A repository-wide sweep is exactly the change that touches every
|
|
# recovery authority at once, which is one more reason the main push below
|
|
# carries no filter at all.
|
|
on:
|
|
pull_request:
|
|
branches: [main]
|
|
paths:
|
|
- 'package.json'
|
|
- 'package-lock.json'
|
|
- 'patches/**'
|
|
- 'scripts/apply-dependency-patches.mjs'
|
|
- 'scripts/install-electron-with-retry.mjs'
|
|
- 'scripts/run-electron-installer.cjs'
|
|
- 'scripts/clean-build.mjs'
|
|
- 'scripts/clean-paths.mjs'
|
|
- 'scripts/windows-runtime-host-local-ipc-trust.ps1'
|
|
- 'tsconfig.base.json'
|
|
- 'tsconfig.lib.json'
|
|
- 'packages/core/package.json'
|
|
- 'packages/core/tsconfig.json'
|
|
- 'packages/core/src/**'
|
|
- 'packages/storage/package.json'
|
|
- 'packages/storage/tsconfig.json'
|
|
- 'packages/storage/src/**'
|
|
- 'packages/runtime/package.json'
|
|
- 'packages/runtime/tsconfig.json'
|
|
- 'packages/runtime/src/**'
|
|
- 'packages/runtime/scripts/**'
|
|
- 'packages/runtime-host/package.json'
|
|
- 'packages/runtime-host/tsconfig.json'
|
|
- 'packages/runtime-host/src/**'
|
|
- '.github/workflows/windows-recovery.yml'
|
|
# Unfiltered on purpose: required_status_checks is `strict: false`, so a pull
|
|
# request goes green against a stale base and only the merged result proves
|
|
# two independently green halves still agree. It is also the backstop for the
|
|
# 300-file case above. The nightly alone would find either a day later,
|
|
# against a batch of commits instead of one.
|
|
push:
|
|
branches: [main]
|
|
schedule:
|
|
# Offset from windows-sandbox-w0 so the Windows lanes do not overlap.
|
|
- cron: '17 8 * * *'
|
|
workflow_dispatch:
|
|
|
|
# Pull request pushes supersede each other, keyed on the pull request number
|
|
# because github.head_ref is a bare branch name two forks can share: a second
|
|
# contributor pushing to their own `main` would otherwise cancel the first
|
|
# contributor's run, and a cancelled check is not a failed one.
|
|
# Scheduled, manual and main-push runs fall back to the run id, since
|
|
# github.ref is refs/heads/main for all three and one shared group would let a
|
|
# dispatch queue behind the nightly and then be discarded while still pending.
|
|
# That deliberately stops main pushes from superseding each other: this lane is
|
|
# the only place a merged Windows regression is observed, so every merge needs
|
|
# its own evidence rather than only the newest one surviving.
|
|
concurrency:
|
|
group: windows-recovery-${{ github.event.pull_request.number || github.run_id }}
|
|
cancel-in-progress: true
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
windows_recovery:
|
|
name: windows_recovery
|
|
runs-on: windows-latest
|
|
timeout-minutes: 45
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
with:
|
|
node-version: "24"
|
|
cache: npm
|
|
|
|
- name: Install dependencies
|
|
run: npm.cmd ci
|
|
|
|
- name: Build test artifacts
|
|
run: npm.cmd run build:test
|
|
|
|
- name: Verify managed dependency alternate streams
|
|
shell: pwsh
|
|
run: |
|
|
node.exe --test --test-reporter=tap --test-concurrency=1 `
|
|
--test-name-pattern="NTFS alternate stream" `
|
|
packages/storage/dist/__tests__/managed-dependency-environment.test.js `
|
|
2>&1 | Tee-Object -FilePath "$env:RUNNER_TEMP/managed-dependency-ads.tap"
|
|
$exitCode = $LASTEXITCODE
|
|
if ($exitCode -ne 0) { exit $exitCode }
|
|
$output = Get-Content "$env:RUNNER_TEMP/managed-dependency-ads.tap"
|
|
if ($output -notcontains '# tests 3' -or $output -notcontains '# pass 3' -or $output -notcontains '# skipped 0') {
|
|
Write-Error 'Managed dependency ADS gate did not run exactly three passing Windows tests'
|
|
exit 1
|
|
}
|
|
|
|
- name: Verify root initialization replacement race
|
|
shell: pwsh
|
|
run: |
|
|
node.exe --test --test-reporter=tap --test-concurrency=1 `
|
|
--test-name-pattern="rejects replacement before opening the temporary marker" `
|
|
packages/storage/dist/__tests__/root-authority.test.js `
|
|
2>&1 | Tee-Object -FilePath "$env:RUNNER_TEMP/root-initialization-race.tap"
|
|
$exitCode = $LASTEXITCODE
|
|
if ($exitCode -ne 0) { exit $exitCode }
|
|
$output = Get-Content "$env:RUNNER_TEMP/root-initialization-race.tap"
|
|
if ($output -notcontains '# tests 1' -or $output -notcontains '# pass 1' -or $output -notcontains '# skipped 0') {
|
|
Write-Error 'Root initialization race gate did not run exactly one passing Windows test'
|
|
exit 1
|
|
}
|
|
|
|
- name: Verify Runtime Host Local IPC trust boundary
|
|
shell: pwsh
|
|
run: |
|
|
node.exe --test packages/runtime-host/dist/__tests__/control-endpoint.test.js
|
|
./scripts/windows-runtime-host-local-ipc-trust.ps1
|
|
|
|
- name: Verify Skill catalog on Windows
|
|
shell: pwsh
|
|
run: |
|
|
node.exe --test --test-reporter=tap --test-concurrency=1 `
|
|
packages/runtime-host/dist/__tests__/skill-catalog-coordinator.test.js `
|
|
packages/runtime-host/dist/__tests__/skill-catalog-protocol.test.js `
|
|
packages/runtime-host/dist/__tests__/skill-catalog-repository.test.js `
|
|
packages/runtime-host/dist/__tests__/skill-catalog-transaction.test.js `
|
|
packages/runtime-host/dist/__tests__/skill-catalog-two-client-uds.test.js `
|
|
2>&1 | Tee-Object -FilePath "$env:RUNNER_TEMP/skill-catalog.tap"
|
|
$exitCode = $LASTEXITCODE
|
|
if ($exitCode -ne 0) { exit $exitCode }
|
|
$output = Get-Content "$env:RUNNER_TEMP/skill-catalog.tap"
|
|
if ($output -notcontains '# tests 91' -or $output -notcontains '# pass 91' -or $output -notcontains '# skipped 0') {
|
|
Write-Error 'Skill catalog gate did not run exactly 91 passing Windows tests'
|
|
exit 1
|
|
}
|
|
|
|
- name: Verify SQLite crash recovery
|
|
shell: pwsh
|
|
run: |
|
|
node.exe --test --test-concurrency=1 `
|
|
packages/storage/dist/__tests__/sqlite-runtime-crash.test.js `
|
|
packages/storage/dist/__tests__/sqlite-long-term-memory-crash.test.js
|
|
|
|
- name: Verify Runtime continuation recovery
|
|
shell: pwsh
|
|
run: |
|
|
node.exe --test --test-concurrency=1 `
|
|
packages/runtime/dist/__tests__/runtime-resume-crash.test.js `
|
|
packages/runtime/dist/__tests__/runtime-continuation-crash.test.js
|
|
|
|
- name: Verify Runtime Host owner-death recovery
|
|
shell: pwsh
|
|
run: |
|
|
node.exe --test --test-reporter=tap --test-concurrency=1 `
|
|
--test-name-pattern="owner death|a killed Host is recovered exactly once" `
|
|
packages/runtime-host/dist/__tests__/artifact-two-client-uds.test.js `
|
|
packages/runtime-host/dist/__tests__/execution-host-queue.test.js `
|
|
2>&1 | Tee-Object -FilePath "$env:RUNNER_TEMP/runtime-host-recovery.tap"
|
|
$exitCode = $LASTEXITCODE
|
|
if ($exitCode -ne 0) { exit $exitCode }
|
|
$output = Get-Content "$env:RUNNER_TEMP/runtime-host-recovery.tap"
|
|
if ($output -notcontains '# tests 2' -or $output -notcontains '# pass 2' -or $output -notcontains '# skipped 0') {
|
|
Write-Error 'Runtime Host recovery gate did not run exactly two passing tests'
|
|
exit 1
|
|
}
|