Skip to content

Commit 53e0dee

Browse files
authored
Update to Swift 6.2, Xcode 26, and expand platform support (#37)
1 parent c18df55 commit 53e0dee

File tree

4 files changed

+306
-32
lines changed

4 files changed

+306
-32
lines changed

.github/workflows/RadiantKit.yml

Lines changed: 96 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,26 @@ jobs:
1414
if: "!contains(github.event.head_commit.message, 'ci skip')"
1515
strategy:
1616
matrix:
17-
image-name: ["swift:6.0", "swift:6.1", "swiftlang/swift:nightly-6.2-noble"]
17+
include:
18+
- image-name: "swift:6.2"
19+
swift-label: "6.2"
20+
- image-name: "swiftlang/swift:nightly-6.3-noble"
21+
swift-label: "nightly-6.3"
1822

1923
container:
2024
image: ${{ matrix.image-name }}
2125
steps:
2226
- uses: actions/checkout@v4
23-
- uses: brightdigit/swift-build@v1.1.1
27+
- uses: brightdigit/swift-build@v1.4.2
2428
- uses: sersoft-gmbh/swift-coverage-action@v4
2529
id: coverage-files
2630
with:
2731
fail-on-empty-output: true
2832
- name: Upload coverage to Codecov
29-
uses: codecov/codecov-action@v4
33+
uses: codecov/codecov-action@v4
3034
with:
3135
fail_ci_if_error: true
32-
flags: swift-${{ matrix.image-name }},ubuntu
36+
flags: ${{ matrix.swift-label }},ubuntu
3337
verbose: true
3438
token: ${{ secrets.CODECOV_TOKEN }}
3539
files: ${{ join(fromJSON(steps.coverage-files.outputs.files), ',') }}
@@ -42,63 +46,80 @@ jobs:
4246
matrix:
4347
include:
4448
# SPM Build Matrix
45-
- runs-on: macos-15
46-
xcode: "/Applications/Xcode_16.1.app"
4749
- runs-on: macos-15
4850
xcode: "/Applications/Xcode_16.4.app"
51+
- runs-on: macos-26
52+
xcode: "/Applications/Xcode_26.2.app"
4953

54+
# macOS Build Matrix
5055
- type: macos
5156
runs-on: macos-15
5257
xcode: "/Applications/Xcode_16.4.app"
53-
58+
- type: macos
59+
runs-on: macos-26
60+
xcode: "/Applications/Xcode_26.2.app"
61+
5462
# iOS Build Matrix
5563
- type: ios
5664
runs-on: macos-15
5765
xcode: "/Applications/Xcode_16.1.app"
5866
deviceName: "iPhone 16"
5967
osVersion: "18.1"
68+
download-platform: true
6069
- type: ios
6170
runs-on: macos-15
6271
xcode: "/Applications/Xcode_16.4.app"
6372
deviceName: "iPhone 16 Pro"
64-
osVersion: "18.2"
65-
73+
osVersion: "18.6"
74+
- type: ios
75+
runs-on: macos-26
76+
xcode: "/Applications/Xcode_26.2.app"
77+
deviceName: "iPhone 17 Pro"
78+
osVersion: "26.2"
79+
6680
# watchOS Build Matrix
6781
- type: watchos
6882
runs-on: macos-15
6983
xcode: "/Applications/Xcode_16.1.app"
7084
deviceName: "Apple Watch Ultra 2 (49mm)"
71-
osVersion: "11.1"
85+
osVersion: "11.2"
86+
download-platform: true
7287
- type: watchos
7388
runs-on: macos-15
7489
xcode: "/Applications/Xcode_16.4.app"
7590
deviceName: "Apple Watch Ultra 2 (49mm)"
76-
osVersion: "11.2"
91+
osVersion: "11.5"
92+
- type: watchos
93+
runs-on: macos-26
94+
xcode: "/Applications/Xcode_26.2.app"
95+
deviceName: "Apple Watch Ultra 3 (49mm)"
96+
osVersion: "26.2"
7797

7898
# visionOS Build Matrix
7999
- type: visionos
80-
runs-on: macos-15
81-
xcode: "/Applications/Xcode_16.4.app"
100+
runs-on: macos-26
101+
xcode: "/Applications/Xcode_26.2.app"
82102
deviceName: "Apple Vision Pro"
83-
osVersion: "2.1"
84-
103+
osVersion: "26.2"
104+
85105
# tvOS Build Matrix
86106
- type: tvos
87-
runs-on: macos-15
88-
xcode: "/Applications/Xcode_16.4.app"
107+
runs-on: macos-26
108+
xcode: "/Applications/Xcode_26.2.app"
89109
deviceName: "Apple TV 4K (3rd generation)"
90-
osVersion: "18.2"
110+
osVersion: "26.2"
91111
steps:
92112
- uses: actions/checkout@v4
93113

94114
- name: Build and Test
95-
uses: brightdigit/swift-build@v1.1.1
115+
uses: brightdigit/swift-build@v1.4.2
96116
with:
97117
scheme: ${{ env.PACKAGE_NAME }}-Package
98118
type: ${{ matrix.type }}
99119
xcode: ${{ matrix.xcode }}
100120
deviceName: ${{ matrix.deviceName }}
101121
osVersion: ${{ matrix.osVersion }}
122+
download-platform: ${{ matrix.download-platform }}
102123

103124
# Common Coverage Steps
104125
- name: Process Coverage
@@ -115,11 +136,65 @@ jobs:
115136
with:
116137
token: ${{ secrets.CODECOV_TOKEN }}
117138
flags: ${{ matrix.type && format('{0}{1}', matrix.type, matrix.osVersion) || 'spm' }}
139+
140+
build-windows:
141+
name: Build on Windows
142+
runs-on: ${{ matrix.runs-on }}
143+
if: "!contains(github.event.head_commit.message, 'ci skip')"
144+
strategy:
145+
fail-fast: false
146+
matrix:
147+
runs-on: [windows-2022, windows-2025]
148+
swift:
149+
- version: swift-6.2-release
150+
build: 6.2-RELEASE
151+
steps:
152+
- uses: actions/checkout@v4
153+
- uses: brightdigit/swift-build@v1.4.2
154+
with:
155+
scheme: ${{ env.PACKAGE_NAME }}-Package
156+
windows-swift-version: ${{ matrix.swift.version }}
157+
windows-swift-build: ${{ matrix.swift.build }}
158+
159+
build-android:
160+
name: Build on Android
161+
runs-on: ubuntu-latest
162+
if: "!contains(github.event.head_commit.message, 'ci skip')"
163+
strategy:
164+
fail-fast: false
165+
matrix:
166+
include:
167+
- android-swift-version: "6.1"
168+
android-api-level: "28"
169+
- android-swift-version: "6.2"
170+
android-api-level: "33"
171+
- android-swift-version: "nightly-main"
172+
android-api-level: "34"
173+
steps:
174+
- uses: actions/checkout@v4
175+
176+
- name: Free disk space
177+
uses: jlumbroso/free-disk-space@main
178+
with:
179+
tool-cache: false
180+
android: false
181+
dotnet: true
182+
haskell: true
183+
large-packages: true
184+
docker-images: true
185+
swap-storage: true
186+
187+
- uses: brightdigit/swift-build@v1.4.2
188+
with:
189+
scheme: ${{ env.PACKAGE_NAME }}-Package
190+
android-swift-version: ${{ matrix.android-swift-version }}
191+
android-api-level: ${{ matrix.android-api-level }}
192+
118193
lint:
119194
name: Linting
120-
if: ${{ !contains(github.event.head_commit.message, 'ci skip') }}
195+
if: ${{ !contains(github.event.head_commit.message, 'ci skip') }}
121196
runs-on: ubuntu-latest
122-
needs: [build-ubuntu, build-macos]
197+
needs: [build-ubuntu, build-macos, build-windows, build-android]
123198
env:
124199
MINT_PATH: .mint/lib
125200
MINT_LINK_PATH: .mint/bin

CLAUDE.md

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
RadiantKit is a Swift Package Manager library providing SwiftUI utilities across Apple platforms (iOS 18+, macOS 15+, tvOS 18+, watchOS 11+, visionOS 2+). The package contains four distinct modules with clear separation of concerns.
8+
9+
## Common Commands
10+
11+
### Building and Testing
12+
```bash
13+
# Build the package (Swift 6.0+ required)
14+
swift build
15+
16+
# Run tests
17+
swift test
18+
19+
# Build for specific platform (requires Xcode)
20+
xcodebuild -scheme RadiantKit-Package -destination 'platform=iOS Simulator,name=iPhone 16'
21+
22+
# Run single test
23+
swift test --filter RadiantKitTests.<TestClassName>/<testMethodName>
24+
```
25+
26+
### Linting and Formatting
27+
```bash
28+
# Run full lint (formats code, adds headers, then validates)
29+
./Scripts/lint.sh
30+
31+
# Format only (skip validation)
32+
FORMAT_ONLY=1 ./Scripts/lint.sh
33+
34+
# Strict mode (treats warnings as errors)
35+
LINT_MODE=STRICT ./Scripts/lint.sh
36+
37+
# Skip linting entirely
38+
LINT_MODE=NONE ./Scripts/lint.sh
39+
```
40+
41+
The lint script uses Mint for dependency management and runs:
42+
- swift-format (formatting and linting)
43+
- swiftlint (Swift style validation)
44+
- header.sh (copyright header management)
45+
46+
### Documentation Generation
47+
```bash
48+
# Generate Swift-DocC documentation
49+
./Scripts/swift-doc.sh
50+
51+
# Watch mode for documentation development
52+
./Scripts/watch-docc.sh
53+
```
54+
55+
### Development Tools
56+
```bash
57+
# Install Mint dependencies
58+
mint bootstrap -m Mintfile
59+
60+
# Run periphery (dead code detection)
61+
mint run periphery scan
62+
```
63+
64+
## Architecture
65+
66+
### Module Structure
67+
68+
**RadiantKit** (Core Foundation)
69+
- Property wrappers: `@AppStored`, `@DefaultWrapped` for persistent storage patterns
70+
- View utilities: `IdentifiableView`, `IdentifiableViewBuilder` for collection-based navigation
71+
- `Binding.map()`: Type-safe binding transformations
72+
- Platform adapters: NSWindowDelegate wrappers for macOS
73+
- Custom views: GuidedLabeledContent, SliderStepperView, Video, ValueTextBubble
74+
75+
**RadiantDocs** (depends on RadiantKit)
76+
- Document management for SwiftUI apps
77+
- Core protocols: `CodablePackage`, `FileTypeSpecification`, `InitializablePackage`
78+
- `DocumentFile<FileType>`: Generic, type-safe file wrapper
79+
- `CodablePackageDocument<T>`: FileDocument implementation for package files
80+
- File panel abstractions and UTType integration
81+
82+
**RadiantPaging** (depends on RadiantKit)
83+
- Page-based navigation UI patterns
84+
- `PageView`: Main component for sequential page display
85+
- Environment-based actions: `NextPageAction`, `PreviousPageAction`, `CancelPageAction`
86+
- `PageNavigationAvailability`: Controls which navigation buttons appear
87+
- Integrates with `IdentifiableView` from RadiantKit
88+
89+
**RadiantProgress** (independent, depends on swift-log for Linux)
90+
- Progress tracking for file operations and downloads
91+
- `ProgressOperation<ValueType>`: Protocol for any progress-reporting operation
92+
- `DownloadOperation`: Observable implementation with URLSession integration
93+
- `FileOperationProgress`: SwiftUI-friendly wrapper for any ProgressOperation
94+
- `ObservableDownloader`: Combines Observation and Combine patterns
95+
96+
### Key Architectural Patterns
97+
98+
**Property Wrappers**
99+
- `AppStored` protocol defines key-based storage contracts
100+
- `DefaultWrapped` extends AppStored with default value support
101+
- UserDefaults extensions provide type-safe retrieval
102+
103+
**Generic Type Systems**
104+
- `DocumentFile<FileType: FileTypeSpecification>`: Type-safe file handling
105+
- `ProgressOperation<ValueType: BinaryInteger & Sendable>`: Flexible progress reporting
106+
- Extensive use of generics to prevent runtime errors
107+
108+
**Observable/Reactive**
109+
- `@Observable` macro for iOS 17+ reactive state
110+
- MainActor isolation throughout for UI thread safety
111+
- Sendable conformance for cross-actor communication
112+
113+
**Protocol-Based Design**
114+
- Interface segregation (small, focused protocols)
115+
- Protocol extensions for shared functionality
116+
- Generic constraints for type safety
117+
118+
**SwiftUI Environment Integration**
119+
- Page navigation actions injected via environment
120+
- Custom environment keys for cross-view communication
121+
122+
### Module Dependencies
123+
124+
```
125+
RadiantKit (foundation)
126+
↑ ↑
127+
| |
128+
| |
129+
RadiantDocs RadiantPaging
130+
131+
RadiantProgress (independent)
132+
```
133+
134+
## Swift 6 & Experimental Features
135+
136+
This project uses Swift 6.0 with multiple experimental features enabled:
137+
- AccessLevelOnImport
138+
- BitwiseCopyable
139+
- IsolatedAny
140+
- MoveOnlyPartialConsumption
141+
- NestedProtocols
142+
- NoncopyableGenerics
143+
- TransferringArgsAndResults
144+
- VariadicGenerics
145+
- FullTypedThrows (upcoming)
146+
- InternalImportsByDefault (upcoming)
147+
148+
Code must be compatible with strict concurrency checking and Sendable requirements.
149+
150+
## Code Style
151+
152+
### Formatting
153+
- Uses swift-format (v600.0.0) with configuration in `.swift-format`
154+
- SwiftLint (v0.58.0) with rules in `.swiftlint.yml`
155+
- All source files require copyright headers (managed by `Scripts/header.sh`)
156+
157+
### Concurrency
158+
- All UI components are `@MainActor` isolated
159+
- Closures crossing actor boundaries must be `@Sendable`
160+
- Use `nonisolated` sparingly and only when necessary
161+
162+
### Naming Conventions
163+
- Protocols use descriptive nouns (CodablePackage, ProgressOperation)
164+
- Generic type parameters use full words (FileType, ValueType)
165+
- Environment keys follow pattern: `<Action>Key` (NextPageKey, PreviousPageKey)
166+
167+
## Testing
168+
169+
Tests are located in `Tests/RadiantKitTests/`. The CI pipeline runs tests across:
170+
- Ubuntu (Swift 6.2, nightly 6.3)
171+
- Windows (Swift 6.2)
172+
- Android (Swift 6.1, 6.2, nightly-main)
173+
- macOS/iOS/tvOS/watchOS/visionOS simulators with Xcode 16.1, 16.4, and 26.2
174+
175+
When adding features:
176+
1. Add tests to RadiantKitTests targeting the appropriate module
177+
2. Ensure tests pass on both macOS and Linux (note: RadiantProgress uses swift-log on Linux)
178+
3. CI enforces strict code coverage requirements via Codecov
179+
180+
## Platform Support
181+
182+
Minimum deployment targets:
183+
- iOS 18.0 / iPadOS 18.0
184+
- macOS 15.0
185+
- tvOS 18.0
186+
- watchOS 11.0
187+
- visionOS 2.0
188+
- Mac Catalyst 18.0
189+
190+
Platform-specific code should use `#if canImport()` or `#if os()` directives.
191+
192+
## Adding New Modules
193+
194+
If creating a new target:
195+
1. Add to `Package.swift` products and targets arrays
196+
2. Apply `swiftSettings` for experimental features
197+
3. Update module dependency graph (RadiantKit as foundation, others can depend on it)
198+
4. Add corresponding test target
199+
5. Update `.github/workflows/RadiantKit.yml` if platform-specific testing needed

0 commit comments

Comments
 (0)