From 2dae0113a23e86ff135fb65e87852db83f9649e0 Mon Sep 17 00:00:00 2001 From: Kazuki Nakashima <65545348+lynnswap@users.noreply.github.com> Date: Mon, 11 May 2026 15:02:42 +0900 Subject: [PATCH] chore: support macOS 15 and Swift 6.2 --- .github/workflows/ci.yml | 124 ++++++++++++++++++ Package.swift | 4 +- README.md | 4 +- .../MiniApp/MiniApp.xcodeproj/project.pbxproj | 4 +- 4 files changed, 130 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..b50165c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,124 @@ +name: CI + +on: + push: + branches: + - main + paths-ignore: + - README.md + - LICENSE + pull_request: + paths-ignore: + - README.md + - LICENSE + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + swift-62-tests: + name: Package Tests (macOS 15, Swift 6.2) + runs-on: macos-15 + timeout-minutes: 60 + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Resolve Swift 6.2 Xcode + run: | + xcode_app="$(ruby <<'RUBY' + candidates = Dir["/Applications/Xcode_26*.app"].select { |path| File.directory?(path) } + + def pre_release_xcode_path?(path) + labels = [path, File.realpath(path)].map { |candidate| File.basename(candidate).downcase } + labels.any? do |label| + label.match?(/beta|release[ _-]?candidate|(?:^|[_. -])rc(?:$|[_. -])/) + end + end + + def version_components(path) + version = File.basename(path)[/Xcode_(\d+(?:\.\d+)*)/, 1] + version.to_s.split(".").map(&:to_i) + end + + matches = candidates.reject { |path| pre_release_xcode_path?(path) }.select do |path| + swift = `DEVELOPER_DIR="#{path}/Contents/Developer" swift --version 2>/dev/null` + swift.include?("Apple Swift version 6.2") + end + + selected = matches.max_by { |path| version_components(path) } + abort("No stable Xcode with Apple Swift 6.2 found") unless selected + puts selected + RUBY + )" + echo "DEVELOPER_DIR=${xcode_app}/Contents/Developer" >> "$GITHUB_ENV" + echo "Resolved Xcode: ${xcode_app}" + + - name: Show Xcode environment + run: | + xcodebuild -version + swift --version + xcodebuild -showsdks + + - name: Verify Swift 6.2 + run: | + swift --version | grep -E 'Apple Swift version 6\.2' + + - name: Run Swift package tests + run: | + swift test + + latest-macos-tests: + name: Package Tests (macOS 26, Latest Xcode) + runs-on: macos-26 + timeout-minutes: 60 + env: + XCODE_MAJOR: '26' + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Resolve latest stable Xcode + run: | + xcode_app="$(ruby <<'RUBY' + xcode_major = ENV.fetch("XCODE_MAJOR") + candidates = Dir["/Applications/Xcode_#{xcode_major}*.app"].select { |path| File.directory?(path) } + + def pre_release_xcode_path?(path) + labels = [path, File.realpath(path)].map { |candidate| File.basename(candidate).downcase } + labels.any? do |label| + label.match?(/beta|release[ _-]?candidate|(?:^|[_. -])rc(?:$|[_. -])/) + end + end + + candidates = candidates.reject do |path| + pre_release_xcode_path?(path) + end + + def version_components(path) + version = File.basename(path)[/Xcode_(\d+(?:\.\d+)*)/, 1] + version.to_s.split(".").map(&:to_i) + end + + selected = candidates.max_by { |path| version_components(path) } + abort("No stable Xcode #{xcode_major} installation found") unless selected + puts selected + RUBY + )" + echo "DEVELOPER_DIR=${xcode_app}/Contents/Developer" >> "$GITHUB_ENV" + echo "Resolved Xcode: ${xcode_app}" + + - name: Show Xcode environment + run: | + xcodebuild -version + swift --version + xcodebuild -showsdks + + - name: Run Swift package tests + run: | + swift test diff --git a/Package.swift b/Package.swift index da44032..e2d3e9c 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version: 6.3 +// swift-tools-version: 6.2 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription @@ -11,7 +11,7 @@ let strictSwiftSettings: [SwiftSetting] = [ let package = Package( name: "NavigationStackController", - platforms: [.macOS(.v26)], + platforms: [.macOS(.v15)], products: [ // Products define the executables and libraries a package produces, making them visible to other packages. .library( diff --git a/README.md b/README.md index 25cc791..dd26313 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,8 @@ It provides a UIKit-style back/forward history model for macOS apps, including o ## Requirements -- macOS 26.0+ -- Swift 6.3+ +- macOS 15.0+ +- Swift 6.2+ - AppKit ## Usage diff --git a/Tools/MiniApp/MiniApp.xcodeproj/project.pbxproj b/Tools/MiniApp/MiniApp.xcodeproj/project.pbxproj index c12a7fa..861581d 100644 --- a/Tools/MiniApp/MiniApp.xcodeproj/project.pbxproj +++ b/Tools/MiniApp/MiniApp.xcodeproj/project.pbxproj @@ -281,7 +281,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 26.4; LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 26.4; + MACOSX_DEPLOYMENT_TARGET = 15.0; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = lynnpd.MiniApp; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -327,7 +327,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 26.4; LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 26.4; + MACOSX_DEPLOYMENT_TARGET = 15.0; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = lynnpd.MiniApp; PRODUCT_NAME = "$(TARGET_NAME)";