Compare commits

..
Author SHA1 Message Date
gronod a2e3f11e70 fix(m9): ad-hoc sign embedded ICCeryCore framework so test host launches (#119) 2026-09-12 09:29:40 +01:00
gronod c3c9bbc5ba Merge pull request 'fix(m9): link ICCeryCore statically so the app launches standalone (#117)' (#118) from feat/117-static-iccerycore into milestone/m9-monterey
macOS CI / build-and-test (push) Failing after 26s
macOS CI / package (push) Skipped
Reviewed-on: #118
2026-09-12 09:17:22 +01:00
gronodandDevin <158243242+devin-ai-integration[bot]@users.noreply.github.com> b5683aa36a fix(m9): link ICCeryCore statically so the app launches standalone (#117)
When the app and test bundles share the local ICCeryCore package, Xcode
builds it as a dynamic package-product framework that is not embedded
in ICCery.app — the app crashes in dyld at launch when run outside the
test host (macOS 12 VM crash, run 31985 products). Declare the product
.static so each consumer links it directly.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-12 09:14:54 +01:00
gronod 707455dcfb Merge pull request 'test(m9): replace MainActor.assertIsolated for Swift 5.7 (#115)' (#116) from feat/115-assertisolated-swift57 into milestone/m9-monterey
macOS CI / build-and-test (push) Failing after 2m53s
macOS CI / package (push) Skipped
Reviewed-on: #116
2026-09-12 09:07:06 +01:00
gronodandDevin <158243242+devin-ai-integration[bot]@users.noreply.github.com> 17ee5d6717 test(m9): replace MainActor.assertIsolated for Swift 5.7 (#115)
MainActor.assertIsolated() requires Swift 5.9 (Xcode 15); the macOS 12
CI runner compiles the test bundle with Swift 5.7 and failed run 31985.
Assert Thread.isMainThread instead — it checks the same contract (the
coalesced log sink hops back to the main actor).

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-12 09:06:45 +01:00
gronod 2295bcdbae Merge pull request 'fix(m9): clear printTask without defer for Swift 5.7 (#113)' (#114) from feat/113-printtask-defer-swift57 into milestone/m9-monterey
macOS CI / build-and-test (push) Failing after 1m59s
macOS CI / package (push) Skipped
Reviewed-on: #114
2026-09-12 09:01:37 +01:00
gronodandDevin <158243242+devin-ai-integration[bot]@users.noreply.github.com> c9bff50a1a fix(m9): clear printTask without defer for Swift 5.7 (#113)
Swift 5.7 on the macOS 12 CI runner (Xcode 14.2) rejects mutation of
actor-isolated properties inside defer bodies, failing run 31978 at
PrintSessionViewModel.swift:113 and :144. Clear printTask explicitly at
each exit point of the print task closures.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-12 09:00:48 +01:00
gronod 1b3d3dd821 Merge pull request 'fix(m9): keep Stage4View under Swift 5.7 ViewBuilder 10-child limit (#111)' (#112) from feat/111-stage4-viewbuilder-limit into milestone/m9-monterey
macOS CI / build-and-test (push) Failing after 1m28s
macOS CI / package (push) Skipped
Reviewed-on: #112
2026-09-12 08:55:57 +01:00
gronodandDevin <158243242+devin-ai-integration[bot]@users.noreply.github.com> 55dee0f0cd fix(m9): keep Stage4View under Swift 5.7 ViewBuilder 10-child limit (#111)
The formSection VStack had 11 direct children; Xcode 14.2's ViewBuilder
only provides buildBlock overloads up to 10 arguments, so the CI build
on the macOS 12 runner failed at line 144 with "extra argument in call"
(run 31958). Nest the calibration toggle and conditional file row in an
inner VStack with identical alignment and spacing.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-12 08:55:12 +01:00
gronod 45fd2b988f Merge pull request 'fix(m9): pin prebuilt xcodegen for macOS 12 CI (#109)' (#110) from feat/109-ci-xcodegen-pin into milestone/m9-monterey
macOS CI / build-and-test (push) Failing after 2m34s
macOS CI / package (push) Skipped
Reviewed-on: #110
2026-09-12 08:35:51 +01:00
5 changed files with 41 additions and 12 deletions
+13
View File
@@ -45,6 +45,19 @@ jobs:
CODE_SIGNING_ALLOWED=YES \ CODE_SIGNING_ALLOWED=YES \
CODE_SIGN_IDENTITY='-' CODE_SIGN_IDENTITY='-'
# Xcode embeds the shared ICCeryCore package framework into the app
# and the test bundle without signing it. Ad-hoc hosts still require
# every loaded dylib to carry a cdhash — dyld killed the test host at
# launch (run 31992) — so sign every embedded copy once the build is
# done (embed steps run after any build script phase) (#119).
- name: Sign package product frameworks
run: |
find "$DERIVED/Build/Products/Debug" -depth -name '*_PackageProduct.framework' -print0 \
| while IFS= read -r -d '' fw; do
echo "signing $fw"
codesign --force --sign - --timestamp=none "$fw"
done
- name: Test unit (ICCeryCoreTests) - name: Test unit (ICCeryCoreTests)
run: | run: |
XCTESTRUN="$(find "$DERIVED" -name 'ICCery*.xctestrun' | head -n 1)" XCTESTRUN="$(find "$DERIVED" -name 'ICCery*.xctestrun' | head -n 1)"
@@ -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
} }
+4
View File
@@ -138,6 +138,9 @@ struct Stage4View: View {
.textFieldStyle(.roundedBorder) .textFieldStyle(.roundedBorder)
.accessibilityIdentifier("colprofCopyright") .accessibilityIdentifier("colprofCopyright")
// Nested VStack keeps the parent at the Swift 5.7 ViewBuilder
// 10-child limit (Xcode 14.2 / macOS 12 CI runner, #111).
VStack(alignment: .leading, spacing: 12) {
Toggle("Apply calibration curve", isOn: $model.applyCalibration) Toggle("Apply calibration curve", isOn: $model.applyCalibration)
.accessibilityIdentifier("colprofApplyCalibration") .accessibilityIdentifier("colprofApplyCalibration")
@@ -151,6 +154,7 @@ struct Stage4View: View {
} }
} }
} }
}
.padding(16) .padding(16)
.background(Theme.panel) .background(Theme.panel)
} }
@@ -21,7 +21,9 @@ final class ProcessRunSupportTests: XCTestCase {
setRunning: { running.append($0) }, setRunning: { running.append($0) },
resetLog: { resets += 1 }, resetLog: { resets += 1 },
onLog: { batch in onLog: { batch in
MainActor.assertIsolated() // MainActor.assertIsolated() needs Swift 5.9; the runner is
// on Xcode 14.2 (Swift 5.7) (#115).
XCTAssertTrue(Thread.isMainThread)
received.append(contentsOf: batch) received.append(contentsOf: batch)
} }
) { onLog in ) { onLog in
+7
View File
@@ -62,6 +62,13 @@ targets:
OTHER_SWIFT_FLAGS: ["$(inherited)", "-strict-concurrency=minimal"] OTHER_SWIFT_FLAGS: ["$(inherited)", "-strict-concurrency=minimal"]
MACOSX_DEPLOYMENT_TARGET: "12.0" MACOSX_DEPLOYMENT_TARGET: "12.0"
ARCHS: "$(ARCHS_STANDARD)" ARCHS: "$(ARCHS_STANDARD)"
# Debug builds sign ad-hoc; hardened-runtime library validation would
# reject the unsigned embedded ICCeryCore package framework when the
# test host launches (run 31992, #119). Release keeps validation and
# links the package statically anyway.
configs:
Debug:
DISABLE_LIBRARY_VALIDATION: YES
ICCeryCoreTests: ICCeryCoreTests:
type: bundle.unit-test type: bundle.unit-test