Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
f0d9d57
chore: update zig-files-hash to v0.0.8
Preeternal Nov 9, 2026
0881290
chore: update example to React Native 0.88 and refresh template
Preeternal Nov 9, 2026
dc13499
ci: verify native and zig engines with SwiftPM
Preeternal Nov 9, 2026
4465735
ci: fix SwiftPM typo
Preeternal Nov 9, 2026
97fbe86
ci: setup-xcode v1.7.0
Preeternal Nov 9, 2026
597a5e4
fix: example SPM and CI
Preeternal Nov 9, 2026
31bfedc
docs: spm clarification
Preeternal Nov 9, 2026
c54b802
fix(ios): honor cancellation and propagate file read errors
Preeternal Nov 10, 2026
844fb3c
fix: make cancellation cleanup race-safe on iOS and Android
Preeternal Nov 10, 2026
62da47e
test: add native cancellation and stream error regression tests
Preeternal Nov 10, 2026
b38d673
fix(ios): preserve promise rejection for queued cancellations
Preeternal Nov 10, 2026
07e3ef0
chore(macos): migrate example to fresh React Native template
Preeternal Nov 10, 2026
9645e75
ci(macos): build example and run native hash smoke test
Preeternal Nov 10, 2026
f26226c
chore: update gem file
Preeternal Nov 10, 2026
c088aab
ci: fix macos example job
Preeternal Nov 10, 2026
37b197d
chore(ci): build macos release smoke bundle
Preeternal Nov 10, 2026
2140ce7
fix(ci): macos runner
Preeternal Nov 10, 2026
7dcdfaf
chore: update windows example
Preeternal Nov 10, 2026
61ced2a
chore: example with RN 0.88.1
Preeternal Nov 10, 2026
3517681
fix: windows ci
Preeternal Nov 10, 2026
ac84305
ci(windows): package identity debug
Preeternal Nov 10, 2026
812febc
chore: bump version
Preeternal Nov 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions .github/actions/setup-zig/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ inputs:
version:
description: Zig version to install
required: false
default: '0.16.0'
default: '0.17.1'

runs:
using: composite
Expand Down Expand Up @@ -44,22 +44,32 @@ runs:
)
fi
;;
Windows)
ARCHIVE_CANDIDATES=(
"zig-x86_64-windows-${ZIG_VERSION}.zip"
"zig-windows-x86_64-${ZIG_VERSION}.zip"
)
;;
*)
echo "Unsupported runner OS: ${{ runner.os }}" >&2
exit 1
;;
esac

rm -f "$RUNNER_TEMP/zig.tar.xz"
ARCHIVE_PATH="$RUNNER_TEMP/zig.tar.xz"
if [[ "${{ runner.os }}" == "Windows" ]]; then
ARCHIVE_PATH="$RUNNER_TEMP/zig.zip"
fi
rm -f "$ARCHIVE_PATH"
ZIG_URL=""
for archive in "${ARCHIVE_CANDIDATES[@]}"; do
candidate_url="https://ziglang.org/download/${ZIG_VERSION}/${archive}"
echo "Trying Zig URL: $candidate_url"
if curl -fL --retry 3 "$candidate_url" -o "$RUNNER_TEMP/zig.tar.xz"; then
if curl -fL --retry 3 "$candidate_url" -o "$ARCHIVE_PATH"; then
ZIG_URL="$candidate_url"
break
fi
rm -f "$RUNNER_TEMP/zig.tar.xz"
rm -f "$ARCHIVE_PATH"
done

if [[ -z "$ZIG_URL" ]]; then
Expand All @@ -68,8 +78,13 @@ runs:
fi

echo "Using Zig archive: $ZIG_URL"
mkdir -p "$RUNNER_TEMP/zig"
tar -xf "$RUNNER_TEMP/zig.tar.xz" -C "$RUNNER_TEMP/zig" --strip-components=1
if [[ "${{ runner.os }}" == "Windows" ]]; then
mkdir -p "$RUNNER_TEMP/zig"
pwsh -NoProfile -Command 'Expand-Archive -LiteralPath "$env:RUNNER_TEMP/zig.zip" -DestinationPath "$env:RUNNER_TEMP/zig-archive" -Force; $root = Get-ChildItem "$env:RUNNER_TEMP/zig-archive" | Select-Object -First 1; Copy-Item "$($root.FullName)\*" "$env:RUNNER_TEMP/zig" -Recurse -Force'
else
mkdir -p "$RUNNER_TEMP/zig"
tar -xf "$RUNNER_TEMP/zig.tar.xz" -C "$RUNNER_TEMP/zig" --strip-components=1
fi
echo "$RUNNER_TEMP/zig" >> "$GITHUB_PATH"

