Skip to content

Add multi-arch workflow - #426

Merged
DropSnorz merged 1 commit into
masterfrom
ci/multi-arch
Jan 18, 2026
Merged

DropSnorz merged 1 commit into
masterfrom
ci/multi-arch

Conversation

@DropSnorz

Copy link
Copy Markdown
Owner

Relates to #409

@coderabbitai

coderabbitai Bot commented Jan 12, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This PR updates build packaging scripts with platform-aware output naming, introduces an OSUtils utility class for centralized platform detection, refactors LibraryLoader to simplify the library loading API, and bumps version numbers to 1.6.0 with VS2022 exporter support.

Changes

Cohort / File(s) Summary
Build Script Updates
build/package-appimage.sh, build/package-deb.sh, build/package-dmg.sh, build/package-msi.cmd
Rename owlplugversion to owlplug_version, introduce target_platform parameter from build arguments, update all references and echo messages, modify output filenames to include platform (e.g., OwlPlug-${owlplug_version}-${target_platform}.deb)
Java Library Loading Refactoring
owlplug-host/src/main/java/com/owlplug/host/io/LibraryLoader.java
Simplify public API from load(String, Class, boolean) to load(String, Class<?>), extract helper methods (tryLoadByName, tryLoadByPath, extractAndLoad), migrate to NIO (Path/Files) for resource extraction, make class final with private constructor
JNI Plugin Integration
owlplug-host/src/main/java/com/owlplug/host/loaders/jni/JNIPluginMapper.java
Import and use OSUtils for platform tag generation in LIB_ID, simplify library loading call to remove explicit false parameter
Embedded Scanner Updates
owlplug-host/src/main/java/com/owlplug/host/loaders/EmbeddedScannerPluginLoader.java
Replace FileSystemUtils with OSUtils for POSIX checks, remove platform-specific extension logic, source platform tag from OSUtils, update logging to use placeholder formatting
Platform Utilities
owlplug-host/src/main/java/com/owlplug/host/utils/OSUtils.java
New utility class providing getPlatformTagName(), getOSTagName(), getArchTagName(), isPosixFileSystem() for cross-platform detection and architecture normalization
Removed Utility
owlplug-host/src/main/java/com/owlplug/host/utils/FileSystemUtils.java
Delete deprecated utility class; functionality superseded by OSUtils.isPosixFileSystem()
Version and Configuration
owlplug-host/src/main/juce/JuceLibraryCode/JuceHeader.h, owlplug-host/src/main/juce/OwlPlugHost.jucer, owlplug-host/src/main/resources/owlplug-host.version, owlplug-host/src/main/resources/owlplug-scanner.version
Bump versions from 1.5.0 to 1.6.0 (scanner: 0.3.0 to 0.4.0), add VS2022 exporter configuration with deprecation note on VS2019, update JUCE project metadata

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Add multi-arch workflow' is vague and generic; it does not convey meaningful information about what multi-arch changes are being made or why. Consider using a more descriptive title that clarifies the specific multi-arch improvements, such as 'Add platform-specific packaging and version tagging' or 'Refactor build scripts for multi-platform support'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The description 'Relates to #409' is minimal but indicates connection to an issue, showing some relationship to the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@DropSnorz
DropSnorz force-pushed the ci/multi-arch branch 9 times, most recently from 3c74cb5 to bab6097 Compare January 12, 2026 23:27
@DropSnorz DropSnorz self-assigned this Jan 12, 2026
@DropSnorz
DropSnorz force-pushed the ci/multi-arch branch 2 times, most recently from 637cdb2 to 034128e Compare January 13, 2026 22:16
@DropSnorz

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jan 13, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
owlplug-host/src/main/java/com/owlplug/host/loaders/EmbeddedScannerPluginLoader.java (1)

47-47: Logger initialized with wrong class.

The logger is using LibraryLoader.class instead of EmbeddedScannerPluginLoader.class. This will cause log messages to be attributed to the wrong class, making debugging more difficult.

