From 7c70d84927199841ff86f389ba201df3e1dbcaa8 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Fri, 9 Oct 2026 23:47:21 -0700 Subject: [PATCH 1/2] deps: align vendored drive/ocaml-signal SHAs with the opam pins CI vendors the lockfile SHAs (opam monorepo pull fills duniverse before the pin-depends clone loop, which then skips existing dirs). The lockfile still pointed at drive 7f407b0, which predates the detach-subtree patch op, so every drive test died in Drive.Model.apply_op with a non-exhaustive match (26 failures). ocaml-signal had drifted the same way (868c145 -> df355e1). --- logseq.opam.locked | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/logseq.opam.locked b/logseq.opam.locked index 82d7a5d..0b34908 100644 --- a/logseq.opam.locked +++ b/logseq.opam.locked @@ -323,7 +323,7 @@ pin-depends: [ ] [ "drive.dev" - "git+https://github.com/logseq/drive.git#7f407b07f18e68596cb0dcb3ba1781cb0572a2bb" + "git+https://github.com/logseq/drive.git#1e1653d5bdd0810e89d9e3a32b2e0ea2811c1cf5" ] [ "dune-build-info.3.24.2" @@ -476,7 +476,7 @@ pin-depends: [ ] [ "ocaml-signal.0.1.0" - "git+https://github.com/logseq/ocaml-signal.git#868c1459f865b4ba3b227eb440dba40f1c812899" + "git+https://github.com/logseq/ocaml-signal.git#df355e15869ceb7220c0365ae7057e4c3fc558b2" ] [ "ocaml-syntax-shims.1.0.0" @@ -1482,7 +1482,7 @@ x-opam-monorepo-duniverse-dirs: [ "angstrom" ] [ - "git+https://github.com/logseq/drive.git#7f407b07f18e68596cb0dcb3ba1781cb0572a2bb" + "git+https://github.com/logseq/drive.git#1e1653d5bdd0810e89d9e3a32b2e0ea2811c1cf5" "drive" ] [ @@ -1490,7 +1490,7 @@ x-opam-monorepo-duniverse-dirs: [ "ocaml-fsrs" ] [ - "git+https://github.com/logseq/ocaml-signal.git#868c1459f865b4ba3b227eb440dba40f1c812899" + "git+https://github.com/logseq/ocaml-signal.git#df355e15869ceb7220c0365ae7057e4c3fc558b2" "ocaml-signal" ] [ From 0311f6c055fe240d387bc9aad15e3498f7ce2890 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Sat, 10 Oct 2026 00:00:56 -0700 Subject: [PATCH 2/2] Build iOS libffi for the device target and cache more build outputs - build-mobile-ios-device.sh now builds a real iOS libffi like the simulator script does: ctypes-foreign's stub compile was falling back to the host CLT ffi.h ("not available on iOS"), and the archive link now gets -L for the vendored libffi.a. PKG_CONFIG_PATH points the ctypes pkg-config discovery at the toolchain prefix. - build-ios-release.yml caches _build/ios-core (incremental dune), apple/.build + DerivedData, and bundler gems under vendor/bundle. - build-android.yml caches android/app/.cxx + build/intermediates for incremental CMake/Gradle rebuilds. --- .github/workflows/build-android.yml | 21 +++++++++++ .github/workflows/build-ios-release.yml | 48 +++++++++++++++++++++++++ scripts/build-mobile-ios-device.sh | 13 ++++++- 3 files changed, 81 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-android.yml b/.github/workflows/build-android.yml index 16fc271..fd5e3ba 100644 --- a/.github/workflows/build-android.yml +++ b/.github/workflows/build-android.yml @@ -168,6 +168,18 @@ jobs: _build/android-sqlite-host key: android-toolchain-${{ runner.os }}-arm64-v8a-5.5.0-${{ hashFiles('scripts/bootstrap-android-ocaml.sh', 'scripts/build-mobile-libffi.sh') }} + - name: Restore Android native build cache + # CMake intermediate objects under .cxx survive source-unchanged + # rebuilds; the sha key falls back to the previous commit's tree. + uses: actions/cache/restore@v4 + with: + path: | + android/app/.cxx + android/app/build/intermediates + key: android-native-${{ runner.os }}-${{ github.sha }} + restore-keys: | + android-native-${{ runner.os }}- + - name: Build Android release APK # assembleRelease depends on buildAndroidNativeCore, which runs # scripts/build-android-native.sh for $LOGSEQ_ANDROID_ABI; the Kotlin @@ -189,6 +201,15 @@ jobs: _build/android-sqlite-host key: android-toolchain-${{ runner.os }}-arm64-v8a-5.5.0-${{ hashFiles('scripts/bootstrap-android-ocaml.sh', 'scripts/build-mobile-libffi.sh') }} + - name: Save Android native build cache + if: always() + uses: actions/cache/save@v4 + with: + path: | + android/app/.cxx + android/app/build/intermediates + key: android-native-${{ runner.os }}-${{ github.sha }} + - name: Sign Android APK run: | echo ${{ secrets.ANDROID_KEYSTORE }} | base64 -d > keystore.jks diff --git a/.github/workflows/build-ios-release.yml b/.github/workflows/build-ios-release.yml index c73f8fa..c7239e6 100644 --- a/.github/workflows/build-ios-release.yml +++ b/.github/workflows/build-ios-release.yml @@ -120,6 +120,26 @@ jobs: eval $(opam env) ./scripts/bootstrap-ios-ocaml.sh device + - name: Restore iOS core build cache + # Dune rebuilds incrementally, so a stale object tree still saves most + # of the cross-compile time on unchanged sources. + uses: actions/cache/restore@v4 + with: + path: _build/ios-core + key: ios-core-${{ runner.os }}-${{ github.sha }} + restore-keys: | + ios-core-${{ runner.os }}- + + - name: Restore Xcode build caches + uses: actions/cache/restore@v4 + with: + path: | + apple/.build + ~/Library/Developer/Xcode/DerivedData + key: ios-xcode-${{ runner.os }}-${{ github.sha }} + restore-keys: | + ios-xcode-${{ runner.os }}- + - name: Build OCaml iOS core (device) # Produces _build/ios-core/device/native-link-inputs.txt, which the # fastlane beta lane exports as LOGSEQ_NATIVE_LINK_INPUTS so the @@ -137,12 +157,31 @@ jobs: path: _build/apple-toolchains key: apple-toolchain-${{ runner.os }}-xcode26.3-ios-device-5.5.0-${{ hashFiles('scripts/bootstrap-ios-ocaml.sh', 'scripts/build-mobile-libffi.sh') }} + - name: Save iOS core build cache + uses: actions/cache/save@v4 + with: + path: _build/ios-core + key: ios-core-${{ runner.os }}-${{ github.sha }} + + - name: Restore bundler gems + uses: actions/cache/restore@v4 + with: + path: apple/App/vendor/bundle + key: bundler-${{ hashFiles('apple/App/Gemfile', 'apple/App/Gemfile.lock', '.github/workflows/build-ios-release.yml') }} + - name: Setup build tools run: | sudo gem install bundler -v 2.7.2 --no-document + bundle _2.7.2_ config set --local path 'vendor/bundle' bundle _2.7.2_ install working-directory: ./apple/App + - name: Save bundler gems + uses: actions/cache/save@v4 + with: + path: apple/App/vendor/bundle + key: bundler-${{ hashFiles('apple/App/Gemfile', 'apple/App/Gemfile.lock', '.github/workflows/build-ios-release.yml') }} + - name: Build and upload iOS app run: | : "${LOGSEQ_GITHUB_PAT:?LOGSEQ_GITHUB_PAT is required for the certificates repository}" @@ -161,3 +200,12 @@ jobs: MATCH_GIT_URL: https://github.com/logseq/certificates.git LOGSEQ_GITHUB_PAT: ${{ secrets.LOGSEQ_GITHUB_PAT }} XCODE_XCARGS: "-allowProvisioningUpdates" + + - name: Save Xcode build caches + if: always() + uses: actions/cache/save@v4 + with: + path: | + apple/.build + ~/Library/Developer/Xcode/DerivedData + key: ios-xcode-${{ runner.os }}-${{ github.sha }} diff --git a/scripts/build-mobile-ios-device.sh b/scripts/build-mobile-ios-device.sh index 43e1556..c48fa83 100755 --- a/scripts/build-mobile-ios-device.sh +++ b/scripts/build-mobile-ios-device.sh @@ -99,8 +99,19 @@ fi ocaml_lib="$target_prefix/lib/ocaml" clang=$(xcrun --sdk iphoneos --find clang) +clangxx=$(xcrun --sdk iphoneos --find clang++) + +# Apple marks libffi unavailable in the iOS SDK headers; ctypes-foreign's stub +# build needs real libffi headers and the final link needs a real libffi.a. +ffi_prefix=$("$repo_root/scripts/build-mobile-libffi.sh" \ + aarch64-apple-darwin \ + "$toolchain_root/ios/libffi-$triple" \ + "$clang -target $triple -isysroot $sdk_path" \ + "$clangxx -target $triple -isysroot $sdk_path") + core_object=$(LOGSEQ_SQLITE_LIB_DIR="$sdk_path/usr/lib" \ LOGSEQ_SQLITE_LINK_FILE="$sdk_path/usr/lib/libsqlite3.tbd" \ + PKG_CONFIG_PATH="$ffi_prefix/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" \ "$repo_root/scripts/build-mobile-ocaml.sh" "$target_prefix" ios_device) for source in logseq_https_darwin.m logseq_crypto_darwin.m; do @@ -121,7 +132,7 @@ native_link_dir="$core_build_dir/native-link-inputs/$native_link_fingerprint" fingerprinted_core_object="$native_link_dir/logseq_runtime.o" mkdir -p "$native_link_dir" [[ -s $fingerprinted_core_object ]] || cp "$core_object" "$fingerprinted_core_object" -native_link_inputs="$fingerprinted_core_object:$https_object:$crypto_object:$ocaml_lib/libthreadsnat.a" +native_link_inputs="$fingerprinted_core_object:$https_object:$crypto_object:$ocaml_lib/libthreadsnat.a:-L$ffi_prefix/lib" # Release path: xcodebuild archives the app via the Xcode project and links # the OCaml core through LOGSEQ_NATIVE_LINK_INPUTS. Emit just the inputs so