Adds docs/PREUAT.md with: - Week 1 tester paths A–E (generate/print, chartread/average, create profile with applycal/iccgamut policy, profcheck/install). - Week 2 tester paths F–H (CAL_ restore loop, import dataset, gamut viewer + sRGB overlay + camera reset). - Build instructions for Debug (xcodegen + xcodebuild test) and the exact package-release.sh invocation with required secrets. - Gatekeeper / notarization / codesign -dvv and spctl checks. - #24 policy in tester language, CAL_ vs profile basename, Cancel vs Force Quit, import skipping print/measure. - CI note: xcodebuild test must use CODE_SIGNING_ALLOWED=YES and CODE_SIGN_IDENTITY='-' (not NO). Does not modify product code, project.yml, README, BUILD-PLAN, or CI workflows. Generated with Devin Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
6.5 KiB
Pre-UAT tester kit
This document is the canonical pre-UAT runbook. It is a docs-only slice; it does not change product code, project.yml, the build plan, or CI workflows.
Builds that can be used for UAT
Only two artefacts are valid test builds:
- Debug built from this repository (
xcodegen→ Debug →xcodebuild test/run). - A notarized release DMG produced by
scripts/package-release.sh.
Unsigned CI artefacts (e.g. a .zip from a non-notarized workflow run) are not test builds. Do not run them on a clean Mac or Gatekeeper will kill them (Killed: 9).
Local Debug build & unit tests
scripts/fetch-argyll.sh # populates Vendor/Argyll and signs sidecars
xcodegen generate --project .
xcodebuild test -scheme ICCery -destination 'platform=macOS' \
ARCHS='arm64 x86_64' ONLY_ACTIVE_ARCH=NO \
CODE_SIGNING_ALLOWED=YES CODE_SIGN_IDENTITY='-'
Use CODE_SIGNING_ALLOWED=YES and CODE_SIGN_IDENTITY='-' (ad-hoc). CODE_SIGNING_ALLOWED=NO is wrong: the app and test bundles will not be signed and xctest cannot be injected into the test host.
After fetch-argyll.sh, verify that sidecars are signed:
codesign -dvv Vendor/Argyll/macos-universal/instlist
codesign -dvv Vendor/Argyll/macos-universal/chartread
Do not install Argyll to $PATH. ICCery never searches $PATH for binaries.
Release build / notarized DMG
scripts/package-release.sh reads these environment variables:
| Variable | Purpose |
|---|---|
CODESIGN_IDENTITY |
Developer ID Application identity name (omit or - for ad-hoc) |
DEVELOPMENT_TEAM |
Apple development team ID, passed through to xcodebuild |
NOTARIZE_APPLE_ID |
Apple ID for notarytool |
NOTARIZE_PASSWORD |
App-specific password for notarytool |
APPLE_TEAM_ID |
Team ID for notarytool |
Invocation for a signed, notarized DMG:
export CODESIGN_IDENTITY="Developer ID Application: Gronod (TEAMID)"
export DEVELOPMENT_TEAM="TEAMID"
export NOTARIZE_APPLE_ID="apple-id@example.com"
export NOTARIZE_PASSWORD="abcd-efgh-ijkl-mnop"
export APPLE_TEAM_ID="TEAMID"
scripts/package-release.sh
The script will emit ICCery-<version>-<build>.dmg. After mounting, verify Gatekeeper acceptance:
spctl -a -t open --context context:primary-signature -v ICCery-*.dmg
And inside the mounted app bundle:
codesign -dvv --strict ICCery.app
Tester paths
Week 1
Run these in order. Do not remap letters to “run unit tests”.
A — Stage 1 generate → Stage 2 print one page → cancel
- Launch Debug build or notarized DMG.
- Choose a target basename and working directory.
- Stage 1: press Generate target (
targen). - Stage 2: press Print one page.
- Cancel the print panel.
Pass: the print panel appears and the app returns cleanly. The printTask is retained and not dropped.
B — Handheld chartread one sheet → Finish & Average
- From Stage 2, press Print chart pages (or print the full target).
- Stage 3: choose Handheld read.
- Read one full sheet, then press Finish & Average.
Pass: a .ti3 file is produced in the working directory.
C — Create profile, Apply Calibration off
- Stage 4: turn Apply Calibration off.
- Press Create profile.
- If
iccgamutfails or the.gamis missing, an info banner appears.
Pass: the app advances to Stage 5 regardless of the iccgamut outcome. This is issue #24: .gam failure is informational, not fatal.
D — Create profile, Apply Calibration on, missing/bad .cal
- Stage 0: enter a printer calibration and let it complete (or hand-create a
CAL_<something>.cal). - Stage 4: turn Apply Calibration on.
- Rename or delete the
.calfile so it is missing or unreadable. - Press Create profile.
Pass: the app does not advance to Stage 5; applycal failure blocks the profile creation.
E — Stage 5 profcheck + user vs system install / overwrite
- Stage 5: press Run profcheck.
- Press Install profile and choose User install.
- Re-run Install profile and choose System install (or vice-versa).
- When prompted, confirm overwrite.
Pass: profcheck completes, and the profile is installed/updated in the chosen scope.
Week 2
F — Stage 0 full loop; return to profile basename; printtarg -K only on non-CAL_ name
- Enter Stage 0 (printer calibration) and complete the full loop.
- Verify that the live basename returns to the original profile basename (not
CAL_*). - Stage 2 print options:
printtarg -K/-Imust not be present for anyCAL_*basename.
Pass: CAL_ never bleeds into colprof; CAL_*.ti3 is not fed to colprof.
G — Import Dataset open panel
- From any unlocked point where Import dataset is available, open the panel.
- Select a file with one of:
.ti3,.txt,.cgats,.csv.
Pass: the imported .ti3/dataset is accepted; the wizard skips the print and measure stages for the imported file. Do not use a .ti1 file for “save” import here.
H — View Gamut + sRGB overlay + reset camera
- Stage 5: press View gamut.
- Verify the sRGB reference mesh is overlaid.
- Click Reset view (or press
R) to reset the camera. - Close the gamut sheet.
Pass: no GPU hang, the camera resets to the default home position, and the app remains responsive.
Known behaviours / policies
#24 — .gam failure is an info banner
iccgamutmissing or failing aftercolprofdoes not failCreate profile.- The Stage 5 gamut pane falls back to the bundled
sRGB.gamwith no profile mesh. applycalfailing does failCreate profilewhen Apply Calibration is on.
CAL_ vs profile basename; Cancel vs Force Quit
- Entering Stage 0 from a non-
CAL_basename stores the original profile basename. - Cancel in the calibration sheet returns to the original basename.
- A Force Quit mid-calibration leaves
CAL_*behind; on relaunch the app restores the original profile basename. CAL_basenames cannot move togenerate,buildProfile, orverifyInstall.
Import skips print and measure
When a dataset is imported via the open panel, the wizard treats it as already measured. It must not re-print or re-measure the imported data.
What is out of scope for pre-UAT
- No new product features (no #16 or M7 work).
- No
milestone/pre-uatintegration branch. - No
project.ymlsigning, sandbox, or deployment-target changes. - No README or BUILD-PLAN rewrite.
- No CI workflow edits; this document is the single source of truth for the pre-UAT runbook.