Proposed fix
-  private static final Logger log = LoggerFactory.getLogger(LibraryLoader.class);
+  private static final Logger log = LoggerFactory.getLogger(EmbeddedScannerPluginLoader.class);
🤖 Fix all issues with AI agents
In @build/package-appimage.sh:
- Around line 3-4: The script defines owlplug_version and target_platform but
never uses target_platform when producing the AppImage; update the packaging
step (the part invoking appimagetool / producing the .AppImage) to rename the
generated artifact to include the platform tag (e.g., append or insert
${target_platform} into the filename) or pass target_platform into the
appimagetool output name so the final .AppImage filename matches the DEB/MSI
pattern; locate the variable usages (owlplug_version and target_platform) in
build/package-appimage.sh and add a post-build mv/rename or adjust the
appimagetool output argument to produce an artifact named with
${owlplug_version}-${target_platform}.AppImage.
🧹 Nitpick comments (6)
build/package-msi.cmd (1)

23-24: Consider adding error handling for the rename operation.

If jpackage fails or produces an unexpected filename, the move command will fail silently. Consider adding validation or if exist checks.

💡 Optional improvement
-move ./output/OwlPlug-%owlplug-version%.msi ./output/OwlPlug-%owlplug-version%-%target-platform%.msi
+if exist "./output/OwlPlug-%owlplug-version%.msi" (
+  move ./output/OwlPlug-%owlplug-version%.msi ./output/OwlPlug-%owlplug-version%-%target-platform%.msi
+) else (
+  echo ERROR: MSI file not found
+  exit /b 1
+)
owlplug-host/src/main/java/com/owlplug/host/utils/OSUtils.java (1)

24-34: Consider making this a proper utility class.

Utility classes with only static methods should typically be final with a private constructor to prevent instantiation and subclassing.

