CI: Windows leg for pull requests that change Windows code, or labelled full-ci (#3793)

* CI: Windows leg for pull requests that change Windows code, or labelled full-ci

* ci-windows: also run on manifest and Cargo.lock changes

* deps: craft-update with flate2's miniz backend (fixes larger-than-raw ZIP TIFFs on Windows)

craft-update's zip dependency used the `deflate` feature, which pulls in
flate2's zlib-rs backend. Cargo unifies flate2's features across the app, so
on Windows the whole of Lightcraft used zlib-rs, whose level 1 (the TIFF
exporter's DeflateLevel::Fast) is a static-Huffman mode that can make a
16-bit ZIP TIFF larger than the uncompressed one. storytold/craft-libs#608
switches craft-update to `deflate-flate2` (miniz_oxide), the backend Linux
and macOS already use.

Only craft-update's rev moves (c5a1cbf -> a231e51); the other craft-libs
crates stay where they are.

* ci-windows: cover lightcraft-cli and menus/files.rs (cfg(windows) code)
This commit is contained in:
FredApps
2026-11-05 16:37:49 +01:00
committed by GitHub
parent 4b5dc8b90a
commit 5cd7eb107e
4 changed files with 82 additions and 1 deletions
+78
View File
@@ -0,0 +1,78 @@
name: CI (Windows)
# The Windows leg of the gate: clippy and the tests of the crates with Windows-only code, on pull
# requests and pushes to main that touch that code, and on pull requests labelled `full-ci`.
# The Linux gate (ci.yml) still runs everything else on every pull request.
#
# Not the full `cargo xtask ci`: on a cold windows-latest runner that is well over an hour, and
# its wasm, layers, assets and parity steps don't differ by platform. What does is the
# `cfg(windows)` code (title bar theme, monitor profiles, file handling) and its tests.
on:
push:
branches: [main]
pull_request:
# `labeled`: adding `full-ci` starts it. Other labels skip (see concurrency and the scope job).
types: [opened, synchronize, reopened, labeled]
workflow_dispatch:
permissions:
contents: read
# Its own group, so the Windows leg never cancels the Linux gate. A newer push to a PR branch
# cancels its older run; a label other than `full-ci` gets a group of its own, so it cancels nothing.
concurrency:
group: ci-windows-${{ github.event_name == 'pull_request' && github.ref || github.run_id }}${{ github.event.action == 'labeled' && github.event.label.name != 'full-ci' && format('-label-{0}', github.run_id) || '' }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
windows-scope:
if: github.event.action != 'labeled' || github.event.label.name == 'full-ci'
uses: storytold/craft-common-actions/.github/workflows/changed-paths.yml@main
with:
label: full-ci
# The crates and files with `cfg(windows)` code, and what decides how they build: their
# manifests and the lockfile (a dependency bump can break only Windows).
paths: |
.github/workflows/ci-windows.yml
apps/lightcraft/*
apps/lightcraft-cli/src/bench_cull.rs
apps/lightcraft-cli/tests/it/cli.rs
apps/lightcraft-cli/Cargo.toml
crates/wincolor/*
crates/ui-egui/src/theme.rs
crates/ui-egui/src/panels/left/local.rs
crates/ui-egui/src/menus/files.rs
crates/ui-egui/src/dialogs/settings/performance.rs
crates/catalog/src/safe_file.rs
crates/catalog/Cargo.toml
crates/engine/src/originals.rs
crates/engine/src/import/scan.rs
crates/engine/src/walk.rs
crates/engine/src/doc_path.rs
crates/engine/src/rename/*
crates/engine/src/cmd/geocode.rs
crates/engine/src/tests/sync.rs
crates/engine/src/tests/import.rs
crates/engine/Cargo.toml
crates/ui-egui/Cargo.toml
Cargo.toml
Cargo.lock
rust-toolchain.toml
.cargo/*
gate-windows:
needs: windows-scope
if: needs.windows-scope.outputs.matched == 'true'
# Tracks @main so suite-wide CI fixes reach every app without a PR in each repository.
uses: storytold/craft-common-actions/.github/workflows/gate.yml@main
with:
os: '["windows-latest"]'
# Same craft-fonts commit as ci.yml and release.yml.
craft-fonts-ref: b076417b5880bd4154bd22f00695b1d28c6bea83
targets: ""
tools: ""
timeout-minutes: 90
windows-command: |
pkgs=(-p lightcraft-wincolor -p lightcraft-catalog -p lightcraft-engine -p lightcraft-ui-egui -p lightcraft -p lightcraft-cli)
cargo clippy "${pkgs[@]}" --all-targets --keep-going -- -D warnings
cargo test "${pkgs[@]}" --lib --bins --tests --no-fail-fast
+1
View File
@@ -161,4 +161,5 @@ evaluates it (`.github/workflows/nix.yml`), so the build may lag behind the work
## CI workflows
- Workflows in `.github/workflows/` call the shared workflows in [`storytold/craft-common-actions`](https://github.com/storytold/craft-common-actions) at `@main`, with their inputs and secrets. No other jobs: if no shared workflow does what's needed, it doesn't go here.
- Don't add or change CI in a feature or fix PR. If the existing workflows can't build or test a change, link an existing craft-common-actions issue or PR, or open a new issue, or a PR only for a small fix that is safe for every app and does not increase CI time.
- `ci.yml` is the Linux gate, on every pull request. `ci-windows.yml` adds a Windows leg (clippy and tests of the crates with `cfg(windows)` code) when a pull request changes the paths it lists; add the `full-ci` label to run it on any other pull request. When you add `cfg(windows)` code in a new file, add the file to its `paths` in a CI PR.
- Some workflow files here still run their own jobs. Don't add to them. Moving a job into craft-common-actions is its own task, never part of another PR, and the job stays here until a shared workflow runs it.
+1
View File
@@ -160,4 +160,5 @@ evaluates it (`.github/workflows/nix.yml`), so the build may lag behind the work
## CI workflows
- Workflows in `.github/workflows/` call the shared workflows in [`storytold/craft-common-actions`](https://github.com/storytold/craft-common-actions) at `@main`, with their inputs and secrets. No other jobs: if no shared workflow does what's needed, it doesn't go here.
- Don't add or change CI in a feature or fix PR. If the existing workflows can't build or test a change, link an existing craft-common-actions issue or PR, or open a new issue, or a PR only for a small fix that is safe for every app and does not increase CI time.
- `ci.yml` is the Linux gate, on every pull request. `ci-windows.yml` adds a Windows leg (clippy and tests of the crates with `cfg(windows)` code) when a pull request changes the paths it lists; add the `full-ci` label to run it on any other pull request. When you add `cfg(windows)` code in a new file, add the file to its `paths` in a CI PR.
- Some workflow files here still run their own jobs. Don't add to them. Moving a job into craft-common-actions is its own task, never part of another PR, and the job stays here until a shared workflow runs it.
+2 -1
View File
@@ -23,7 +23,7 @@ Hours are Opus 5.5 agent wall-clock hours (see [target-app-parity.md](target-app
| 6 B | **Compressed ORF** (every Olympus / OM body since ~2008) | measured: 66 of 78 Olympus / OM models preview-only; `orf.rs` refuses; OM bucket 3% of photographers, 3% of them fully work | +2.6 points; best gain per hour of any raw gap (~0.2) | 8–15 | [raw-parity](raw-parity.md#compressed-orf-a-clean-room-starting-point) (the two Olympus patents that describe the method) |
| 7 | **Nikon High Efficiency NEF** (HE / HE★ on Z 8, Z 9, Z 6III, Z f, Z50II, Z5II when set to HE) | named and preview only (#193); needs a pure-Rust JPEG XS decoder | +1.1 points (only shots taken in HE; lossless works on the same bodies); low gain per hour (~0.04), so not a beta blocker | 20–40 | [raw-parity](raw-parity.md) |
| 8 B | **Lens profiles: lensfun only, no picker, no own calibration** (LR-EDIT-OPTICS-PROFILE): the desktop app offers lensfun's database (CC BY-SA 3.0, pinned, never bundled) once on the first launch and downloads it on that click or from Settings, then looks every raw up by its lens ([lens-profiles.md](lens-profiles.md)), but those profiles are not validated against Lightroom, there is no profile picker (in the file / lens database / own calibration) and no calibration wizard; in-file corrections: DNG opcodes, RW2 in-file distortion, Sony ILCE-7RM4A, ILCE-7M3, full-frame ILCE-7CR distortion (Auto only) and ILCE-7RM6 and ILCE-6700 distortion (`docs/sony-ilce7rm6-lens-corrections.md`) and Nikon Z 6II / Z 8 / Z f distortion (`docs/nikon-lens-corrections.md`); tracked in #329 | Adobe ships 3,635 lens profiles; we never use them | distortion / vignetting correction is a default step for many | 40–80 + calibration shots | [raw-parity](raw-parity.md#lens-profiles) |
| 9 B | **Tests don't run in CI on macOS or Windows, and no CI job runs the GPU equivalence tests**: the CI gate (`ci.yml`, #2667) runs `cargo xtask ci`, which includes `cargo test`, on Linux x64 for every push to `main` and every pull request; FreeBSD runs `cargo test` nightly, on pushes to `release` and on PRs that change its workflow or `packaging/freebsd/`; the macOS and Windows jobs build packages | `.github/workflows/` (ci, freebsd, packaging-lint, release, sonarcloud, windows-arm64); the gate's runner has Mesa software Vulkan drivers installed, but `Gpu::new` refuses software adapters (`crates/gpu/src/ctx.rs`), so the CPU ↔ GPU equivalence tests skip; the linux-riscv64 release job added in 0.6.0 (#844) runs only `lightcraft-cli --version` under QEMU; #1148 (open, not merged; #2667 names it superseded) has the macOS and Windows test legs and a `LIGHTCRAFT_GPU_ALLOW_SOFTWARE` opt-in that runs the GPU tests on lavapipe, Metal and WARP | a regression that only shows on macOS or Windows, or only on a GPU, reaches users; `cargo xtask ci` runs only on Linux in CI | 6–12 | [target-app-parity](target-app-parity.md#by-dimension) |
| 9 B | **Tests don't run in CI on macOS, run on Windows only for Windows code, and no CI job runs the GPU equivalence tests**: the CI gate (`ci.yml`, #2667) runs `cargo xtask ci`, which includes `cargo test`, on Linux x64 for every push to `main` and every pull request; its Windows leg (`ci-windows.yml`) runs clippy and the tests of the crates with `cfg(windows)` code (wincolor, catalog, engine, ui-egui, lightcraft) on windows-latest when a pull request or a push to `main` changes that code, and on pull requests labelled `full-ci`; FreeBSD runs `cargo test` nightly, on pushes to `release` and on PRs that change its workflow or `packaging/freebsd/`; the macOS and Windows jobs build packages | `.github/workflows/` (ci, ci-windows, freebsd, packaging-lint, release, sonarcloud, windows-arm64); the gate's runner has Mesa software Vulkan drivers installed, but `Gpu::new` refuses software adapters (`crates/gpu/src/ctx.rs`), so the CPU ↔ GPU equivalence tests skip; the linux-riscv64 release job added in 0.6.0 (#844) runs only `lightcraft-cli --version` under QEMU; #1148 (open, not merged; #2667 names it superseded) has the macOS and Windows test legs and a `LIGHTCRAFT_GPU_ALLOW_SOFTWARE` opt-in that runs the GPU tests on lavapipe, Metal and WARP | a regression that only shows on macOS, on Windows in code outside the Windows leg's paths, or only on a GPU, reaches users; the full `cargo xtask ci` runs only on Linux in CI | 6–12 | [target-app-parity](target-app-parity.md#by-dimension) |
| 10 B | **Per-model verification thin, plus cheap per-body decode fixes**: 557 of 1,446 Adobe models verified (39%), ~86% of photographers on a verified body; Nikon 5 bodies verified, Canon 34, Leica 14 (the Q3 by a recorded check of 38 private DNGs). Cheap fixes: Z 6II packed 14-bit NEF (#769, PR #671), Sony A100 regression (#702); F828 SRF now discovered and imported as preview-only, sensor decoding still missing, DSLR-A200…A390 / A850 12-bit ARW (#535) | measured: [raw/coverage.tsv](raw/coverage.tsv) | per-body bugs (levels, crops, WB) surface only from users | 25–45 | [raw-parity](raw-parity.md#by-maker-measured) |
| 11 | **Enhance: Raw Details, Super Resolution; trained denoise weights and X-Trans** | ENH rows 0%; denoise Bayer only; the built-in denoiser is classical (block-matching collaborative filtering), RawNIND weights GPL and opt-in | Fujifilm users get no AI denoise; very noisy files gain less than from a trained model | 30–60 + model decision | [raw-parity](raw-parity.md#demosaic-levels-crops-and-lens-metadata) |
| 12 | **Content-aware / generative remove, detect distractions, reflections removal** | REM rows 75%; patch synthesis missing | cleanup work goes back to Photoshop | 25–45 (+ generative model) | [target-app-parity](target-app-parity.md#ai) |
@@ -188,3 +188,4 @@ Beta-blocking gaps (B) total **~230–430 h**; with the stability and platform w
| 2026-10-24 | patch | LR-META-XMP: sidecar keywords are written as names in `dc:subject` and paths in `lr:hierarchicalSubject`, so other DAMs can search them; ranked gaps and estimates unchanged |
| 2026-10-20 | minor | Opt-in Windows DirectComposition preference added; VRR hardware verification pending; parity counts unchanged |
| 2026-10-25 | minor | Gap 1: first chart-calibrated model, the Canon EOS D60 (ColorChecker Classic under tungsten and sun, `crates/raw/src/chart_table.rs`); the gap stays open, hours unchanged |
| 2026-11-05 | minor | Gap 9: a Windows leg runs clippy and the tests of the crates with Windows-only code when a pull request or push changes that code, or a pull request is labelled `full-ci`; gap not closed (macOS, GPU tests) |