Skip to content

Commit def1907

Browse files
cursoragent0xLeif
andcommitted
Fix CI and prep 2.1.3 for AppState 3.0
macOS and DocC were failing because runners no longer ship Xcode 16. Switch those workflows to macos-15 + latest-stable (same as AppState). Also polish the #30 fixes for release: unwrap before collection casts on Linux/WASI, import Combine when available, and document 2.1.3 so AppState can drop its Cache revision pin. Co-authored-by: Leif <leif.algo@pm.me>
1 parent daf6cd6 commit def1907

6 files changed

Lines changed: 47 additions & 17 deletions

File tree

.github/workflows/docc.yml

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
environment:
1919
name: github-pages
2020
url: '${{ steps.deployment.outputs.page_url }}'
21-
runs-on: macos-latest
21+
runs-on: macos-15
2222

2323
steps:
2424
- name: Checkout code
@@ -27,12 +27,7 @@ jobs:
2727
- name: Setup Xcode
2828
uses: maxim-lobanov/setup-xcode@v1
2929
with:
30-
xcode-version: 16.0
31-
32-
- name: Set up Swift
33-
uses: swift-actions/setup-swift@v2
34-
with:
35-
swift-version: '6.1.0'
30+
xcode-version: latest-stable
3631

3732
- name: Build and Export DocC
3833
run: |

.github/workflows/macOS.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ on:
88

99
jobs:
1010
build:
11-
runs-on: macos-latest
11+
runs-on: macos-15
1212
steps:
1313
- uses: maxim-lobanov/setup-xcode@v1
1414
with:
15-
xcode-version: 16.0
15+
xcode-version: latest-stable
1616
- uses: actions/checkout@v4
1717
- name: Build
1818
run: swift build -v

CHANGELOG.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [Unreleased]
9+
10+
## [2.1.3] - 2026-07-17
11+
12+
Release intended for consumers such as **AppState 3.0**, which can replace a revision pin of Cache#30 with `from: "2.1.3"`.
13+
14+
### Fixed
15+
16+
- **WebAssembly / WASI builds** — Guard `@Published` / `ObservableObject` with `#if canImport(Combine)` instead of `#if !os(Linux) && !os(Windows)`, so wasm no longer takes the Combine path ([#30](https://github.com/0xLeif/Cache/pull/30), AppState#149).
17+
- **Linux / WASI collection cast crash**`Dictionary.get(_:as:)` unwraps the optional value before casting, avoiding `swift_dynamicCastFailure` / `_arrayForceCast` aborts when reading collection-typed values from an `Any` cache ([#30](https://github.com/0xLeif/Cache/pull/30), AppState#151).
18+
- **CI** — macOS and DocC workflows no longer pin Xcode 16 (unavailable on current `macos-latest` images). Use `macos-15` with `latest-stable` Xcode, matching AppState.
19+
20+
### Changed
21+
22+
- Explicitly import Combine when available so `@Published` / `ObservableObject` compile reliably across build configurations.
23+
24+
## [2.1.2] - 2025-09-20
25+
26+
### Added
27+
28+
- DocC plugin dependency and GitHub Pages documentation workflow updates.
29+
30+
[Unreleased]: https://github.com/0xLeif/Cache/compare/2.1.3...HEAD
31+
[2.1.3]: https://github.com/0xLeif/Cache/compare/2.1.2...2.1.3
32+
[2.1.2]: https://github.com/0xLeif/Cache/releases/tag/2.1.2

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Cache is a Swift library for caching arbitrary data types in memory. It provides
1515
- Flexible caching, allowing for multiple Cache objects with different configurations
1616
- Thread-safe implementation
1717
- Property Wrappers
18+
- Cross-platform: Apple platforms, Linux, Windows, and WebAssembly (WASI)
1819

1920
## Installation
2021

@@ -24,7 +25,7 @@ Add the following line to your `Package.swift` file in the dependencies array:
2425

2526
```swift
2627
dependencies: [
27-
.package(url: "https://github.com/0xLeif/Cache.git", from: "2.0.0")
28+
.package(url: "https://github.com/0xLeif/Cache.git", from: "2.1.3")
2829
]
2930
```
3031

Sources/Cache/Cache/Cache.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import Foundation
22

3+
#if canImport(Combine)
4+
import Combine
5+
#endif
6+
37
/**
48
`Cache` class provides a cache functionality that can be used to store key-value pairs. It is thread-safe using a locking mechanism.
59

Sources/Cache/Dictionary/Dictionary+Cacheable.swift

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,11 @@ extension Dictionary: Cacheable {
1515
- Returns: The casted value for the given key, or `nil` if the key doesn't exist or the cast fails.
1616
*/
1717
public func get<Item>(_ key: Key, as: Item.Type = Item.self) -> Item? {
18-
// Route through an explicit `Any` boxing step before the conditional cast. This avoids
19-
// `swift_dynamicCastFailure` / `_arrayForceCast` aborts on Linux and WASI when casting an
20-
// `Optional<Any>` that wraps a collection type (e.g. `[SomeStruct]`): without the
21-
// intermediate cast, the runtime takes the `Optional<Any>` → `[T]` forced-array-cast path,
22-
// which is not implemented the same way off Darwin. Boxing to `Any` first normalises the
23-
// dynamic type to the concrete `Item` path.
24-
guard let value = (self[key] as Any) as? Item else {
18+
// Unwrap the optional value first. Casting `Optional<Any>` (or `Optional<Value>`)
19+
// directly to a collection type (e.g. `[T]`) can abort on Linux/WASI with
20+
// `swift_dynamicCastFailure` / `_arrayForceCast`. Unwrapping first takes the
21+
// concrete `Value` → `Item` path instead.
22+
guard let rawValue = self[key], let value = rawValue as? Item else {
2523
return nil
2624
}
2725

0 commit comments

Comments
 (0)