feat(deps): upgrade Tauri to 2.11.5, and own the Android context it stopped setting
🏗️ Build and Test JellyTau / Run Tests (pull_request) Successful in 22m51s
🏗️ Build and Test JellyTau / Supply Chain (pull_request) Failing after 25s
Traceability Validation / Check Requirement Traces (pull_request) Successful in 14s
🏗️ Build and Test JellyTau / Android Compile Check (pull_request) Successful in 4m19s
🏗️ Build and Test JellyTau / Run Tests (pull_request) Successful in 22m51s
🏗️ Build and Test JellyTau / Supply Chain (pull_request) Failing after 25s
Traceability Validation / Check Requirement Traces (pull_request) Successful in 14s
🏗️ Build and Test JellyTau / Android Compile Check (pull_request) Successful in 4m19s
The plugin versions could not be matched upward without this: both
tauri-plugin-log 2.9.0 and tauri-plugin-updater 2.10.1 require tauri
^2.10, and the tree was on 2.9.5. So the framework moves with them --
tauri 2.9.5 -> 2.11.5, tauri-build 2.5.3 -> 2.6.3, wry 0.53.5 -> 0.55.1
-- and every plugin's Rust crate and npm package is now pinned to the
same version on both sides.
That upgrade broke Android outright, and the breakage is the interesting
part.
Seven call sites in this crate reach JNI through
ndk_context::android_context(), which reads a process-global pair of
pointers. Nothing here ever set that global. `tao` did -- the windowing
layer under wry, three levels below anything this project names in
Cargo.toml. tao 0.34.5 called initialize_android_context() while starting
the activity and our code read what it left behind. tao 0.35.3 keeps the
same two pointers in a private struct and no longer publishes them.
The result, on every launch, was:
PANIC at ndk-context/src/lib.rs:72: android context was not initialized
8: ndk_context::android_context
9: jellytau_lib::run::{{closure}}
Not a crash in our code, and not a change to our code: an undocumented
side effect of a transitive dependency disappeared. Relying on someone
else to populate a global is a dependency that does not appear in
Cargo.toml and gives no warning when it goes.
src-tauri/src/android_context.rs now owns that invariant instead of
assuming it. JNI_OnLoad captures the JavaVM as the shared library loads
-- the earliest moment available, and nothing in tao, wry or tauri
defines one to collide with. The Context is resolved lazily via
ActivityThread.currentApplication() and pinned as a global reference for
the process lifetime, since ndk_context stores a bare pointer and does
not own it. It publishes the Application rather than the Activity:
SecureStorage.initialize() immediately reduces its argument to
applicationContext anyway, and an Application cannot outlive itself the
way a retained Activity would.
Restoring the global keeps all seven callers untouched. Threading a VM
and Context handle through five credential call sites would have been a
larger change with more risk, on the credential path.
Failure now degrades instead of aborting: it is logged and credentials
fall back to the encrypted-file path, which the app already supports.
Verified on a device, R8-minified, not merely compiled:
[INIT] Android JavaVM and Application published to ndk_context
Android SecureStorage initialized successfully
Android Keystore available via SecureStorage
[INIT] Using system keyring for credential storage
[CodecDetection] Detected 7 video codecs: av1,h263,h264,hevc,...
-- the real keystore path, not the fallback, and the app stays up. None
of this is reachable by CI: nothing there runs the app.
Also fixed here, both found the same way:
- `tauri android build --apk true` is now `--apk`. The CLI took a value
until 2.10; from 2.11 the stray `true` is a positional and the build
fails before starting. Three call sites in build-android.sh and one
in build-release.yml -- the latter builds the signed APK, by far the
most-downloaded artifact.
- scripts/build-android.sh ran `npm install` on its clean-build path in
a bun project, ignoring bun.lock and re-resolving the tree. That is
exactly how the plugin crate/package versions drift apart again.
scripts/check-tooling.sh now fails on any npm/yarn/pnpm invocation or
foreign lockfile, and runs in CI.
DR-222, DR-223.
This commit is contained in:
Executable
+73
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env bash
|
||||
# Refuse tooling that contradicts what this project actually uses.
|
||||
#
|
||||
# TRACES: | DR-222
|
||||
#
|
||||
# ./scripts/check-tooling.sh
|
||||
#
|
||||
# ## Why
|
||||
#
|
||||
# This is a bun project: `packageManager` in package.json says so, bun.lock is
|
||||
# the committed lockfile, and .gitignore hides the other package managers'
|
||||
# lockfiles precisely so they cannot be committed by accident.
|
||||
#
|
||||
# scripts/build-android.sh nonetheless ran `npm install` on its clean-build
|
||||
# path. npm ignores bun.lock, re-resolves the whole tree from package.json, and
|
||||
# writes a package-lock.json that .gitignore then hides from view.
|
||||
#
|
||||
# That is not a style preference. The Tauri CLI refuses to build when a plugin's
|
||||
# Rust crate and npm package differ by minor version, so the JS side is pinned
|
||||
# exactly against Cargo.lock -- and a silent re-resolve is exactly how those
|
||||
# halves drift apart again. The drift already cost one release build.
|
||||
#
|
||||
# It survived because the clean-build path runs rarely. That is the shape of
|
||||
# nearly every defect found while preparing v0.10.0: the code that runs on every
|
||||
# commit was fine, and the code that runs on a release, a clean build or a tag
|
||||
# had no guard at all.
|
||||
|
||||
set -uo pipefail
|
||||
|
||||
REPO_ROOT="$(git rev-parse --show-toplevel)"
|
||||
cd "$REPO_ROOT" || exit 1
|
||||
|
||||
FAILED=0
|
||||
|
||||
echo "🔎 Checking build tooling is consistent with packageManager…"
|
||||
|
||||
# Only the *invocations* matter. A comment explaining why npm is wrong, or a
|
||||
# .gitignore entry naming package-lock.json, is not a violation -- so match a
|
||||
# command at the start of a line or after a shell separator.
|
||||
PATTERN='(^|[;&|(]|&&|\|\||\bthen |\bdo |[[:space:]]{4,})(npm|yarn|pnpm)[[:space:]]+(install|ci|add|run|exec)\b'
|
||||
|
||||
MATCHES="$(grep -rInE "$PATTERN" \
|
||||
--include='*.sh' --include='*.yml' --include='*.yaml' \
|
||||
scripts/ .gitea/ 2>/dev/null | grep -v '^\s*#' || true)"
|
||||
|
||||
if [ -n "$MATCHES" ]; then
|
||||
echo "❌ A non-bun package manager is invoked:"
|
||||
echo "$MATCHES" | sed 's/^/ /'
|
||||
echo ""
|
||||
echo " This project uses bun (packageManager in package.json, bun.lock"
|
||||
echo " committed). npm/yarn/pnpm ignore that lockfile and re-resolve the"
|
||||
echo " dependency tree, which is how the Tauri plugin crate/package"
|
||||
echo " versions drifted apart and broke a release build."
|
||||
echo ""
|
||||
echo " Use: bun install / bun run / bunx"
|
||||
FAILED=1
|
||||
fi
|
||||
|
||||
# A lockfile from another manager should never exist here; .gitignore hides
|
||||
# them, so one can sit in a working tree unnoticed and change what installs.
|
||||
for stray in package-lock.json yarn.lock pnpm-lock.yaml; do
|
||||
if [ -f "$stray" ]; then
|
||||
echo "❌ $stray exists. Another package manager has run here."
|
||||
echo " Delete it and run: bun install"
|
||||
FAILED=1
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$FAILED" -eq 0 ]; then
|
||||
echo "✅ Only bun is used, and no foreign lockfile is present."
|
||||
fi
|
||||
|
||||
exit "$FAILED"
|
||||
Reference in New Issue
Block a user