From 7371f83e300d5459216901bea2b5e163acffd4c5 Mon Sep 17 00:00:00 2001 From: Nindi Gill Date: Sun, 21 Sep 2025 20:04:18 +1000 Subject: [PATCH 1/8] Add support for macOS Tahoe 26 --- .../Download/DownloadFirmwareOptions.swift | 1 + .../Download/DownloadInstallerOptions.swift | 1 + Mist/Commands/List/ListFirmwareOptions.swift | 1 + Mist/Commands/List/ListInstallerOptions.swift | 1 + Mist/Extensions/Sequence+Extension.swift | 2 ++ Mist/Model/Catalog.swift | 26 +++++++++++-------- Mist/Model/Firmware.swift | 4 ++- Mist/Model/Installer.swift | 2 +- 8 files changed, 25 insertions(+), 13 deletions(-) diff --git a/Mist/Commands/Download/DownloadFirmwareOptions.swift b/Mist/Commands/Download/DownloadFirmwareOptions.swift index d57b640..5c6ae38 100644 --- a/Mist/Commands/Download/DownloadFirmwareOptions.swift +++ b/Mist/Commands/Download/DownloadFirmwareOptions.swift @@ -13,6 +13,7 @@ struct DownloadFirmwareOptions: ParsableArguments { Name │ Version │ Build ───────────────┼─────────┼────── + macOS Tahoe | 26.x │ 25xyz macOS Sequoia | 15.x │ 24xyz macOS Sonoma │ 14.x │ 23xyz macOS Ventura │ 13.x │ 22xyz diff --git a/Mist/Commands/Download/DownloadInstallerOptions.swift b/Mist/Commands/Download/DownloadInstallerOptions.swift index a4e9273..78480a5 100644 --- a/Mist/Commands/Download/DownloadInstallerOptions.swift +++ b/Mist/Commands/Download/DownloadInstallerOptions.swift @@ -13,6 +13,7 @@ struct DownloadInstallerOptions: ParsableArguments { Name │ Version │ Build ───────────────────┼─────────┼────── + macOS Tahoe │ 26.x │ 25xyz macOS Sequoia │ 15.x │ 24xyz macOS Sonoma │ 14.x │ 23xyz macOS Ventura │ 13.x │ 22xyz diff --git a/Mist/Commands/List/ListFirmwareOptions.swift b/Mist/Commands/List/ListFirmwareOptions.swift index 02e21e0..e01ce48 100644 --- a/Mist/Commands/List/ListFirmwareOptions.swift +++ b/Mist/Commands/List/ListFirmwareOptions.swift @@ -13,6 +13,7 @@ struct ListFirmwareOptions: ParsableArguments { Name │ Version │ Build ───────────────┼─────────┼────── + macOS Tahoe │ 26.x │ 25xyz macOS Sequoia │ 15.x │ 24xyz macOS Sonoma │ 14.x │ 23xyz macOS Ventura │ 13.x │ 22xyz diff --git a/Mist/Commands/List/ListInstallerOptions.swift b/Mist/Commands/List/ListInstallerOptions.swift index 453742d..4d6ae5b 100644 --- a/Mist/Commands/List/ListInstallerOptions.swift +++ b/Mist/Commands/List/ListInstallerOptions.swift @@ -13,6 +13,7 @@ struct ListInstallerOptions: ParsableArguments { Name │ Version │ Build ───────────────────┼─────────┼────── + macOS Tahoe │ 26.x │ 25xyz macOS Sequoia │ 15.x │ 24xyz macOS Sonoma │ 14.x │ 23xyz macOS Ventura │ 13.x │ 22xyz diff --git a/Mist/Extensions/Sequence+Extension.swift b/Mist/Extensions/Sequence+Extension.swift index f6e0b4e..ba1352c 100644 --- a/Mist/Extensions/Sequence+Extension.swift +++ b/Mist/Extensions/Sequence+Extension.swift @@ -10,6 +10,7 @@ import Yams extension Sequence where Iterator.Element == [String: Any] { // swiftlint:disable function_body_length + /// Returns an ASCII-formatted table string for the provided array of `Firmware` dictionaries. /// /// - Parameters: @@ -90,6 +91,7 @@ extension Sequence where Iterator.Element == [String: Any] { // swiftlint:enable function_body_length // swiftlint:disable function_body_length + /// Returns an ASCII-formatted table string for the provided array of `Installer` dictionaries. /// /// - Parameters: diff --git a/Mist/Model/Catalog.swift b/Mist/Model/Catalog.swift index b2c694c..07fed08 100644 --- a/Mist/Model/Catalog.swift +++ b/Mist/Model/Catalog.swift @@ -12,20 +12,11 @@ enum Catalog: String, CaseIterable { case `public` static var urls: [String] { - allCases.map(\.url) + allCases.map(\.sequoiaURL) + allCases.map(\.sequoiaURL) + allCases.map(\.tahoeURL) } var url: String { - switch self { - case .standard: - "https://swscan.apple.com/content/catalogs/others/index-14-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz" - case .customer: - "https://swscan.apple.com/content/catalogs/others/index-14customerseed-14-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz" - case .developer: - "https://swscan.apple.com/content/catalogs/others/index-14seed-14-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz" - case .public: - "https://swscan.apple.com/content/catalogs/others/index-14beta-14-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz" - } + sequoiaURL } private var sequoiaURL: String { @@ -40,4 +31,17 @@ enum Catalog: String, CaseIterable { "https://swscan.apple.com/content/catalogs/others/index-15beta-15-14-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz" } } + + private var tahoeURL: String { + switch self { + case .standard: + "https://swscan.apple.com/content/catalogs/others/index-26-15-14-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz" + case .customer: // swiftlint:disable:next line_length + "https://swscan.apple.com/content/catalogs/others/index-26customerseed-26-15-14-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz" + case .developer: + "https://swscan.apple.com/content/catalogs/others/index-26seed-26-15-14-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz" + case .public: + "https://swscan.apple.com/content/catalogs/others/index-26beta-26-15-14-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz" + } + } } diff --git a/Mist/Model/Firmware.swift b/Mist/Model/Firmware.swift index dd85053..c8cd0f1 100644 --- a/Mist/Model/Firmware.swift +++ b/Mist/Model/Firmware.swift @@ -29,7 +29,9 @@ struct Firmware: Decodable { var name: String { var name: String = "" - if version.range(of: "^15", options: .regularExpression) != nil { + if version.range(of: "^26", options: .regularExpression) != nil { + name = "macOS Tahoe" + } else if version.range(of: "^15", options: .regularExpression) != nil { name = "macOS Sequoia" } else if version.range(of: "^14", options: .regularExpression) != nil { name = "macOS Sonoma" diff --git a/Mist/Model/Installer.swift b/Mist/Model/Installer.swift index fcaf983..5bba0bd 100644 --- a/Mist/Model/Installer.swift +++ b/Mist/Model/Installer.swift @@ -615,7 +615,7 @@ struct Installer: Decodable { } var bigSurOrNewer: Bool { - version.range(of: "^1[1-9]\\.", options: .regularExpression) != nil + version.range(of: "^(1[1-5]|26)\\.", options: .regularExpression) != nil } var beta: Bool { From eb9fcc369ed19f32ddc717d43daf4feb25341c18 Mon Sep 17 00:00:00 2001 From: Nindi Gill Date: Sun, 21 Sep 2025 20:05:22 +1000 Subject: [PATCH 2/8] Use InstallAssistant.pkg instead of distribution if available --- Mist/Helpers/InstallerCreator.swift | 22 ++++++++++++++++------ Mist/Model/Installer.swift | 4 ++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/Mist/Helpers/InstallerCreator.swift b/Mist/Helpers/InstallerCreator.swift index 55c8525..0ed2225 100644 --- a/Mist/Helpers/InstallerCreator.swift +++ b/Mist/Helpers/InstallerCreator.swift @@ -9,6 +9,8 @@ import Foundation /// Helper Struct used to install macOS Installers. enum InstallerCreator { + // swiftlint:disable function_body_length + /// Creates a recently downloaded macOS Installer. /// /// - Parameters: @@ -55,14 +57,20 @@ enum InstallerCreator { let arguments: [String] = ["hdiutil", "detach", legacyDiskImageMountPointURL.path, "-force"] _ = try Shell.execute(arguments) } else { - guard let url: URL = URL(string: installer.distribution) else { - throw MistError.invalidURL(installer.distribution) - } + !options.quiet ? PrettyPrint.print("Creating new installer '\(installer.temporaryInstallerURL.path)'...", noAnsi: options.noAnsi) : Mist.noop() - let distributionURL: URL = temporaryURL.appendingPathComponent(url.lastPathComponent) + if installer.containsInstallAssistantPackage { + let installAssistantPackageURL: URL = temporaryURL.appendingPathComponent("InstallAssistant.pkg") + arguments = ["installer", "-pkg", installAssistantPackageURL.path, "-target", installer.temporaryDiskImageMountPointURL.path] + } else { + guard let url: URL = URL(string: installer.distribution) else { + throw MistError.invalidURL(installer.distribution) + } + + let distributionURL: URL = temporaryURL.appendingPathComponent(url.lastPathComponent) + arguments = ["installer", "-pkg", distributionURL.path, "-target", installer.temporaryDiskImageMountPointURL.path] + } - !options.quiet ? PrettyPrint.print("Creating new installer '\(installer.temporaryInstallerURL.path)'...", noAnsi: options.noAnsi) : Mist.noop() - arguments = ["installer", "-pkg", distributionURL.path, "-target", installer.temporaryDiskImageMountPointURL.path] let variables: [String: String] = ["CM_BUILD": "CM_BUILD"] _ = try Shell.execute(arguments, environment: variables) } @@ -80,4 +88,6 @@ enum InstallerCreator { !options.quiet ? PrettyPrint.print("Created new installer '\(installer.temporaryInstallerURL.path)'", noAnsi: options.noAnsi) : Mist.noop() } + + // swiftlint:enable function_body_length } diff --git a/Mist/Model/Installer.swift b/Mist/Model/Installer.swift index 5bba0bd..41afe2c 100644 --- a/Mist/Model/Installer.swift +++ b/Mist/Model/Installer.swift @@ -561,6 +561,10 @@ struct Installer: Decodable { (sierraOrOlder ? [] : [Package(url: distribution, size: 0, integrityDataURL: nil, integrityDataSize: nil)]) + packages.sorted { $0.filename < $1.filename } } + var containsInstallAssistantPackage: Bool { + packages.contains { $0.filename == "InstallAssistant.pkg" } + } + var temporaryDiskImageMountPointURL: URL { URL(fileURLWithPath: "/Volumes/\(identifier)") } From 9163b928daaae156e2b58bf5660775ab22ee1934 Mon Sep 17 00:00:00 2001 From: Nindi Gill Date: Sun, 21 Sep 2025 20:16:50 +1000 Subject: [PATCH 3/8] Bump GitHub actions configs --- .github/workflows/build.yml | 4 ++-- .github/workflows/draft_new_release.yml | 4 ++-- .github/workflows/linting.yml | 4 ++-- .github/workflows/unit_tests.yml | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 21541b6..f100b57 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,9 +10,9 @@ on: jobs: build: name: Build - runs-on: macos-14 + runs-on: macos-15 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: swift-actions/setup-swift@v2 - name: Install Apple Developer ID Application Certificate env: diff --git a/.github/workflows/draft_new_release.yml b/.github/workflows/draft_new_release.yml index bc632c6..404f425 100644 --- a/.github/workflows/draft_new_release.yml +++ b/.github/workflows/draft_new_release.yml @@ -3,7 +3,7 @@ on: workflow_dispatch jobs: build: name: Draft New Release - runs-on: macos-14 + runs-on: macos-15 env: APPLE_DEVELOPER_ID_APPLICATION_CERTIFICATE: ${{ secrets.APPLE_DEVELOPER_ID_APPLICATION_CERTIFICATE }} APPLE_DEVELOPER_ID_APPLICATION_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_DEVELOPER_ID_APPLICATION_CERTIFICATE_PASSWORD }} @@ -18,7 +18,7 @@ jobs: APPLE_DEVELOPER_TEAM_ID: "7K3HVCLV7Z" KEYCHAIN_FILE: "apple-developer.keychain-db" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: swift-actions/setup-swift@v2 - name: Install Apple Developer ID Certificates run: | diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 5087340..73cefa4 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -10,9 +10,9 @@ on: jobs: linting: name: Linting - runs-on: macos-14 + runs-on: macos-15 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: swift-actions/setup-swift@v2 - uses: sinoru/actions-swiftlint@v6 - name: Print SwiftLint version diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 187569d..f110851 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -10,9 +10,9 @@ on: jobs: unit_tests: name: Unit Tests - runs-on: macos-14 + runs-on: macos-15 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: swift-actions/setup-swift@v2 - name: Run Unit Tests run: swift test From c3e51c9fb9e98a49c4ee481429a2a133cddfd7d6 Mon Sep 17 00:00:00 2001 From: Nindi Gill Date: Sun, 21 Sep 2025 20:24:24 +1000 Subject: [PATCH 4/8] Keychain fix for macOS Sequoia GitHub runner --- .github/workflows/build.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f100b57..7ef620e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,7 +30,9 @@ jobs: security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" security unlock-keychain -p "$APPLE_DEVELOPER_KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" security import "$APPLE_DEVELOPER_ID_APPLICATION_CERTIFICATE_PATH" -P "$APPLE_DEVELOPER_ID_APPLICATION_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH" - security import "$APPLE_DEVELOPER_CERTIFICATE_AUTHORITY_PATH" -P "$APPLE_DEVELOPER_CERTIFICATE_PASSWORD" -A -t cert -f pkcs7 -k "$KEYCHAIN_PATH" + if ! security find-certificate -c "Developer ID Certification Authority" "$KEYCHAIN_PATH" ; then + security import "$APPLE_DEVELOPER_CERTIFICATE_AUTHORITY_PATH" -P "$APPLE_DEVELOPER_CERTIFICATE_PASSWORD" -A -t cert -f pkcs7 -k "$KEYCHAIN_PATH" + fi security list-keychain -d user -s "$KEYCHAIN_PATH" - name: Build mist run: swift build --configuration release --arch arm64 --arch x86_64 From 2d7b6063862c2191c99acea123d95781b850ebb5 Mon Sep 17 00:00:00 2001 From: Nindi Gill Date: Sun, 21 Sep 2025 20:26:19 +1000 Subject: [PATCH 5/8] Keychain fix for macOS Sequoia GitHub runner --- .github/workflows/draft_new_release.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/draft_new_release.yml b/.github/workflows/draft_new_release.yml index 404f425..716f4ac 100644 --- a/.github/workflows/draft_new_release.yml +++ b/.github/workflows/draft_new_release.yml @@ -33,7 +33,9 @@ jobs: security unlock-keychain -p "$APPLE_DEVELOPER_KEYCHAIN_PASSWORD" "$RUNNER_TEMP/$KEYCHAIN_FILE" security import "$APPLE_DEVELOPER_ID_APPLICATION_CERTIFICATE_PATH" -P "$APPLE_DEVELOPER_ID_APPLICATION_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k "$RUNNER_TEMP/$KEYCHAIN_FILE" security import "$APPLE_DEVELOPER_ID_INSTALLER_CERTIFICATE_PATH" -P "$APPLE_DEVELOPER_ID_INSTALLER_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k "$RUNNER_TEMP/$KEYCHAIN_FILE" - security import "$APPLE_DEVELOPER_CERTIFICATE_AUTHORITY_PATH" -P "$APPLE_DEVELOPER_CERTIFICATE_PASSWORD" -A -t cert -f pkcs7 -k "$RUNNER_TEMP/$KEYCHAIN_FILE" + if ! security find-certificate -c "Developer ID Certification Authority" "$RUNNER_TEMP/$KEYCHAIN_FILE" ; then + security import "$APPLE_DEVELOPER_CERTIFICATE_AUTHORITY_PATH" -P "$APPLE_DEVELOPER_CERTIFICATE_PASSWORD" -A -t cert -f pkcs7 -k "$RUNNER_TEMP/$KEYCHAIN_FILE" + fi security list-keychain -d user -s "$RUNNER_TEMP/$KEYCHAIN_FILE" - name: Build mist run: swift build --configuration release --arch arm64 --arch x86_64 From 669bb9395c751c22adccf3a00cbef4e0e62ed48d Mon Sep 17 00:00:00 2001 From: Nindi Gill Date: Sun, 21 Sep 2025 20:33:42 +1000 Subject: [PATCH 6/8] Try m-takuma/setup-swiftlint@1 --- .github/workflows/linting.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 73cefa4..73c6da7 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/checkout@v5 - uses: swift-actions/setup-swift@v2 - - uses: sinoru/actions-swiftlint@v6 + - uses: m-takuma/setup-swiftlint@1 - name: Print SwiftLint version run: swiftlint --version - name: Run SwiftLint From ef25ab8fc8d6d6422ccb2ddc128fd0e577731b1c Mon Sep 17 00:00:00 2001 From: Nindi Gill Date: Sun, 21 Sep 2025 20:35:10 +1000 Subject: [PATCH 7/8] Update linting.yml --- .github/workflows/linting.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 73c6da7..b2ff093 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/checkout@v5 - uses: swift-actions/setup-swift@v2 - - uses: m-takuma/setup-swiftlint@1 + - uses: m-takuma/setup-swiftlint - name: Print SwiftLint version run: swiftlint --version - name: Run SwiftLint From ef09db0dff3ae9a8862163ffcbfe4e942d2fa275 Mon Sep 17 00:00:00 2001 From: Nindi Gill Date: Sun, 21 Sep 2025 20:35:57 +1000 Subject: [PATCH 8/8] Update linting.yml --- .github/workflows/linting.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index b2ff093..4aff9b7 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/checkout@v5 - uses: swift-actions/setup-swift@v2 - - uses: m-takuma/setup-swiftlint + - uses: m-takuma/setup-swiftlint@1.0.0 - name: Print SwiftLint version run: swiftlint --version - name: Run SwiftLint