Skip to content

Add pre-built bundle publishing support for native apps#436

Merged
shannah merged 13 commits intomasterfrom
claude/plan-bundle-publishing-z16B4
Mar 13, 2026
Merged

Add pre-built bundle publishing support for native apps#436
shannah merged 13 commits intomasterfrom
claude/plan-bundle-publishing-z16B4

Conversation

@shannah
Copy link
Copy Markdown
Owner

@shannah shannah commented Mar 13, 2026

Summary

This PR adds support for building and publishing pre-built native app bundles (.exe, .app, Linux binaries) at publish time, allowing users to download ready-to-run applications directly instead of waiting for the installer to bundle them.

Key Changes

  • PublishBundleService: New service that builds platform-specific native bundles during publish and wraps them in JAR files for distribution. Reads enabled platforms from jdeploy.artifacts in package.json and builds both GUI and CLI variants (CLI only for Windows).

  • Bundle Models: Added BundleArtifact and BundleManifest classes to represent and manage collections of built bundle artifacts with metadata (platform, arch, version, SHA-256 hash, download URL).

  • Upload Routing:

    • BundleUploadRouter routes bundle uploads to appropriate destinations (S3 or GitHub releases) based on configuration
    • BundleChecksumWriter writes bundle URLs and SHA-256 hashes into the published package.json
  • S3 Support:

    • S3Config reads S3 configuration from environment variables (JDEPLOY_S3_BUCKET, JDEPLOY_S3_REGION, JDEPLOY_S3_PREFIX)
    • S3BundleUploader uploads bundles to S3 using AWS Signature Version 4 (no AWS SDK dependency)
    • S3RequestSigner handles request signing for S3 REST API calls
  • Driver Integration: Updated GitHubPublishDriver and NPMPublishDriver to integrate bundle publishing into their publish workflows, with fallback to GitHub releases when S3 is not configured.

  • Comprehensive Tests:

    • BundlePublishMockNetworkTest verifies end-to-end bundle publishing pipeline with real BundleUploadRouter and BundleChecksumWriter but mocked PublishBundleService
    • PublishBundleServiceTest validates bundle building logic, platform selection, and CLI-only-for-Windows behavior