- name: Verify Zig
Expand Down
231 changes: 182 additions & 49 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -400,10 +400,17 @@ jobs:

- name: Use appropriate Xcode version
if: env.turbo_cache_hit != 1
uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0
uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1.7.0
with:
xcode-version: ${{ env.XCODE_VERSION }}

- name: Run native Swift unit tests
run: |
CLANG_MODULE_CACHE_PATH="$RUNNER_TEMP/clang-module-cache" \
SWIFT_MODULECACHE_PATH="$RUNNER_TEMP/swift-module-cache" \
FILE_HASH_SWIFT_TESTS=1 \
swift test

- name: Install cocoapods
if: env.turbo_cache_hit != 1 && steps.cocoapods-cache.outputs.cache-hit != 'true'
run: |
Expand All @@ -416,8 +423,17 @@ jobs:
run: |
yarn turbo run build:ios --filter=@preeternal/react-native-file-hash-example --cache-dir="${{ env.TURBO_CACHE_DIR }}"

build-android-rn87:
runs-on: ubuntu-latest
build-ios-spm:
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
engine: [native, zig]

env:
XCODE_VERSION: 26
RCT_USE_RN_DEP: 1
RCT_USE_PREBUILT_RNCORE: 1

steps:
- name: Checkout
Expand All @@ -426,41 +442,66 @@ jobs:
- name: Setup
uses: ./.github/actions/setup

- name: Set up JDK 17
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
- name: Use appropriate Xcode version
uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1.7.0
with:
distribution: zulu
java-version: 17

- name: Accept Android SDK licenses
run: yes | "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" --licenses >/dev/null || true
xcode-version: ${{ env.XCODE_VERSION }}

- name: Cache Gradle
- name: Cache React Native SwiftPM artifacts (${{ matrix.engine }})
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-rn87-${{ hashFiles('examples/ExampleSpm/android/gradle/wrapper/gradle-wrapper.properties', 'yarn.lock') }}
path: ~/Library/Caches/ReactNative/spm-artifacts
key: ${{ runner.os }}-react-native-spm-${{ matrix.engine }}-${{ hashFiles('example/package.json', 'Package.swift', 'yarn.lock', '.yarn/patches/**') }}
restore-keys: |
${{ runner.os }}-gradle-rn87-
${{ runner.os }}-gradle-
${{ runner.os }}-react-native-spm-${{ matrix.engine }}-

- name: Build RN 0.87 example for Android
env:
JAVA_OPTS: '-XX:MaxHeapSize=6g'
run: yarn example:spm build:android
- name: Install CocoaPods
run: |
cd example
bundle install
bundle exec pod repo update --verbose
bundle exec pod install --project-directory=ios

- name: Set up SwiftPM
run: |
plutil -insert ZFHEngine -string "${{ matrix.engine }}" \
example/ios/FileHashExample/Info.plist
cd example
bundle exec pod deintegrate ios/FileHashExample.xcodeproj
npx react-native spm add --yes

- name: Verify benchmark TurboModule registration
- name: Build example for iOS with SwiftPM (${{ matrix.engine }})
run: |
grep -Fq 'add(BenchmarkFilePackage())' examples/ExampleSpm/android/app/src/main/java/com/examplespm/MainApplication.kt
grep -Fq ': NativeBenchmarkFileSpec' examples/ExampleSpm/android/app/src/main/java/com/examplespm/BenchmarkFileModule.kt
IOS_BUILD_LOG="$RUNNER_TEMP/ios-spm-${{ matrix.engine }}-build.log"
if ! xcodebuild \
-project example/ios/FileHashExample.xcodeproj \
-scheme FileHashExample \
-configuration Debug \
-sdk iphonesimulator \
-destination 'generic/platform=iOS Simulator' \
-derivedDataPath example/ios/build/DerivedData \
COMPILER_INDEX_STORE_ENABLE=NO \
DISABLE_MANUAL_TARGET_ORDER_BUILD_WARNING=YES \
CODE_SIGNING_ALLOWED=NO \
CODE_SIGNING_REQUIRED=NO \
build 2>&1 | tee "$IOS_BUILD_LOG"; then
grep -n -m 30 -E 'error:|fatal error:' "$IOS_BUILD_LOG" || true
exit 1
fi

