Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,6 @@ jobs:
if ($blockingAlerts.Count) { throw "Unresolved serious code-scanning findings on main: $($blockingAlerts -join ', ')" }
gh run download $runs['verify.yml'] --name "AppSwitcher-$commit" --dir artifacts/release-upload
./scripts/check-release-artifacts.ps1 -Path artifacts/release-upload -Version $version -Commit $commit
if ($version -notmatch '-') {
foreach ($installer in Get-ChildItem artifacts/release-upload -Filter '*-setup.exe') {
if ((Get-AuthenticodeSignature -LiteralPath $installer.FullName).Status -ne 'Valid') { throw 'Stable installer lacks a valid Windows publisher signature.' }
}
}
foreach ($asset in Get-ChildItem artifacts/release-upload -File) {
gh attestation verify $asset.FullName --repo $env:GITHUB_REPOSITORY --signer-workflow "$env:GITHUB_REPOSITORY/.github/workflows/verify.yml" --source-ref refs/heads/main --source-digest $commit --deny-self-hosted-runners
}
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## 1.2.0 — 2026-11-03

- Support unsigned stable Windows releases under the owner's zero-cost distribution policy. Remove mandatory publisher signing from stable builds and acceptance records; retain workstation and offline-browser acceptance, exact-commit verification, security scans, checksums, manifests, SPDX inventories, attestations and immutable release assets. Optional installer signatures must still be valid.
- Update release and installation guidance to disclose unsigned stable distribution. The existing Mozilla-signed Firefox payload is unchanged.
- Scope acceptance to the intended workstations with no audio output: make actual Narrator speech testing optional while retaining keyboard navigation, visible focus/errors/status, high contrast, touch usability and automated accessibility checks.
- Record offline VM qualification of the published RC, including actual installer upgrade/rollback/uninstall, released browser-bridge recovery, and persistent Chrome/Edge installations with two unattended offline restarts each. Keep their manual folder-picker walkthrough and target-workstation acceptance open. Update installer wording for beta, RC and stable packages.
- Fix the browser test helper's disconnect handling so it consumes POST bodies before replying and clears stale connections before a reconnect check; add a regression that fails against the old helper. Released application and extension behavior is unchanged.

This first **unsigned Windows x64 stable release** includes the RC's session-timeout, operator-scope, scheduler, lifecycle, window-restoration and audit-log fixes, plus explicit Save/discard behavior and streamlined application/browser setup. The Mozilla-signed offline Firefox bridge remains byte-for-byte 1.1.0, and configuration remains schema 12. Roll back with the previous binary and its pre-upgrade configuration backup.