Implementation Details

  • Bundle JARs follow naming convention: {fqpn}-{platform}-{arch}-{version}[-cli].jar
  • Each native bundle is wrapped as the sole entry in a JAR for portable distribution and integrity verification
  • Bundle metadata is recorded in jdeploy.bundles section of published package.json with URLs and SHA-256 hashes
  • CLI bundles are only built for Windows platforms (macOS includes CLI binary inside the .app bundle)
  • S3 is optional; GitHub releases are used as fallback for GitHub targets when S3 is not configured
  • NPM targets require S3 configuration (NPM registry doesn't host arbitrary assets)

https://claude.ai/code/session_01QwiNyMDsuXcg6pyPUCMJDt

claude added 13 commits March 13, 2026 02:15
Add support for building platform-specific native bundles (.exe, .app,
Linux binary) at publish time and uploading them as downloadable
artifacts. Enabled via `publishBundles: true` in package.json jdeploy config.

New classes:
- BundleArtifact/BundleManifest: models for bundle artifact metadata
- PublishBundleService: builds native bundles and wraps in JARs with SHA-256
- S3BundleUploader/S3Config/S3RequestSigner: S3 upload with AWS Sig V4
- BundleUploadRouter: routes uploads to S3 or GitHub releases
- BundleChecksumWriter: writes bundle URLs/hashes to package.json

Modified:
- GitHubPublishDriver: integrates bundle building in prepare()
- NPMPublishDriver: integrates bundle building in prepare()

https://claude.ai/code/session_01QwiNyMDsuXcg6pyPUCMJDt
…ished manifest

Avoid conflict with the existing jdeploy.bundles array (which declares
which platform bundles to build). The published manifest with download
URLs and checksums is now written under jdeploy.publishedBundles.

https://claude.ai/code/session_01QwiNyMDsuXcg6pyPUCMJDt
Add installer support for downloading pre-built native bundles from
jdeploy.artifacts in package.json. When artifacts are available for the
current platform, the installer downloads and verifies the JAR (SHA-256)
instead of running Bundler.runit(), with graceful fallback to local
generation on failure.

Also restricts CLI bundle generation to Windows only, since macOS
includes the CLI binary inside the .app bundle.

https://claude.ai/code/session_01QwiNyMDsuXcg6pyPUCMJDt
Revert installer changes (PreBuiltBundleDownloader, Main.install(),
NPMPackageVersion artifact methods). Bundle downloading will be
implemented in a separate ticket. This PR only covers publishing.

https://claude.ai/code/session_01QwiNyMDsuXcg6pyPUCMJDt
Add mock PublishBundleService, BundleUploadRouter, and
BundleChecksumWriter to GitHubPublishDriver and NPMPublishDriver
test constructors to match the updated signatures.

https://claude.ai/code/session_01QwiNyMDsuXcg6pyPUCMJDt
Tests verify that:
- CLI bundles are only built for Windows platforms (not Mac/Linux)
- GUI bundles are built for all configured platforms
- No CLI bundles when no commands are defined
- publishBundles flag correctly enables/disables the feature
- Artifact filenames follow naming convention with SHA-256 hashes
- BundleManifest.toPackageJsonBundles() only includes cli sub-object
  for Windows entries

Uses MockedStatic<Bundler> to intercept Bundler.runit() calls and
verify the correct targets and CLI mode flags are passed.

https://claude.ai/code/session_01QwiNyMDsuXcg6pyPUCMJDt
Replace the publishBundles boolean + downloadPage.platforms approach
with jdeploy.artifacts entries. Users seed artifact entries with
"enabled": true to declare which platforms to build:

  "artifacts": {
    "mac-arm64": { "enabled": true },
    "win-x64": { "enabled": true }
  }

At publish time, url and sha256 are merged into the existing entries,
preserving the enabled flag and any other user-defined fields.

Changes:
- PublishBundleService reads platform list from jdeploy.artifacts keys
  with enabled: true (no longer depends on DownloadPageSettingsService)
- BundleChecksumWriter merges built data into existing artifact entries
  instead of replacing the entire artifacts object
- Tests updated for new artifacts-based configuration

https://claude.ai/code/session_01QwiNyMDsuXcg6pyPUCMJDt
BaseMockNetworkPublishingTest and MockNetworkPublishingTest were missing
the PublishBundleService, BundleUploadRouter, and BundleChecksumWriter
parameters added to GitHubPublishDriver and NPMPublishDriver constructors.

https://claude.ai/code/session_01QwiNyMDsuXcg6pyPUCMJDt
Verifies that the bundle publishing pipeline produces correct artifacts:
- Bundle JARs are copied to GitHub release files directory
- SHA-256 checksums and download URLs are written to publish package.json
- Bundle metadata propagates into package-info.json version entries
- Full prepare+publish flow uploads bundle assets to GitHub
- No bundle artifacts when publishing is disabled
- Release dir package.json gets matching checksums
- Enabled flag is preserved alongside url/sha256 fields

Uses real BundleUploadRouter and BundleChecksumWriter with mocked
PublishBundleService to test the integration surface without requiring
native bundling toolchains.

https://claude.ai/code/session_01QwiNyMDsuXcg6pyPUCMJDt
@shannah shannah merged commit 7009416 into master Mar 13, 2026
17 checks passed
@shannah shannah deleted the claude/plan-bundle-publishing-z16B4 branch March 13, 2026 16:59
shannah pushed a commit that referenced this pull request Mar 13, 2026
Add rfc/bundle-publishing-spec.md as the canonical source of truth for the
package.json artifacts schema introduced in PR #436. This spec defines the
exact structure that external projects should use to detect whether pre-built
app bundles exist, including platform keys, field reference, detection
algorithm, naming conventions, and integrity verification.

https://claude.ai/code/session_015WNb4G3Wb6cxatBZCkg2b7
shannah added a commit that referenced this pull request Mar 13, 2026
* docs: add RFC spec for pre-built app bundle publishing

Add rfc/bundle-publishing-spec.md as the canonical source of truth for the
package.json artifacts schema introduced in PR #436. This spec defines the
exact structure that external projects should use to detect whether pre-built
app bundles exist, including platform keys, field reference, detection
algorithm, naming conventions, and integrity verification.

https://claude.ai/code/session_015WNb4G3Wb6cxatBZCkg2b7

* docs: add detailed bundle JAR contents to RFC spec

Expand the Bundle JAR Contents section with full directory trees for each
platform (macOS .app structure, Windows .exe, Linux ELF), describe the
embedded app.xml manifest, and clarify what bundles do not include.

https://claude.ai/code/session_015WNb4G3Wb6cxatBZCkg2b7

---------

Co-authored-by: Claude <noreply@anthropic.com>
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.

2 participants