Files
eagle0/docs/RULES_APPLE_WORKSPACE_SEPARATION.md
7aee0ee789 Add documentation for rules_apple workspace separation (#5905)
Documents why SparklePlugin is built in a separate workspace due to
rules_swift version conflicts, and provides a checklist for when/how
to reintegrate it into the main workspace.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 11:09:36 -08:00

5.3 KiB

rules_apple Workspace Separation

This document explains why rules_apple is built in a separate Bazel workspace (sparkle_workspace/) and what conditions need to be met before it can be reintegrated into the main workspace.

Background

The main workspace cannot include rules_apple due to transitive dependency conflicts with rules_swift. Multiple dependencies require different major versions of rules_swift:

Dependency rules_swift Version Compatibility Level
grpc 3.x 3
flatbuffers 2.x 2
rules_apple 2.x 2

Bzlmod's single_version_override can force a single version, but compatibility levels 2 and 3 are incompatible. Forcing rules_swift 3.x (required for grpc) breaks rules_apple and flatbuffers.

Current Solution

The SparklePlugin (the only component requiring rules_apple) is built in an isolated workspace:

sparkle_workspace/
├── MODULE.bazel      # Minimal deps: apple_support, rules_apple, sparkle
├── BUILD.bazel       # Builds SparklePlugin.bundle
├── SparklePlugin.m   # Objective-C source
├── Info.plist        # Bundle metadata
└── external/
    └── BUILD.sparkle # Build file for Sparkle framework

How It Works

  1. Build script: scripts/build_sparkle_plugin.sh builds the plugin from the separate workspace
  2. Output: The built SparklePlugin.bundle is placed in Assets/Plugins/macOS/
  3. CI integration: mac_build.yml calls inject_sparkle.sh to embed Sparkle into the Mac app

The main workspace uses single_version_override for rules_swift 3.x to satisfy grpc, and includes a comment noting that rules_apple is intentionally excluded.

What SparklePlugin Does

SparklePlugin is a native macOS library that:

  • Initializes the Sparkle auto-update framework
  • Exposes C functions for Unity to call via P/Invoke:
    • SparklePlugin_Initialize
    • SparklePlugin_CheckForUpdates
    • SparklePlugin_CheckForUpdatesInBackground
    • SparklePlugin_IsCheckingForUpdates
    • SparklePlugin_GetAutomaticallyChecksForUpdates
    • SparklePlugin_SetAutomaticallyChecksForUpdates
    • SparklePlugin_IsRunningFromReadOnlyVolume
    • SparklePlugin_ShowDMGWarning

Conditions for Reintegration

To move rules_apple back into the main workspace, all of the following must be true:

1. rules_swift Version Alignment

Check if grpc, flatbuffers, and rules_apple all support the same rules_swift major version:

# Check what rules_swift version each dependency requires
bazel mod graph 2>&1 | grep -A2 "rules_swift"

Or check BCR directly:

Test: After updating versions, verify you can add this to MODULE.bazel without errors:

bazel_dep(name = "rules_apple", version = "X.Y.Z")

2. Build Test

If the dependency can be added, test that both the main build and SparklePlugin work:

# Main workspace builds
bazel build //src/main/scala/net/eagle0/eagle:eagle_server
bazel build //src/main/cpp/net/eagle0/shardok:shardok-server
bazel build //ci:eagle_server_image

# SparklePlugin builds (would move to main workspace)
bazel build //sparkle:SparklePlugin  # After moving files

3. Files to Move

When reintegrating, move these from sparkle_workspace/ to the main workspace:

Source Destination
sparkle_workspace/SparklePlugin.m src/main/objc/net/eagle0/sparkle/SparklePlugin.m
sparkle_workspace/Info.plist src/main/objc/net/eagle0/sparkle/Info.plist
sparkle_workspace/BUILD.bazel src/main/objc/net/eagle0/sparkle/BUILD.bazel
sparkle_workspace/external/BUILD.sparkle (inline into MODULE.bazel http_archive)

4. MODULE.bazel Changes

Add to the main MODULE.bazel:

bazel_dep(name = "rules_apple", version = "X.Y.Z", repo_name = "build_bazel_rules_apple")

# Sparkle framework
http_archive(
    name = "sparkle",
    build_file_content = """...""",  # Contents from external/BUILD.sparkle
    sha256 = "...",
    url = "https://github.com/sparkle-project/Sparkle/releases/download/...",
)

Remove the single_version_override for rules_swift if no longer needed.

5. Update Build Scripts

  • Update scripts/build_sparkle_plugin.sh to build from main workspace
  • Update scripts/build_plugins.sh if it references the separate workspace
  • Verify mac_build.yml still works

6. Cleanup

After successful integration:

rm -rf sparkle_workspace/

Update comments in MODULE.bazel that reference the separate workspace.

Version History

Date Event
2026-02-04 Separated sparkle_workspace (PR #5882) to enable Bazel 8 upgrade
2026-02-05 Upgraded to Bazel 8.5.1 (PR #5883)

Monitoring

Periodically check if the upstream dependencies have aligned:

  1. grpc releases: https://github.com/grpc/grpc/releases
  2. flatbuffers releases: https://github.com/google/flatbuffers/releases
  3. rules_apple releases: https://github.com/bazelbuild/rules_apple/releases
  4. BCR updates: https://registry.bazel.build/

When a new version of any of these is released, check if the rules_swift requirements have converged.