name: Windows Update-Survival E2E # Install/update two released Windows builds and prove daemon/input/no-flash behavior on disposable CI only. oneClick uninstalls registry-selected app, so a real workstation install could be deleted. # Feature-branch push enables pre-merge workflow testing before dispatch exists on default; path-filter it to avoid 30min runs on unrelated changes. Push inputs use defaults. on: push: branches: - Jinwoo-H/windows-update-survival paths: - 'tests/tools/win-update-e2e/**' - '.github/workflows/win-update-e2e.yml' workflow_dispatch: inputs: from_tag: description: Release tag to install first (e.g. v1.4.124-rc.8) required: true type: string to_tag: description: Release tag to update to (e.g. v1.4.124-rc.9) required: true type: string expect: description: Expected outcome profile required: true type: choice default: cold-restore options: - cold-restore - survival asset_pattern: description: Installer asset glob required: false type: string default: '*windows-setup.exe' soak_seconds: description: Post-relaunch console-window watch duration required: false type: string default: '60' permissions: contents: read # Why: cancel a superseded run when iterating — a new push to the branch makes # the in-flight Windows job obsolete, so free the runner immediately. concurrency: group: win-update-e2e-${{ github.ref }} cancel-in-progress: true jobs: update-e2e: name: update ${{ inputs.from_tag || 'v1.4.124-rc.8' }} -> ${{ inputs.to_tag || 'v1.4.124-rc.9' }} (${{ inputs.expect || 'cold-restore' }}) runs-on: windows-2022 timeout-minutes: 30 env: FROM_TAG: ${{ inputs.from_tag || 'v1.4.124-rc.8' }} TO_TAG: ${{ inputs.to_tag || 'v1.4.124-rc.9' }} EXPECT: ${{ inputs.expect || 'cold-restore' }} ASSET_PATTERN: ${{ inputs.asset_pattern || '*windows-setup.exe' }} SOAK_SECONDS: ${{ inputs.soak_seconds || '60' }} steps: - name: Checkout uses: actions/checkout@v6 with: # This job only reads the repo and downloads a release; it never pushes. persist-credentials: false - name: Setup Node.js uses: actions/setup-node@v6 with: node-version-file: package.json check-latest: true - name: Setup pnpm uses: pnpm/setup@v2 with: install: false # Why: the harness only needs its runtime deps (the Playwright Electron # driver); it drives already-built installer artifacts, so no app build. - name: Install dependencies run: pnpm install --frozen-lockfile # Why: fail fast with a readable message if a tag has no matching Windows # installer, rather than deep inside the harness. - name: Download installers env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} shell: pwsh run: | New-Item -ItemType Directory -Force artifacts/from | Out-Null New-Item -ItemType Directory -Force artifacts/to | Out-Null gh release download "$env:FROM_TAG" --repo "${{ github.repository }}" --pattern "$env:ASSET_PATTERN" --dir artifacts/from gh release download "$env:TO_TAG" --repo "${{ github.repository }}" --pattern "$env:ASSET_PATTERN" --dir artifacts/to $from = Get-ChildItem artifacts/from -Filter *.exe | Select-Object -First 1 $to = Get-ChildItem artifacts/to -Filter *.exe | Select-Object -First 1 if (-not $from) { throw "No installer matching '$env:ASSET_PATTERN' in $env:FROM_TAG" } if (-not $to) { throw "No installer matching '$env:ASSET_PATTERN' in $env:TO_TAG" } "FROM_EXE=$($from.FullName)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append "TO_EXE=$($to.FullName)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append # Own default per-user install on disposable CI; no real install needs the imperfect isolated-mode protection. - name: Run update-survival harness id: harness shell: pwsh env: # Why: on a driving failure the harness dumps a screenshot + DOM state # here so the actual post-onboarding UI is visible in the artifacts. ORCA_E2E_DIAG_DIR: artifacts/diag run: | $log = "artifacts/harness-output.log" node tests/tools/win-update-e2e/run.mjs ` --from "$env:FROM_EXE" ` --to "$env:TO_EXE" ` --expect "$env:EXPECT" ` --soak-seconds "$env:SOAK_SECONDS" 2>&1 | Tee-Object -FilePath $log exit $LASTEXITCODE - name: Upload harness output if: always() uses: actions/upload-artifact@v7 with: name: win-update-e2e-output # Why: log + diagnostics only, never the multi-hundred-MB installers. path: | artifacts/harness-output.log artifacts/diag/** retention-days: 7 if-no-files-found: warn