Use the following tools to create an installer or package for your Makepad application.
cargo-packager and robius-packaging-commands are used under the hood to create the packages.
cargo-makepad is used to build the mobile applications for iOS and Android platforms.
Note: that due to platform restrictions, you can currently only build:
- Linux packages on a Linux OS machine
- Windows installer executables on a Windows OS machine
- macOS disk images / app bundles on a macOS machine
- iOS apps on a macOS machine.
- Android, on a machine with any OS!
- One-step packaging for Makepad desktop and mobile targets
- GitHub Release upload with optional tag/name/body templating
- Sensible defaults sourced from
Cargo.toml - Matrix-friendly usage (pass
argsto target specific triples)
These inputs are already defined in action.yaml:
args: extra args passed to build commands (e.g.--release --target x86_64-unknown-linux-gnu)packager_formats: comma-separated formats forcargo packager(e.g.deb,dmg,nsis)packager_args: extra args passed only tocargo packagertagName: GitHub Release tag, supports__VERSION__placeholder. If omitted and the workflow runs on a tag ref, that tag is used.releaseName: Release title, supports__VERSION__placeholderreleaseBody: Release body markdownreleaseId: existing GitHub Release ID (uploads assets to this release and skips release creation)releaseCommitish: branch/commit SHA for creating tag/release (default: current commit SHA)upload_updater_json: upload/updatelatest.jsonupdater metadata asset on the release (default:true)uploadUpdaterJson: alias ofupload_updater_jsonuploadUpdaterSignatures: upload.sigfiles (if present next to built assets) and include signatures inlatest.json(default:true)updaterJsonPreferNsis: for Windows updater default key, prefer NSIS (.exe) over MSI (.msi) when both exist (default:false, meaning MSI preferred)retryAttempts: additional retry attempts for release-asset/latest.json upload conflicts (default:0)owner: release target repository owner (default: current repo owner)repo: release target repository name (default: current repo name)githubBaseUrl: custom GitHub API base URL (for GHE/self-hosted APIs)generateReleaseNotes: use GitHub generated release notes when creating a release (default:false)releaseAssetNamePattern: pattern naming for uploaded assets, supports[app] [name] [version] [platform] [arch] [mode] [ext] [filename] [basename]asset_name_template: template for asset names (__APP__,__VERSION__,__PLATFORM__,__ARCH__,__MODE__,__EXT__,__FILENAME__,__BASENAME__)asset_prefix: optional prefix prepended to generated asset namesreleaseDraft: create draft release (true/false)prerelease: mark as prerelease (true/false)github_token: token for release creation/upload (defaults to envGITHUB_TOKEN)project_path: Makepad project root (default:.)projectPath: alias ofproject_pathapp_name: override app name (auto fromCargo.tomlif omitted)app_version: override version (auto fromCargo.tomlif omitted)identifier: override bundle identifierinclude_release: include release build (default:true)include_debug: include debug build (default:false)
Mobile and signing configuration is provided via env vars only:
-
MAKEPAD_ANDROID_ABI: Android ABI override (x86_64,aarch64,armv7,i686), defaultaarch64 -
MAKEPAD_ANDROID_FULL_NDK: install full Android NDK (true/false), defaultfalse -
MAKEPAD_ANDROID_VARIANT: Android build variant (default,quest), defaultdefault -
MAKEPAD_MOBILE_CARGO_EXTRA_ARGS: extra args appended to both iOS and Androidcargo makepadbuild commands -
MAKEPAD_ANDROID_CARGO_EXTRA_ARGS: extra args appended only to Androidcargo makepadbuild commands -
MAKEPAD_IOS_ORG: iOS org identifier (e.g.com.example) -
MAKEPAD_IOS_APP: iOS app name -
MAKEPAD_IOS_PROFILE: provisioning profile UUID or path (optional, auto-derived when Apple envs are set) -
MAKEPAD_IOS_CERT: signing certificate fingerprint (optional, auto-derived when Apple envs are set) -
MAKEPAD_IOS_SIM: build for iOS simulator (true/false), defaultfalse -
MAKEPAD_IOS_CREATE_IPA: create IPA from .app bundle (true/false), defaultfalse -
MAKEPAD_IOS_UPLOAD_TESTFLIGHT: upload IPA to TestFlight (true/false), defaultfalse -
MAKEPAD_IOS_CARGO_EXTRA_ARGS: extra args appended only to iOScargo makepadbuild commands -
APPLE_CERTIFICATE: base64-encoded Apple signing certificate (.p12) -
APPLE_CERTIFICATE_PASSWORD: password for the certificate -
APPLE_PROVISIONING_PROFILE: base64-encoded provisioning profile (.mobileprovision) -
APPLE_KEYCHAIN_PASSWORD: password for the temporary keychain -
APPLE_SIGNING_IDENTITY: signing identity common name used to locate the certificate (default:Apple Distribution)
For faster mobile CI builds (mirroring robrix#729), you can pass Cargo profile overrides:
env:
MAKEPAD_MOBILE_CARGO_EXTRA_ARGS: >-
--config profile.dev.opt-level=0
--config profile.dev.debug=false
--config profile.dev.lto=off
--config profile.dev.strip=true
--config profile.dev.debug-assertions=falseCommon commands used by the action:
# Install toolchain
cargo makepad apple ios install-toolchain
# Run on simulator
cargo makepad apple ios --org=org.example --app=MyApp run-sim -p my-app --release
# Run on device (requires provisioning profile)
cargo makepad apple ios --org=org.example --app=MyApp run-device -p my-app --release
# List certificates/profiles/devices
cargo makepad apple listiOS device builds require a provisioning profile. Create an empty app in Xcode with the
same organization and product names you plan to use (no spaces or unusual characters),
then run it on a real device at least once so the profile is generated. Use those values
for MAKEPAD_IOS_ORG and MAKEPAD_IOS_APP.
If you have multiple signing identities or profiles, set MAKEPAD_IOS_PROFILE and
MAKEPAD_IOS_CERT (or provide APPLE_SIGNING_IDENTITY so the action can select the right cert).
The action uses --device=iPhone for device builds.
To upload to TestFlight, set MAKEPAD_IOS_UPLOAD_TESTFLIGHT=true and provide:
APP_STORE_CONNECT_API_KEY(orAPP_STORE_CONNECT_API_KEY_CONTENT)APP_STORE_CONNECT_KEY_IDAPP_STORE_CONNECT_ISSUER_ID
When TestFlight upload is enabled, the action requires a device build (MAKEPAD_IOS_SIM=false)
and automatically forces MAKEPAD_IOS_CREATE_IPA=true.
artifacts: JSON array of{ path, platform, arch, mode, version }app_name: resolved app nameapp_version: resolved versionrelease_id: GitHub Release ID used for upload (if any)release_url: GitHub Release URL (if created)
- Determine target from
args(--target), else default to host platform - Mobile builds require a target triple (e.g.
aarch64-linux-android,aarch64-apple-ios) - OpenHarmony targets are currently unsupported and will fail fast
- Resolve app metadata from
Cargo.tomlunless overridden - Install packaging tools per target (
cargo-packager,cargo-makepad) - Build artifacts and collect outputs into a normalized list
- Android package names are normalized to valid Java identifiers (e.g.
dora-studio→dora_studio) - If
releaseIdprovided, upload artifacts to that release (no release creation) - If
tagNameprovided (andreleaseIdnot set), create/update a GitHub Release and upload artifacts - Note: GitHub Release creation is not atomic. If multiple jobs call the action with the same
tagName, they can race and create separate drafts; prefer a single create-release job and passreleaseIdto each job to keep assets together. - Supports publishing to another repository via
owner+repo(token must have permission there) - Supports GitHub Enterprise/self-hosted API URLs via
githubBaseUrl - Release upload filters to recommended formats per platform when available (e.g. macOS
.dmg, iOS.ipa) - If an artifact is a directory (like
.app), it is zipped before upload - Asset names default to a unique
app-version-platform-arch-mode.extpattern unless overridden - By default, release upload also creates/updates a
latest.jsonasset (version,notes,pub_date,platforms) suitable for static updater metadata hosted on GitHub Releases CDN - For draft releases, updater URLs are generated using the release tag (
/releases/download/<tag>/<asset>) and become publicly downloadable after the release is published - If
<artifact>.sigexists next to an uploaded artifact anduploadUpdaterSignatures=true, it is uploaded as<asset>.sigand used assignatureinlatest.json - Upload steps support retries via
retryAttemptsto reduce failures from concurrent asset conflicts - Release upload requires a token with
contents: writepermission
When tagName or releaseName contains __VERSION__, it is replaced with the resolved app version.
- You do not pass signatures in a dedicated action input.
- Instead, place signature files beside built artifacts using the
<artifact>.signaming convention. - Example: if an uploaded asset resolves to
robrix-1.2.3-windows-x86_64-release.exe, provide a file ending with.exe.sigfor that artifact source path. - With
uploadUpdaterSignatures=true(default), the action uploads those.sigfiles and writes them intolatest.jsonunder each matched platform entry.
Use one of these patterns depending on workflow size:
Simple mode(single job / quick setup): call this action once withtagName(orreleaseId) and let it build + upload in one step. This is useful when you want minimal YAML and fast setup.Robust matrix mode(recommended for many parallel jobs): create the GitHub Release once, pass itsreleaseIdinto each build job, and let each job upload only to that existing release. This avoids release-creation races and keeps multi-platform uploads consistent.Build-only mode: omit bothtagNameandreleaseIdif you only want artifacts from the build step and will handle release publishing elsewhere.
For iOS device builds, supply certificate and provisioning profile via env vars.
When MAKEPAD_IOS_PROFILE/MAKEPAD_IOS_CERT are omitted, the action will install and extract them.
- uses: project-robius/makepad-packaging-action@main
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_PROVISIONING_PROFILE: ${{ secrets.APPLE_PROVISIONING_PROFILE }}
APPLE_KEYCHAIN_PASSWORD: ${{ secrets.APPLE_KEYCHAIN_PASSWORD }}
with:
args: --target aarch64-apple-ios- uses: project-robius/makepad-packaging-action@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tagName: app-v__VERSION__
releaseName: "App v__VERSION__"
releaseBody: "See the assets to download this version and install."
releaseDraft: true
prerelease: false
args: ${{ matrix.args }}Create the release once, then pass its ID to every build job so assets land on the same page.
jobs:
create_release:
runs-on: ubuntu-22.04
outputs:
release_id: ${{ steps.create_release.outputs.id }}
steps:
- uses: softprops/action-gh-release@v2
id: create_release
with:
tag_name: v1.2.3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
package:
needs: create_release
runs-on: ubuntu-22.04
steps:
- uses: project-robius/makepad-packaging-action@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
releaseId: ${{ needs.create_release.outputs.release_id }}
args: --target aarch64-linux-android- uses: project-robius/makepad-packaging-action@v1
with:
args: --target aarch64-linux-android- Desktop packaging: implemented (cargo-packager)
- Android packaging: implemented (APK build)
- iOS packaging: implemented (app bundle, optional IPA)
- OpenHarmony packaging: not implemented
- Web packaging: not implemented yet
- Release upload: implemented
- Web packaging (
wasm_profile)