The owner authorized publication with [documented validation limits](https://github.com/Sparkz400/AppSwitcher/blob/main/docs/RELEASE_ACCEPTANCE_1.2.0.md): physical workstation/full-shift acceptance and the Chrome/Edge manual folder-picker walkthrough remain unperformed. Persistent browser installation and unattended offline restarts passed. Site deployment still requires its applicable acceptance checks. Windows publisher signing, browser-store publication and Narrator speech are not required for the agreed zero-cost, silent-workstation scope. Windows may show an unknown-publisher warning; verify the downloaded checksums and build/release attestations.

## 1.2.0-rc.1 — 2026-11-03

- Repair session timeout transitions, scheduler retries, lifecycle cancellation, manual minimization and stale HTTP health results.
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Install Git, PowerShell 7, the SDK specified by `global.json` and Node.js 24. Fr
./scripts/build-release.ps1
```

The first command restores locked packages, builds, runs .NET/extension tests, renders native UI, and exercises isolated process/recovery behavior. It opens synthetic windows and checks that the real saved configuration is unchanged. The second builds the self-contained Windows x64 package, validates bundled Firefox source/signature payload correspondence, checks installer install/upgrade/rollback/uninstall, and emits the ZIP, setup EXE, submission materials and checksums under `artifacts/releases`. Candidates are unsigned unless publisher signing is configured; stable builds require signing as described in [Maintenance](MAINTENANCE.md).
The first command restores locked packages, builds, runs .NET/extension tests, renders native UI, and exercises isolated process/recovery behavior. It opens synthetic windows and checks that the real saved configuration is unchanged. The second builds the self-contained Windows x64 package, validates bundled Firefox source/signature payload correspondence, checks installer install/upgrade/rollback/uninstall, and emits the ZIP, setup EXE, submission materials and checksums under `artifacts/releases`. Beta, RC and stable builds are unsigned unless optional publisher signing is configured; no paid signing identity is required. See [Maintenance](MAINTENANCE.md).

A build with uncommitted changes records `dirty: true` in its release manifest and must not be published as a release. Output directories are revision-specific and existing release artifacts are never overwritten. Build a new revision or use a fresh checkout when repeating a release build. Build-time package/compiler downloads need internet access; deployment does not.

Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>1.2.0-rc.1</Version>
<Version>1.2.0</Version>
<DefaultItemExcludes>$(DefaultItemExcludes);**\artifacts\**;**\output\**;**\obj_*\**</DefaultItemExcludes>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<RuntimeIdentifiers>win-x64</RuntimeIdentifiers>
Expand Down
20 changes: 12 additions & 8 deletions MAINTENANCE.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
# Maintenance and release policy

AppSwitcher is a community-maintained release candidate. There is no promised release schedule, response time, service-level agreement or machine certification. The repository is available for inspection, modification and independent builds under MIT. Report reproducible bugs with synthetic data; production deployments remain the operator's responsibility.
AppSwitcher is a community-maintained Windows application. There is no promised release schedule, response time, service-level agreement or machine certification. The repository is available for inspection, modification and independent builds under MIT. Report reproducible bugs with synthetic data; production deployments remain the operator's responsibility.

## Supported line

The latest `1.2.0-rc.*` and `main` receive fixes. Older betas are retained for controlled rollback, not maintained in parallel. Version numbers use `major.minor.patch` with a beta or RC suffix while interfaces and configuration behavior are still being qualified. An incompatible configuration or bridge protocol change must be called out in the changelog with migration and rollback instructions.
The `1.2` line and `main` receive fixes. Older betas are retained for controlled rollback, not maintained in parallel. Version numbers use `major.minor.patch`, with a beta or RC suffix for prereleases. Preparing a stable-version package does not bypass its publication acceptance gates. An incompatible configuration or bridge protocol change must be called out in the changelog with migration and rollback instructions.

The release target is Windows 11 x64 with a self-contained .NET runtime. The installer permits compatible Windows 10 build 19041 or later, but installation compatibility is not an operating-system support commitment. Use a Windows edition still supported under your organization's Microsoft servicing arrangement. ARM64 emulation, Windows Server, remote desktop, specific kiosk editions, unusual display drivers and physical touch panels require separate acceptance. The desktop app is not supported on macOS or Linux.

The extension manifests declare Chrome/Edge 120+ and Firefox 142+ compatibility. Deploy a browser with current vendor security support and test the exact version/profile/policy combination. Manifest minimums are API floors, not a promise to support obsolete browsers. Store approval and code signing are separate distribution steps; this beta is unsigned and uses offline extension installation.
The extension manifests declare Chrome/Edge 120+ and Firefox 142+ compatibility. Deploy a browser with current vendor security support and test the exact version/profile/policy combination. Manifest minimums are API floors, not a promise to support obsolete browsers. AppSwitcher uses offline extension installation and supports unsigned Windows releases, including stable. The project requires no paid signing identity or paid store distribution.

## Before each release

1. Review open bug/security reports and update release notes, supported versions and known limitations.
2. Restore locked packages; review vulnerability results, dependency licenses and asset/source provenance. Review new dependencies before updating the inventory.
3. Run full Windows CI at the exact source commit and retain native captures, test reports and installer evidence. Re-run real browser/restart checks when browser integration changes.
4. For a deployment candidate, record a sustained-run result and complete [workstation acceptance](docs/WORKSTATION_ACCEPTANCE.md) for the target site. No unattended update is enabled.
5. Build from a clean tagged source revision. Verify the archive manifest, setup/ZIP checksums, unsigned status and bundled Firefox payload. Publish release notes with exact evidence boundaries.
5. Build from a clean tagged source revision. Verify the archive manifest, setup/ZIP checksums, actual signing status and bundled Firefox payload. Unsigned releases are supported; any optional publisher signature must be valid. Publish release notes with exact evidence boundaries and disclose the signing status.
6. Keep the previous release and a pre-update configuration backup for rollback. Publish a correction or replacement version if a release is faulty; never silently replace a published asset.

Dependency update proposals are checked weekly by automation. That cadence is a check, not a promise that updates will be merged weekly. Security reports and user-visible regressions take priority over feature work.
Expand All @@ -25,7 +25,7 @@ Dependency update proposals are checked weekly by automation. That cadence is a

1. Update `Directory.Build.props` and the matching version section in `CHANGELOG.md` in a normal pull request. Review dependency notices and complete the checks above.
2. Merge through the protected branch. Wait for **Windows verification** and **CodeQL** to succeed on the exact resulting `main` commit, not just the pull-request merge preview.
3. Create and push the matching `vX.Y.Z-beta.N`, `vX.Y.Z-rc.N`, or qualified `vX.Y.Z` tag at that commit. The **Publish verified release** workflow checks the version and main ancestry, refuses open critical/high-security or error-level code-scanning findings on `main`, then downloads the eight assets from that commit's successful Windows run. It verifies package/source manifests, checksums, the SPDX inventory, and signed build/SBOM attestations from the exact main revision. It creates a draft, checks uploaded asset digests, then publishes an immutable prerelease with links to the verification runs.
3. Create and push the matching `vX.Y.Z-beta.N`, `vX.Y.Z-rc.N`, or authorized `vX.Y.Z` tag at that commit. The **Publish verified release** workflow checks the version and main ancestry, refuses open critical/high-security or error-level code-scanning findings on `main`, then downloads the eight assets from that commit's successful Windows run. It verifies package/source manifests, checksums, the SPDX inventory, and signed build/SBOM attestations from the exact main revision. It creates a draft, checks uploaded asset digests, then publishes an immutable release with links to the verification runs; beta/RC tags remain prereleases.

The workflow publishes the tested artifact without rebuilding it. Artifacts are retained for 30 days; if the artifact expired, rerun Windows verification for the exact commit before tagging. A tag pushed before checks finish fails publication; after resolving the cause, rerun the failed release workflow without moving the tag. Existing releases are never overwritten. A correction to a published release needs a new version.

Expand All @@ -35,14 +35,18 @@ GitHub generates the immutable release attestation after publication. Verificati

Keep repository immutable releases enabled and the active `v*` tag ruleset in place, with updates/deletion denied and creation allowed. Existing beta.1/beta.2 assets remain unchanged and do not gain immutable status retroactively. Main builds produce provenance for all eight assets and an SBOM attestation for the desktop ZIP/installer only; pull requests do not produce publication attestations. See [download verification and inventory scope](docs/VERIFY_DOWNLOADS.md).

Beta/RC artifacts remain unsigned prereleases. Stable tags additionally require reviewed evidence in `docs/release-readiness.json` (workstation, Narrator, offline browsers, publisher signing), an ancestor qualification revision without subsequent code/build changes, and a valid Authenticode signature on the exact installer. Stable publication becomes the latest release; prereleases do not. Missing evidence blocks stable publication. No certificate or signing service is bundled.
Beta, RC and stable artifacts may be unsigned. Stable tags additionally require reviewed records in `docs/release-readiness.json` (workstation, offline browsers) and an ancestor reviewed revision without subsequent code/build changes. A record must be passed or explicitly deferred under versioned owner authorization, with a reason and evidence report. Deferred checks require an exact list of their scope and `deploymentAccepted: false`; missing/pending records still block publication. The [1.2.0 decision](docs/RELEASE_ACCEPTANCE_1.2.0.md) records the owner's instruction to publish with disclosed deployment limits. Stable publication becomes the latest release; prereleases do not. Windows publisher signing is optional; no certificate purchase or paid signing service is required. Checksums, manifests, SPDX inventory, security scans, exact-commit CI, build/release attestations and immutable assets remain required. An optional installer publisher signature must be valid; invalid or untrusted signatures are rejected.

The owner selected zero-cost, unsigned Windows distribution on 3 November 2026. Release notes and installation guidance must disclose that Windows may show an unknown-publisher or reputation warning. GitHub attestations verify build/release provenance; they do not provide a Windows publisher signature. The bundled Mozilla-signed Firefox bridge is separate and remains unchanged.

The intended workstations have no audio output. Actual Narrator speech testing is optional follow-up work, outside this deployment's stable-release acceptance scope; it is not recorded as passed. Keyboard navigation, visible focus, visible errors/status, high contrast and touch/glove usability remain part of workstation acceptance. Existing automated accessible-name and UI Automation checks remain enabled. A deployment that needs spoken screen-reader output requires separate qualification of that flow.

Schema 12 preserves explicit empty operator restrictions and migrates the old 40px launcher/menu defaults. Roll back using the old binary **and its pre-upgrade configuration backup**; older versions cannot safely interpret the new empty-restricted scope. Do not feed schema-12 configuration to a beta launcher. Encryption remains tied to its Windows account. Retain browser ownership journals/profiles for rollback; never regenerate identities to bypass recovery.

Normal release preparation never changes main protection or invents a reviewer. The sole-maintainer PR policy remains in effect; add required second-person review when an actual reviewer is available.

## Publisher signing preparation
## Optional publisher signing

An authorized signing runner may set `APPSWITCHER_SIGNING_CERTIFICATE_THUMBPRINT` to a code-signing certificate already provisioned in its current-user certificate store, and `APPSWITCHER_SIGNING_TIMESTAMP_SERVER` to the publisher-approved timestamp service. No private key or certificate is committed, exported or installed by these scripts. Only the four AppSwitcher-owned app/host EXE/DLL files and the distributable installer are signed, before manifests, hashes and attestations are generated. Third-party binaries and the Mozilla XPI are preserved. Test installers use a separate product identity and remain unsigned.

The helper uses [Windows Authenticode signing](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-authenticodesignature), checks code-signing usage, certificate dates/private-key presence, signature validity and timestamp presence. Without configured signing, RC builds explicitly remain unsigned and stable builds stop. Hosted CI has no signing credential configured by this change; the real signing path must be qualified by the publisher before marking its gate passed.
The helper uses [Windows Authenticode signing](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-authenticodesignature), checks code-signing usage, certificate dates/private-key presence, signature validity and timestamp presence. Without configured signing, beta, RC and stable builds explicitly remain unsigned. Hosted CI has no signing credential configured. If signing is introduced later, qualify that path and update the disclosed signing status before publishing signed artifacts; this is not required for the zero-cost release.
Loading
Loading