Skip to content

feat: support module_version for add-to-app releases#121

Open
eseidel wants to merge 7 commits intoadd-build-tracefrom
feat/aar-release-version
Open

feat: support module_version for add-to-app releases#121
eseidel wants to merge 7 commits intoadd-build-tracefrom
feat/aar-release-version

Conversation

@eseidel
Copy link
Copy Markdown

@eseidel eseidel commented Apr 2, 2026

Summary

  • Flutter tool: Read SHOREBIRD_MODULE_VERSION env var in compileShorebirdYaml() and write module_version into the compiled shorebird.yaml (same pattern as SHOREBIRD_PUBLIC_KEY)
  • Engine: No changes to release_version handling — host app version passes through unchanged
  • Updater: Parse module_version from shorebird.yaml, add to UpdateConfig and PatchCheckRequest as a separate optional field sent alongside release_version

Context

Part of shorebirdtech/shorebird#793

release_version always stays the host app's version. module_version is a separate field used for patch lookup in add-to-app releases where the module's identity is independent of the host app.

Companion PRs:

Test plan

  • Existing Flutter tools tests pass
  • Existing engine tests pass
  • Verify module_version appears in compiled yaml when env var is set
  • Verify compiled yaml unchanged when env var is absent

eseidel added 5 commits April 2, 2026 10:43
When shorebird.yaml contains a release_version field, use it as
the release version instead of the host app's version+versionCode.

This enables add-to-app (AAR/iOS framework) releases where the
module's identity needs to be independent of the host app's version.
The CLI injects this field during `shorebird release aar` builds.

Falls back to existing behavior when release_version is absent,
so this is fully backwards-compatible.

Part of shorebirdtech/shorebird#793
When the SHOREBIRD_RELEASE_VERSION environment variable is set,
write it as release_version into the compiled shorebird.yaml.
This follows the same pattern as SHOREBIRD_PUBLIC_KEY.

The Shorebird CLI sets this env var during `shorebird release aar`
builds. The engine reads release_version from the compiled yaml
and uses it instead of the host app's version for patch checking.

Part of shorebirdtech/shorebird#793
The concept applies to both AAR and iOS framework releases —
module_version is the platform-agnostic name for the version
of an embeddable Flutter module.
@eseidel
Copy link
Copy Markdown
Author

eseidel commented Apr 2, 2026

Design discussion: module_version vs release_version in the protocol

The current approach in this PR works by having the engine substitute module_version (from shorebird.yaml) into the release_version field that gets passed to the updater. This means:

  • Pro: No updater (Rust) changes needed — the updater already receives release_version as a string and doesn't care where it came from.
  • Pro: No server/database changes needed — release version is just an opaque string.

However, this means the host app's actual version is thrown away. The server has no way to distinguish a module version (git hash) from an app version, and can't report which host app versions are running a given module.

Alternative: plumb module_version as a separate field

Instead of overriding release_version, the engine could pass both values to the updater:

  • release_version — always the host app's version (from PackageInfo)
  • module_version — from shorebird.yaml, nullable

The updater would then send both in the PatchCheckRequest. The server would look up patches by module_version when present, falling back to release_version. The host app version could be stored for analytics.

This requires touching more code:

  • Updater (Rust): Add module_version to AppConfig, PatchCheckRequest, and the check logic
  • Server: Update patch lookup to prefer module_version over release_version
  • Protocol: Add module_version field to PatchCheckRequest
  • Engine (C++): Pass module_version as a separate field rather than overriding release_version

But avoids future problems:

  • No polluted release_version data (git hashes mixed with semver app versions)
  • Host app version still available for analytics/debugging
  • No protocol migration needed later if we want both values
  • Cleaner semantics — each field means exactly one thing

Recommendation

The current PR is a valid MVP, but we're leaning toward plumbing module_version as a separate field through the full stack (updater → server → protocol) to keep the data clean. This PR's engine + Flutter tool changes would still be needed either way — the difference is whether the engine overrides release_version (current approach) or passes module_version alongside it.

Leaving this here for discussion before we decide which path to take.

Instead of overriding release_version in the engine, pass
module_version as a separate optional field through the full stack:

- YamlConfig: parse module_version from shorebird.yaml
- UpdateConfig: propagate module_version
- PatchCheckRequest: send module_version alongside release_version
- Engine C++: revert release_version override, pass host app
  version through unchanged

The server uses module_version for patch lookup when present,
while release_version always contains the host app's version
for analytics. This avoids polluting release_version data with
git hashes from module releases.

Part of shorebirdtech/shorebird#793
@eseidel eseidel marked this pull request as ready for review April 2, 2026 22:25
@eseidel eseidel requested a review from bdero April 2, 2026 22:25
@eseidel eseidel changed the title feat: read release_version from shorebird.yaml for add-to-app feat: support module_version for add-to-app releases Apr 2, 2026
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