💡 Suggested improvement
-public class OSUtils {
+public final class OSUtils {
+
+  private OSUtils() {
+    // Utility class
+  }
 
   public static String getPlatformTagName() {
owlplug-host/src/main/java/com/owlplug/host/loaders/EmbeddedScannerPluginLoader.java (1)

233-242: Clarify or remove dead code.

getPlatformExecutableExtension() now unconditionally returns an empty string for all platforms. If platform-specific extensions are no longer needed, consider removing this method entirely and using an empty string literal directly, or document why it's kept as a placeholder.

owlplug-host/src/main/java/com/owlplug/host/loaders/jni/JNIPluginMapper.java (1)

41-46: Singleton pattern is not thread-safe.

The getInstance() method lacks synchronization, which could result in multiple instances being created if called concurrently from different threads. While this may be acceptable if init() is always called from a single thread, consider using double-checked locking or an enum-based singleton for safety.

Example thread-safe singleton
+  private static final Object LOCK = new Object();
+
   public static JNIPluginMapper getInstance() {
     if (INSTANCE == null) {
-      INSTANCE = new JNIPluginMapper();
+      synchronized (LOCK) {
+        if (INSTANCE == null) {
+          INSTANCE = new JNIPluginMapper();
+        }
+      }
     }
     return INSTANCE;
   }
build/package-dmg.sh (2)

3-4: Add input validation for required parameters.

The script will fail or produce unexpected results if owlplug_version or target_platform are not provided. Consider adding validation at the start of the script.

Proposed validation
 echo "Preparing package"

 owlplug_version=$1
 target_platform=$2
+
+if [ -z "$owlplug_version" ] || [ -z "$target_platform" ]; then
+  echo "Usage: $0 <version> <target_platform>"
+  exit 1
+fi

16-21: Quote variables to handle edge cases.

While unlikely in this context, unquoted variables can cause issues with special characters or spaces. Quoting ${owlplug_version} and ${target_platform} in the mv command and jpackage arguments would be safer.

Proposed fix
-jpackage --input ./input/ --name OwlPlug --main-class org.springframework.boot.loader.launch.JarLauncher \
---main-jar owlplug.jar --license-file ./input/LICENSE --dest ./output \
---app-version ${owlplug_version} --icon ./resources/owlplug.icns --vendor OwlPlug \
---mac-package-identifier owlplug --mac-package-name OwlPlug
+jpackage --input ./input/ --name OwlPlug --main-class org.springframework.boot.loader.launch.JarLauncher \
+--main-jar owlplug.jar --license-file ./input/LICENSE --dest ./output \
+--app-version "${owlplug_version}" --icon ./resources/owlplug.icns --vendor OwlPlug \
+--mac-package-identifier owlplug --mac-package-name OwlPlug

-mv  ./output/OwlPlug-${owlplug_version}.dmg ./output/OwlPlug-${owlplug_version}-${target_platform}.dmg
+mv  "./output/OwlPlug-${owlplug_version}.dmg" "./output/OwlPlug-${owlplug_version}-${target_platform}.dmg"
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 66dc67e and 034128e.

⛔ Files ignored due to path filters (1)
  • .github/workflows/main.yml is excluded by !**/*.yml
📒 Files selected for processing (13)
  • build/package-appimage.sh
  • build/package-deb.sh
  • build/package-dmg.sh
  • build/package-msi.cmd
  • owlplug-host/src/main/java/com/owlplug/host/io/LibraryLoader.java
  • owlplug-host/src/main/java/com/owlplug/host/loaders/EmbeddedScannerPluginLoader.java
  • owlplug-host/src/main/java/com/owlplug/host/loaders/jni/JNIPluginMapper.java
  • owlplug-host/src/main/java/com/owlplug/host/utils/FileSystemUtils.java
  • owlplug-host/src/main/java/com/owlplug/host/utils/OSUtils.java
  • owlplug-host/src/main/juce/JuceLibraryCode/JuceHeader.h
  • owlplug-host/src/main/juce/OwlPlugHost.jucer
  • owlplug-host/src/main/resources/owlplug-host.version
  • owlplug-host/src/main/resources/owlplug-scanner.version
💤 Files with no reviewable changes (1)
  • owlplug-host/src/main/java/com/owlplug/host/utils/FileSystemUtils.java
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2024-07-26T20:55:41.458Z
Learnt from: DropSnorz
Repo: DropSnorz/OwlPlug PR: 225
File: build/OwlPlug.AppDir/AppRun:1-6
Timestamp: 2024-07-26T20:55:41.458Z
Learning: The `AppRun` script used in the OwlPlug AppImage is the default script from the AppImages repository, and despite not being POSIX compliant, it is used for consistency and compatibility reasons.

Applied to files:

  • build/package-appimage.sh
📚 Learning: 2025-11-03T18:35:06.941Z
Learnt from: DropSnorz
Repo: DropSnorz/OwlPlug PR: 359
File: owlplug-client/src/main/java/com/owlplug/plugin/tasks/PluginScanTask.java:104-113
Timestamp: 2025-11-03T18:35:06.941Z
Learning: In OwlPlug's PluginScanTask (owlplug-client/src/main/java/com/owlplug/plugin/tasks/PluginScanTask.java), all plugin paths are absolute paths, never relative, as they are normalized via FileUtils.convertPath before being stored or used as directory scopes.

Applied to files:

  • owlplug-host/src/main/java/com/owlplug/host/loaders/EmbeddedScannerPluginLoader.java
  • owlplug-host/src/main/java/com/owlplug/host/loaders/jni/JNIPluginMapper.java
  • owlplug-host/src/main/java/com/owlplug/host/io/LibraryLoader.java
🧬 Code graph analysis (2)
owlplug-host/src/main/java/com/owlplug/host/loaders/EmbeddedScannerPluginLoader.java (1)
owlplug-host/src/main/java/com/owlplug/host/utils/OSUtils.java (1)
  • OSUtils (24-72)
owlplug-host/src/main/java/com/owlplug/host/loaders/jni/JNIPluginMapper.java (3)
owlplug-host/src/main/java/com/owlplug/host/utils/OSUtils.java (1)
  • OSUtils (24-72)
owlplug-host/src/main/java/com/owlplug/host/io/ClassPathVersionUtils.java (1)
  • ClassPathVersionUtils (27-59)
owlplug-host/src/main/java/com/owlplug/host/io/LibraryLoader.java (1)
  • LibraryLoader (38-111)
🪛 Shellcheck (0.11.0)
build/package-appimage.sh

[warning] 4-4: target_platform appears unused. Verify use (or export if used externally).

(SC2034)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: build-host-linux (linux-x64)
  • GitHub Check: build-host-win (win-x64)
  • GitHub Check: build-host-osx (osx-arm64)
  • GitHub Check: build-host-osx (osx-x64)
🔇 Additional comments (18)
owlplug-host/src/main/resources/owlplug-scanner.version (1)

1-1: LGTM!

Version bump to 0.4.0 aligns with the project-wide version updates for multi-arch support.

build/package-msi.cmd (1)

3-5: LGTM!

The target-platform parameter is properly captured and used to tag the MSI output filename, aligning with the multi-arch naming convention across other packaging scripts.

build/package-deb.sh (1)

3-4: LGTM!

Variables are properly defined and the syntax is consistent with shell best practices.

owlplug-host/src/main/java/com/owlplug/host/utils/OSUtils.java (2)

47-65: LGTM!

The architecture detection logic handles common os.arch values well, including:

  • x86_64/amd64 → x64
  • i386-i686/x86 → x32
  • aarch64/arm64 → arm64
  • arm/arm32 → arm32

The null check and lowercase normalization are good defensive practices.


67-72: LGTM on the POSIX detection.

Using FileSystems.getDefault().supportedFileAttributeViews() is a reliable way to detect POSIX filesystem support.

Minor: There's an extra blank line before the closing brace (line 71).

owlplug-host/src/main/java/com/owlplug/host/loaders/EmbeddedScannerPluginLoader.java (1)

95-102: LGTM!

The switch from FileSystemUtils.isPosix() to OSUtils.isPosixFileSystem() is consistent with the centralization effort in this PR. The POSIX permission handling logic remains correct.

owlplug-host/src/main/resources/owlplug-host.version (1)

1-1: LGTM!

Version bump to 1.6.0 is consistent with the JuceHeader.h changes and aligns with the multi-arch workflow release.

owlplug-host/src/main/java/com/owlplug/host/loaders/jni/JNIPluginMapper.java (2)

31-32: Same empty platform tag concern as EmbeddedScannerPluginLoader.

If OSUtils.getPlatformTagName() returns an empty string, LIB_ID will be malformed with a trailing hyphen (e.g., owlplug-host-1.6.0-). This mirrors the issue in EmbeddedScannerPluginLoader and should be handled consistently across both classes.


48-52: LGTM!

The updated LibraryLoader.load() call aligns with the simplified API. The guard against re-loading an already loaded library is correct.

owlplug-host/src/main/juce/JuceLibraryCode/JuceHeader.h (1)

49-50: LGTM!

Version bump to 1.6.0 is correctly reflected in both versionString and versionNumber (0x10600). The hex encoding follows JUCE's convention of major/minor/patch in byte pairs.

owlplug-host/src/main/java/com/owlplug/host/io/LibraryLoader.java (5)

38-46: LGTM - Good utility class pattern.

Making the class final with a private constructor correctly enforces non-instantiability. The fail-fast behavior from platformExtension() during static initialization is appropriate for early detection of unsupported platforms.


48-55: Clean loading flow with sensible fallback chain.

The three-step approach (system library path → cached temp file → extract from classpath) is well-structured and provides good resilience. The API simplification from throwOnFailure to a boolean return is cleaner.


57-81: LGTM - Well-implemented loading helpers.

Proper distinction between System.loadLibrary (name-based) and System.load (path-based), with appropriate existence checks and logging levels.


83-101: Good use of NIO for resource extraction.

Clean implementation with proper try-with-resources and null checks. The REPLACE_EXISTING option appropriately handles stale temp files from previous runs.

One minor consideration: if multiple JVMs or threads simultaneously extract and load the same library, there's a small race window between Files.copy completing and tryLoadByPath executing where another process could overwrite the file. In practice, this is unlikely during typical single-threaded startup scenarios.


103-110: LGTM - Correct platform extension mapping.

The extension mappings are accurate for each platform, and throwing UnsupportedOperationException provides clear fail-fast behavior for unsupported operating systems.

owlplug-host/src/main/juce/OwlPlugHost.jucer (3)

3-5: LGTM!

Version bump to 1.6.0 aligns with the broader version updates across the project.


57-58: Good deprecation practice.

Retaining VS2019 for backward compatibility while clearly signaling the migration path to VS2022 is a sensible approach. The deprecation note is clear and actionable.


78-97: VS2022 exporter configuration is complete and correct.

The exporter is properly configured with the appropriate target folder, header paths, and module paths, mirroring the VS2019 structure. All 10 JUCE modules are included consistently with other exporters. VS2022 exporter support has been available in JUCE since version 6.1.3.

Comment thread build/package-appimage.sh Resolved
Comment thread build/package-deb.sh Resolved
@DropSnorz

DropSnorz commented Jan 18, 2026 •

Copy link
Copy Markdown
Owner Author

Issues:

  • win-x64 installer not collected by workflow
  • osx-arm64 scanner binary not found in classpath at runtime

@DropSnorz
DropSnorz merged commit bc6f8db into master Jan 18, 2026
17 checks passed
@DropSnorz DropSnorz added this to the 1.32.0 milestone Jan 27, 2026
@DropSnorz
DropSnorz deleted the ci/multi-arch branch September 14, 2026 20:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant