Compare commits

...
Author SHA1 Message Date
gronodandDevin <158243242+devin-ai-integration[bot]@users.noreply.github.com> b2b85ae835 chore(m9): retarget project spec, CI, and core syntax to macOS 12 / Swift 5.7
Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-11 20:02:57 +01:00
gronod 09f433106d Merge pull request 'Milestone 8 — UAT-ready hardening and consolidation (#79–#86)' (#104) from milestone/m8-consolidation into develop
macOS CI / build-and-test (push) Successful in 13m1s
macOS CI / package (push) Successful in 4m25s
2026-09-11 17:10:23 +01:00
gronodandDevin <158243242+devin-ai-integration[bot]@users.noreply.github.com> 891a504ee7 test(ui): activate app after launch in calibration UI tests
macOS CI / build-and-test (pull_request) Successful in 11m22s
macOS CI / package (pull_request) Skipped
testCalibrationDashboardOpensAndCanGenerate failed in every full-suite
gate run while passing standalone: without an explicit activate() the
synthesized btnCalGenerate click was consumed by window activation when
focus sat on another app after the prior test app terminated. Matches
the launchApp() convention used by the other UI suites.

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

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-11 15:15:16 +01:00
gronod f681e60778 Merge pull request 'refactor(ui): complete logged-run and Notice consolidation (#80)' (#103) from feat/80-process-run-notice-consolidation into milestone/m8-consolidation 2026-09-11 13:53:44 +01:00
9 changed files with 34 additions and 24 deletions
+10 -2
View File
@@ -14,13 +14,21 @@ jobs:
build-and-test:
# Prefer a self-hosted Mac runner if your Gitea has one. If not,
# macos-14 works for this pipeline.
runs-on: macos-14
runs-on: macos-12
env:
DERIVED: build/DerivedData-test
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Assert Xcode 14 toolchain
run: xcodebuild -version | grep -E "Xcode 14." || (echo "Unexpected Xcode version" && exit 1)
- name: Ensure host tools
run: |
command -v xcodegen || brew install xcodegen
python3 -c "import dmgbuild" 2>/dev/null || pip3 install dmgbuild
- name: Generate Xcode project
run: xcodegen generate --spec project.yml
@@ -120,7 +128,7 @@ jobs:
package:
needs: build-and-test
runs-on: macos-14
runs-on: macos-12
if: github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/tags/v')
steps:
- name: Checkout
+2 -2
View File
@@ -1,9 +1,9 @@
// swift-tools-version: 6.0
// swift-tools-version: 5.7
import PackageDescription
let package = Package(
name: "ICCeryCore",
platforms: [.macOS(.v14)],
platforms: [.macOS(.v12)],
products: [
.library(name: "ICCeryCore", targets: ["ICCeryCore"]),
],
@@ -200,7 +200,7 @@ public struct ArgyllRunner: Sendable {
await processManager.kill(id: id)
var attempts = 0
while await processManager.isRunning(id), attempts < 30 {
try? await Task.sleep(for: .milliseconds(100))
try? await Task.sleep(nanoseconds: 100_000_000)
attempts += 1
}
}
@@ -243,7 +243,7 @@ public struct ArgyllRunner: Sendable {
if flushPartialLines {
dotFlushTask = Task { [processManager] in
while !Task.isCancelled {
try? await Task.sleep(for: .milliseconds(500))
try? await Task.sleep(nanoseconds: 500_000_000)
if Task.isCancelled { break }
await processManager.flushPartialLine(id: processId)
}
@@ -592,7 +592,7 @@ public struct ArgyllRunner: Sendable {
await processManager.setPreKillHook(id: processId) { [processManager] in
if isXY {
try? await processManager.sendStdin(id: processId, bytes: ChartreadInput.quit.bytes)
try? await Task.sleep(for: .milliseconds(500))
try? await Task.sleep(nanoseconds: 500_000_000)
}
}
@@ -72,7 +72,7 @@ public enum CGATSParser {
public static func parse(
_ contents: String,
sourceURL: URL? = nil
) throws(CGATSParseError) -> CGATSDataset {
) throws -> CGATSDataset {
guard !contents.isEmpty else { throw .emptyFile }
let ext = sourceURL?.pathExtension.lowercased() ?? ""
@@ -213,7 +213,7 @@ public enum CGATSParser {
private static func preprocess(
_ contents: String,
isCSV: Bool
) throws(CGATSParseError) -> (CGATSFormat, [String]) {
) throws -> (CGATSFormat, [String]) {
let allLines = contents.components(separatedBy: .newlines)
var lines = [String]()
@@ -559,7 +559,7 @@ public actor ProcessManager {
// Start a watchdog in case the `readabilityHandler` EOFs never
// arrive after the process exits (e.g. a hung pipe).
child.finalizeTask = Task { [weak self] in
try? await Task.sleep(for: .seconds(2))
try? await Task.sleep(nanoseconds: 2_000_000_000)
guard let self else { return }
await self.forceKill(id: id)
await self.forceFinalize(id: id)
+1 -1
View File
@@ -33,7 +33,7 @@ final class SettingsViewModel {
sink.applySettings(settings)
savedFlash = true
Task {
try? await Task.sleep(for: .seconds(1.5))
try? await Task.sleep(nanoseconds: 1_500_000_000)
savedFlash = false
}
return true
+1 -1
View File
@@ -201,7 +201,7 @@ final class WizardViewModel {
self.notice = notice
if let delay = notice.autoHideAfter {
noticeDismissTask = Task { [weak self] in
try? await Task.sleep(for: .seconds(delay))
try? await Task.sleep(nanoseconds: UInt64(delay * 1_000_000_000))
guard !Task.isCancelled else { return }
if self?.notice?.id == notice.id {
self?.notice = nil
@@ -32,6 +32,7 @@ final class Milestone6CalibrationUITests: XCTestCase {
"ICCERY_TEST_WORKDIR": testWorkDir.path
]
app.launch()
app.activate()
}
override func tearDown() async throws {
@@ -104,6 +105,7 @@ final class Milestone6CalibrationUITests: XCTestCase {
app.launchEnvironment["ICCERY_TEST_ROOT"] = testRoot.path
app.launchEnvironment["ICCERY_MOCK_TARGEN_EXIT"] = "2"
app.launch()
app.activate()
let calButton = app.buttons["btnCalibratePrinter"]
XCTAssertTrue(calButton.waitForExistence(timeout: 10))
+12 -12
View File
@@ -2,7 +2,7 @@ name: ICCery
options:
bundleIdPrefix: com.gronod
deploymentTarget:
macOS: "14.0"
macOS: "12.0"
groupSortPosition: top
packages:
@@ -13,7 +13,7 @@ targets:
ICCery:
type: application
platform: macOS
deploymentTarget: "14.0"
deploymentTarget: "12.0"
sources:
- path: Sources/ICCery
- path: Resources
@@ -46,7 +46,7 @@ targets:
PRODUCT_BUNDLE_PACKAGE_TYPE: APPL
GENERATE_INFOPLIST_FILE: YES
INFOPLIST_KEY_CFBundleDisplayName: ICCery
INFOPLIST_KEY_LSMinimumSystemVersion: "14.0"
INFOPLIST_KEY_LSMinimumSystemVersion: "12.0"
INFOPLIST_KEY_NSPrincipalClass: NSApplication
INFOPLIST_KEY_NSHumanReadableCopyright: "Copyright © 2026 Gronod. AGPLv3."
MARKETING_VERSION: "2.0.0"
@@ -58,15 +58,15 @@ targets:
ENABLE_APP_SANDBOX: NO
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME: AccentColor
SWIFT_VERSION: "6.0"
SWIFT_STRICT_CONCURRENCY: complete
MACOSX_DEPLOYMENT_TARGET: "14.0"
SWIFT_VERSION: "5.0"
OTHER_SWIFT_FLAGS: ["$(inherited)", "-strict-concurrency=minimal"]
MACOSX_DEPLOYMENT_TARGET: "12.0"
ARCHS: "$(ARCHS_STANDARD)"
ICCeryCoreTests:
type: bundle.unit-test
platform: macOS
deploymentTarget: "14.0"
deploymentTarget: "12.0"
sources:
- path: Tests/ICCeryCoreTests
dependencies:
@@ -79,13 +79,13 @@ targets:
TEST_HOST: "$(BUILT_PRODUCTS_DIR)/ICCery.app/Contents/MacOS/ICCery"
GENERATE_INFOPLIST_FILE: YES
CODE_SIGN_IDENTITY: "-"
SWIFT_VERSION: "6.0"
MACOSX_DEPLOYMENT_TARGET: "14.0"
SWIFT_VERSION: "5.0"
MACOSX_DEPLOYMENT_TARGET: "12.0"
ICCeryUITests:
type: bundle.ui-testing
platform: macOS
deploymentTarget: "14.0"
deploymentTarget: "12.0"
sources:
- path: Tests/ICCeryUITests
dependencies:
@@ -95,8 +95,8 @@ targets:
TEST_TARGET_NAME: ICCery
GENERATE_INFOPLIST_FILE: YES
CODE_SIGN_IDENTITY: "-"
SWIFT_VERSION: "6.0"
MACOSX_DEPLOYMENT_TARGET: "14.0"
SWIFT_VERSION: "5.0"
MACOSX_DEPLOYMENT_TARGET: "12.0"
schemes:
ICCery: