Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c9bff50a1a | ||
|
|
1b3d3dd821 | ||
|
|
55dee0f0cd | ||
|
|
45fd2b988f | ||
|
|
7c6ad1e6ce | ||
|
|
9857ddb4d0 | ||
|
|
7a6b82816b |
@@ -24,10 +24,11 @@ jobs:
|
|||||||
- name: Assert Xcode 14 toolchain
|
- name: Assert Xcode 14 toolchain
|
||||||
run: xcodebuild -version | grep -E "Xcode 14." || (echo "Unexpected Xcode version" && exit 1)
|
run: xcodebuild -version | grep -E "Xcode 14." || (echo "Unexpected Xcode version" && exit 1)
|
||||||
|
|
||||||
|
# Homebrew's xcodegen formula requires Xcode 15.3, which cannot be
|
||||||
|
# installed on macOS 12 (#109). The script installs a pinned
|
||||||
|
# prebuilt release instead.
|
||||||
- name: Ensure host tools
|
- name: Ensure host tools
|
||||||
run: |
|
run: scripts/ensure-host-tools.sh
|
||||||
command -v xcodegen || brew install xcodegen
|
|
||||||
python3 -c "import dmgbuild" 2>/dev/null || pip3 install dmgbuild
|
|
||||||
|
|
||||||
- name: Generate Xcode project
|
- name: Generate Xcode project
|
||||||
run: xcodegen generate --spec project.yml
|
run: xcodegen generate --spec project.yml
|
||||||
@@ -134,6 +135,11 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
# scripts/package-release.sh runs `xcodegen generate` and dmgbuild;
|
||||||
|
# see build-and-test for why brew is not used on macOS 12 (#109).
|
||||||
|
- name: Ensure host tools
|
||||||
|
run: scripts/ensure-host-tools.sh
|
||||||
|
|
||||||
- name: Package release
|
- name: Package release
|
||||||
run: scripts/package-release.sh
|
run: scripts/package-release.sh
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -110,7 +110,8 @@ final class PrintSessionViewModel: ObservableObject {
|
|||||||
isPrinting = true
|
isPrinting = true
|
||||||
let task = Task { @MainActor [weak self] in
|
let task = Task { @MainActor [weak self] in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
defer { self.printTask = nil }
|
// `defer` cannot mutate isolated state under Swift 5.7
|
||||||
|
// (Xcode 14.2 / macOS 12 runner), so clear explicitly (#113).
|
||||||
var printed = 0
|
var printed = 0
|
||||||
for page in result.pages {
|
for page in result.pages {
|
||||||
do {
|
do {
|
||||||
@@ -123,6 +124,7 @@ final class PrintSessionViewModel: ObservableObject {
|
|||||||
+ error.localizedDescription
|
+ error.localizedDescription
|
||||||
)
|
)
|
||||||
isPrinting = false
|
isPrinting = false
|
||||||
|
self.printTask = nil
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,6 +134,7 @@ final class PrintSessionViewModel: ObservableObject {
|
|||||||
autoHideAfter: nil
|
autoHideAfter: nil
|
||||||
)
|
)
|
||||||
isPrinting = false
|
isPrinting = false
|
||||||
|
self.printTask = nil
|
||||||
}
|
}
|
||||||
printTask = task
|
printTask = task
|
||||||
}
|
}
|
||||||
@@ -141,7 +144,6 @@ final class PrintSessionViewModel: ObservableObject {
|
|||||||
isPrinting = true
|
isPrinting = true
|
||||||
let task = Task { @MainActor [weak self] in
|
let task = Task { @MainActor [weak self] in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
defer { self.printTask = nil }
|
|
||||||
do {
|
do {
|
||||||
try await spool(page, index: page.index, pageSize: pageSize)
|
try await spool(page, index: page.index, pageSize: pageSize)
|
||||||
printNotice = Notice(
|
printNotice = Notice(
|
||||||
@@ -156,6 +158,7 @@ final class PrintSessionViewModel: ObservableObject {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
isPrinting = false
|
isPrinting = false
|
||||||
|
self.printTask = nil
|
||||||
}
|
}
|
||||||
printTask = task
|
printTask = task
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,16 +138,20 @@ struct Stage4View: View {
|
|||||||
.textFieldStyle(.roundedBorder)
|
.textFieldStyle(.roundedBorder)
|
||||||
.accessibilityIdentifier("colprofCopyright")
|
.accessibilityIdentifier("colprofCopyright")
|
||||||
|
|
||||||
Toggle("Apply calibration curve", isOn: $model.applyCalibration)
|
// Nested VStack keeps the parent at the Swift 5.7 ViewBuilder
|
||||||
.accessibilityIdentifier("colprofApplyCalibration")
|
// 10-child limit (Xcode 14.2 / macOS 12 CI runner, #111).
|
||||||
|
VStack(alignment: .leading, spacing: 12) {
|
||||||
|
Toggle("Apply calibration curve", isOn: $model.applyCalibration)
|
||||||
|
.accessibilityIdentifier("colprofApplyCalibration")
|
||||||
|
|
||||||
if model.applyCalibration {
|
if model.applyCalibration {
|
||||||
HStack {
|
HStack {
|
||||||
TextField("Calibration .cal file", text: $model.calibrationFile)
|
TextField("Calibration .cal file", text: $model.calibrationFile)
|
||||||
.textFieldStyle(.roundedBorder)
|
.textFieldStyle(.roundedBorder)
|
||||||
.accessibilityIdentifier("colprofCalibrationFile")
|
.accessibilityIdentifier("colprofCalibrationFile")
|
||||||
Button("Browse…") { model.browseForCalibrationFile() }
|
Button("Browse…") { model.browseForCalibrationFile() }
|
||||||
.accessibilityIdentifier("btnBrowseCalibrationFile")
|
.accessibilityIdentifier("btnBrowseCalibrationFile")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,14 @@ final class Milestone6CalibrationUITests: XCTestCase {
|
|||||||
// After generation the wizard should advance to Stage 2 (layout) because
|
// After generation the wizard should advance to Stage 2 (layout) because
|
||||||
// a CAL_ .ti1 now exists and the session is in calibration mode.
|
// a CAL_ .ti1 now exists and the session is in calibration mode.
|
||||||
let layout = app.buttons["btnCreateLayout"]
|
let layout = app.buttons["btnCreateLayout"]
|
||||||
XCTAssertTrue(layout.waitForExistence(timeout: 25))
|
if !layout.waitForExistence(timeout: 25) {
|
||||||
|
// The generate tap can be dropped while the dashboard is still
|
||||||
|
// settling after the stage transition; retry once before failing.
|
||||||
|
if calGenerate.waitForExistence(timeout: 2) {
|
||||||
|
calGenerate.tap()
|
||||||
|
}
|
||||||
|
XCTAssertTrue(layout.waitForExistence(timeout: 25))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A failing calibration targen surfaces the error through the
|
/// A failing calibration targen surfaces the error through the
|
||||||
|
|||||||
Executable
+40
@@ -0,0 +1,40 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# scripts/ensure-host-tools.sh
|
||||||
|
#
|
||||||
|
# Bootstrap host tools needed by CI on the macOS 12 runner:
|
||||||
|
# - xcodegen: pinned prebuilt release from GitHub (Homebrew's current
|
||||||
|
# formula requires Xcode 15.3, which cannot be installed on macOS 12).
|
||||||
|
# - dmgbuild: via pip3 (used by scripts/package-release.sh).
|
||||||
|
#
|
||||||
|
# Safe to run repeatedly: existing tools are left alone.
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
XCODEGEN_VERSION="2.38.0"
|
||||||
|
INSTALL_ROOT="${XCODEGEN_HOME:-$HOME/.local/xcodegen/$XCODEGEN_VERSION}"
|
||||||
|
|
||||||
|
echo "==> Ensuring dmgbuild"
|
||||||
|
python3 -c "import dmgbuild" 2>/dev/null || pip3 install dmgbuild
|
||||||
|
|
||||||
|
if command -v xcodegen >/dev/null 2>&1; then
|
||||||
|
echo "==> xcodegen already on PATH: $(xcodegen --version)"
|
||||||
|
else
|
||||||
|
echo "==> Installing xcodegen $XCODEGEN_VERSION (prebuilt)"
|
||||||
|
TMP="${RUNNER_TEMP:-${TMPDIR:-/tmp}}"
|
||||||
|
ZIP="$TMP/xcodegen-$XCODEGEN_VERSION.zip"
|
||||||
|
curl -fL --retry 3 \
|
||||||
|
"https://github.com/yonaskolb/XcodeGen/releases/download/$XCODEGEN_VERSION/xcodegen.zip" \
|
||||||
|
-o "$ZIP"
|
||||||
|
rm -rf "$INSTALL_ROOT"
|
||||||
|
mkdir -p "$INSTALL_ROOT"
|
||||||
|
# Zip contains xcodegen/{bin/xcodegen,share/xcodegen/SettingPresets};
|
||||||
|
# XcodeGen resolves its presets relative to the binary, so keep the tree.
|
||||||
|
unzip -q "$ZIP" -d "$INSTALL_ROOT"
|
||||||
|
BIN_DIR="$INSTALL_ROOT/xcodegen/bin"
|
||||||
|
chmod +x "$BIN_DIR/xcodegen"
|
||||||
|
if [ -n "${GITHUB_PATH:-}" ]; then
|
||||||
|
echo "$BIN_DIR" >> "$GITHUB_PATH"
|
||||||
|
fi
|
||||||
|
PATH="$BIN_DIR:$PATH"
|
||||||
|
echo "==> Installed: $("$BIN_DIR/xcodegen" --version)"
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user