fix: trust mise configs and ensure rust target in the build hook

This commit is contained in:
Santo Shakil 2026-07-04 18:52:31 +06:00
parent ead25d62b5
commit bca556b6c5
6 changed files with 82 additions and 5 deletions

View file

@ -34,6 +34,15 @@ platform :ios do
)
end
# Xcode script phases don't inherit MISE_TRUSTED_CONFIG_PATHS, and the mise shim
# for rustup refuses untrusted configs, which kills the native assets build hook.
# `mise trust` persists trust to disk so it survives into the xcode environment.
def trust_mise_configs
return unless system("command -v mise > /dev/null 2>&1")
sh("mise trust ../../../mise.toml")
sh("mise trust ../../mise.toml")
end
# Helper method to assemble xcargs with optional CUSTOM_GROUP_ID override
def build_xcargs(group_id: nil)
args = "-skipMacroValidation CODE_SIGN_IDENTITY='#{CODE_SIGN_IDENTITY}' CODE_SIGN_STYLE=Manual"
@ -102,6 +111,8 @@ end
)
app_identifier = base_bundle_id
trust_mise_configs
# Set version number if provided
if version_number
increment_version_number(version_number: version_number)
@ -258,6 +269,8 @@ end
api_key = get_api_key
trust_mise_configs
# Download and install provisioning profiles from App Store Connect
# Certificate is imported by GHA workflow into build.keychain
sigh(api_key: api_key, app_identifier: DEV_BUNDLE_ID, force: true)

View file

@ -1,3 +1,6 @@
import 'dart:io';
import 'package:code_assets/code_assets.dart';
import 'package:hooks/hooks.dart';
import 'package:native_toolchain_rust/native_toolchain_rust.dart';
@ -6,9 +9,53 @@ import 'package:native_toolchain_rust/native_toolchain_rust.dart';
// @Native DefaultAsset id). The crate is a sibling, so point cratePath at it.
void main(List<String> args) async {
await build(args, (input, output) async {
await _ensureRustTarget(input);
await RustBuilder(
assetName: 'src/ffi/bindings.g.dart',
cratePath: '../crates/immich_core_dart',
).run(input: input, output: output);
});
}
// rustup only auto-installs the rust-toolchain.toml targets when that file drives
// toolchain selection; with RUSTUP_TOOLCHAIN exported (mise does on CI) the file is
// bypassed and cross targets never install. Add the build target explicitly a
// fast no-op when it's already present.
Future<void> _ensureRustTarget(BuildInput input) async {
final code = input.config.code;
final triple = switch (code.targetOS) {
OS.android => switch (code.targetArchitecture) {
Architecture.arm => 'armv7-linux-androideabi',
Architecture.arm64 => 'aarch64-linux-android',
Architecture.x64 => 'x86_64-linux-android',
_ => null,
},
OS.iOS => switch ((code.targetArchitecture, code.iOS.targetSdk)) {
(Architecture.arm64, IOSSdk.iPhoneSimulator) => 'aarch64-apple-ios-sim',
(Architecture.arm64, _) => 'aarch64-apple-ios',
(Architecture.x64, _) => 'x86_64-apple-ios',
_ => null,
},
OS.macOS => switch (code.targetArchitecture) {
Architecture.arm64 => 'aarch64-apple-darwin',
Architecture.x64 => 'x86_64-apple-darwin',
_ => null,
},
OS.linux => switch (code.targetArchitecture) {
Architecture.arm64 => 'aarch64-unknown-linux-gnu',
Architecture.x64 => 'x86_64-unknown-linux-gnu',
_ => null,
},
_ => null,
};
if (triple == null) return;
final crate = input.packageRoot
.resolve('../crates/immich_core_dart/')
.toFilePath();
// best effort if rustup itself is broken the build below reports it properly
await Process.run('rustup', [
'target',
'add',
triple,
], workingDirectory: crate);
}

View file

@ -2,4 +2,5 @@ import 'ffi/bindings.g.dart' as bindings;
import 'ffi/ffi.dart';
/// Version baked into the native core. Cheap fine on the main isolate.
String coreVersion() => readAndFree(bindings.immich_core_version(), 'core_version');
String coreVersion() =>
readAndFree(bindings.immich_core_version(), 'core_version');

View file

@ -15,7 +15,10 @@ String sha1Hex(Uint8List bytes) {
final buf = malloc<Uint8>(len == 0 ? 1 : len);
try {
if (len > 0) buf.asTypedList(len).setAll(0, bytes);
return readAndFree(bindings.immich_core_sha1_hex(buf.cast(), len), 'sha1_hex');
return readAndFree(
bindings.immich_core_sha1_hex(buf.cast(), len),
'sha1_hex',
);
} finally {
malloc.free(buf);
}
@ -27,7 +30,10 @@ String sha1Hex(Uint8List bytes) {
String sha1File(String path) {
final cpath = path.toNativeUtf8();
try {
return readAndFree(bindings.immich_core_sha1_file(cpath.cast()), 'sha1_file');
return readAndFree(
bindings.immich_core_sha1_file(cpath.cast()),
'sha1_file',
);
} finally {
malloc.free(cpath);
}

View file

@ -7,7 +7,10 @@ import 'ffi/bindings.g.dart' as bindings;
/// True if [orientation] (EXIF) swaps width and height (the 90/270/transpose family).
bool orientationSwapsDims(int orientation) =>
orientation == 5 || orientation == 6 || orientation == 7 || orientation == 8;
orientation == 5 ||
orientation == 6 ||
orientation == 7 ||
orientation == 8;
/// Rotate an RGBA8888 image to the given EXIF [orientation], returning a freshly
/// packed buffer (dims swap for 90/270/transpose). [srcStride] is bytes per source
@ -15,7 +18,13 @@ bool orientationSwapsDims(int orientation) =>
///
/// The production caller is the platform decode pipeline (it has the locked native
/// bitmap); this Dart entry mirrors that path and is what the host tests exercise.
Uint8List? rotateRgba8888(Uint8List src, int srcStride, int width, int height, int orientation) {
Uint8List? rotateRgba8888(
Uint8List src,
int srcStride,
int width,
int height,
int orientation,
) {
final dw = orientationSwapsDims(orientation) ? height : width;
final dh = orientationSwapsDims(orientation) ? width : height;
final dstLen = dw * dh * 4;

View file

@ -15,6 +15,7 @@ dependencies:
sdk: flutter
ffi: ^2.2.0
# build-hook deps — run at build time to compile the Rust crate (need rustup).
code_assets: ^1.2.1
hooks: ^2.0.2
native_toolchain_rust: ^1.0.4