- name: Verify SwiftPM integration (${{ matrix.engine }})
run: |
test -f example/ios/FileHashExample.xcodeproj/.spm-injected.json
test -f example/ios/ReactNativeSPM/ReactNativeSPM.xcconfig
test -f example/ios/ReactNativeSPM/Scripts/sync-autolinking.sh
test -f example/ios/ReactNativeSPM/Scripts/embed-flavored-frameworks.sh


build-ios-spm-rn87:
build-macos-example:
runs-on: macos-latest

env:
XCODE_VERSION: latest-stable
XCODE_VERSION: 26

steps:
- name: Checkout
Expand All @@ -469,39 +510,131 @@ jobs:
- name: Setup
uses: ./.github/actions/setup

- name: Test smoke runner
run: node --test scripts/__tests__/run-macos-smoke.test.cjs

- name: Use appropriate Xcode version
uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0
uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1.7.0
with:
xcode-version: ${{ env.XCODE_VERSION }}

- name: Cache React Native SwiftPM artifacts
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: ~/Library/Caches/ReactNative/spm-artifacts
key: ${{ runner.os }}-react-native-spm-${{ hashFiles('examples/ExampleSpm/package.json', 'Package.swift', 'yarn.lock', '.yarn/patches/**') }}
restore-keys: |
${{ runner.os }}-react-native-spm-
- name: Install Zig
uses: ./.github/actions/setup-zig

- name: Build RN 0.87 example for iOS with SwiftPM
- name: Build Zig prebuilt for macOS
run: ./scripts/build-zig-macos.sh

- name: Install CocoaPods
working-directory: examples/macos
run: |
IOS_BUILD_LOG="$RUNNER_TEMP/ios-spm-rn87-build.log"
if ! yarn example:spm build:ios 2>&1 | tee "$IOS_BUILD_LOG"; then
grep -n -m 30 -E 'error:|fatal error:' "$IOS_BUILD_LOG" || true
exit 1
fi
bundle install
bundle exec pod install --project-directory=macos

- name: Build package
run: yarn prepare

- name: Build macOS Release smoke bundle
working-directory: examples/macos/macos
run: |
set -o pipefail
xcodebuild \
-workspace FileHashMacOSExample.xcworkspace \
-scheme FileHashMacOSExample-macOS \
-configuration Release \
-sdk macosx \
-derivedDataPath "$RUNNER_TEMP/file-hash-macos-derived" \
CODE_SIGNING_ALLOWED=NO \
CODE_SIGNING_REQUIRED=NO \
ENTRY_FILE=index.smoke.tsx \
BUNDLE_NAME=main.smoke \
build 2>&1 | tee "$RUNNER_TEMP/macos-build.log"

- name: Run Release JS hash smoke test
working-directory: examples/macos/macos
run: |
set -euo pipefail
app_binary="$RUNNER_TEMP/file-hash-macos-derived/Build/Products/Release/FileHashMacOSExample.app/Contents/MacOS/FileHashMacOSExample"
smoke_log="$RUNNER_TEMP/macos-smoke.log"

bash ../../../scripts/run-macos-smoke.sh "$app_binary" "$smoke_log"

- name: Upload macOS diagnostics
if: always()
uses: actions/upload-artifact@v4
with:
name: macos-example-diagnostics
if-no-files-found: warn
path: |
${{ runner.temp }}/macos-build.log
${{ runner.temp }}/macos-smoke.log

build-windows-example:
runs-on: windows-2025-vs2026

steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

- name: Setup
uses: ./.github/actions/setup

- name: Install Zig
uses: ./.github/actions/setup-zig

- name: Typecheck Windows example
run: yarn workspace @preeternal/react-native-file-hash-windows-example typecheck

- name: Build Zig prebuilt for Windows
shell: bash
run: ./scripts/build-zig-windows.sh

- name: Verify podless integration and benchmark registration
- name: Build package
run: yarn prepare

- name: Build Windows Release smoke bundle
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'
$kitsRoot = Join-Path ${env:ProgramFiles(x86)} 'Windows Kits\10'
$sdkVersion = Get-ChildItem (Join-Path $kitsRoot 'Include') -Directory |
Where-Object { $_.Name -match '^10\.0\.\d+\.0$' } |
Where-Object {
[version]$_.Name -ge [version]'10.0.22621.0' -and
(Test-Path (Join-Path $_.FullName 'um\Windows.h')) -and
(Test-Path (Join-Path $kitsRoot "Lib\$($_.Name)\um\x64\kernel32.lib")) -and
(Test-Path (Join-Path $kitsRoot "Lib\$($_.Name)\ucrt\x64\ucrt.lib"))
} |
Sort-Object { [version]$_.Name } -Descending |
Select-Object -First 1 -ExpandProperty Name
if (-not $sdkVersion) { throw 'No complete x64 Windows SDK >= 10.0.22621.0 is installed' }
Write-Host "Using Windows SDK $sdkVersion"
$msbuildProps = "BundleEntryFile=index.smoke.windows.tsx,WindowsTargetPlatformVersion=$sdkVersion,TargetPlatformVersion=$sdkVersion"

$env:FILE_HASH_WINDOWS_SMOKE_LOG = Join-Path $env:RUNNER_TEMP 'windows-smoke.log'
Remove-Item $env:FILE_HASH_WINDOWS_SMOKE_LOG -ErrorAction SilentlyContinue
yarn workspace @preeternal/react-native-file-hash-windows-example windows --release --arch x64 --no-deploy --no-packager --msbuildprops $msbuildProps

- name: Register Windows app layout
shell: pwsh
run: yarn workspace @preeternal/react-native-file-hash-windows-example windows --release --arch x64 --no-build --no-launch --no-packager --deploy-from-layout

- name: Run Release JS hash smoke test
shell: pwsh
run: |
test ! -d examples/ExampleSpm/ios/Pods
grep -q '@"BenchmarkFile": @"BenchmarkFileModule"' examples/ExampleSpm/ios/build/generated/ios/ReactCodegen/RCTModuleProviders.mm
./scripts/run-windows-smoke.ps1 -LogFile (Join-Path $env:RUNNER_TEMP 'windows-smoke.log')

- name: Upload SwiftPM build log
- name: Upload Windows diagnostics
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
uses: actions/upload-artifact@v4
with:
name: ios-spm-rn87-build-log
path: ${{ runner.temp }}/ios-spm-rn87-build.log
if-no-files-found: ignore
name: windows-example-diagnostics
if-no-files-found: warn
path: |
${{ runner.temp }}/windows-smoke.log
${{ runner.temp }}/windows-smoke.log.events.log
examples/windows/windows/**/msbuild*.err
examples/windows/windows/**/msbuild*.wrn
examples/windows/windows/**/msbuild*.binlog

build-ios-zig:
runs-on: macos-latest
Expand Down Expand Up @@ -538,7 +671,7 @@ jobs:

- name: Use appropriate Xcode version
if: env.turbo_cache_hit != 1
uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0
uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1.7.0
with:
xcode-version: ${{ env.XCODE_VERSION }}

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ jsconfig.json
# Xcode
#
build/
.build/
*.pbxuser
!default.pbxuser
*.mode1v3
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v24.13.0
v24.22.1
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
diff --git a/package.json b/package.json
--- a/package.json
+++ b/package.json
@@ -1,3 +1,6 @@
{
"name": "@react-native-documents/picker",
+ "swiftpmConfig": {
+ "name": "Picker"
+ },
"version": "12.0.3",
diff --git a/Package.swift b/Package.swift
new file mode 100644
index 0000000000000000000000000000000000000000..f3381059164fc8a31f0d976d09bc79713417743a
Expand Down
Loading
Loading