Skip to main content

Release Notes

Release Notes

Longer-form notes for each Patch release train. Shorter summaries and install links stay on GitHub Releases.

Patch ships three versioned surfaces on independent tags. To upgrade each one, run the following:

SurfaceUpgrade
React Native SDKnpm install @codemagic/react-native-patch@latest
CLInpm install -g @codemagic/patch-cli@latest
Server (self-host)cmpatch selfhost upgrade

Version 0.5.0​

23rd September 2026

Wire the SDK into your app with one command, integrate with a single Patch.wrap, and sign in to self-hosted servers with GitLab.

Upgrade your server first

SDK 0.5.0 reports update lifecycle events as Ready and Applied. Servers 0.4.x and earlier drop these events without storing them, so upgrade your server to 0.5.0 before you ship an app build with the new SDK. Server 0.5.0 still accepts the old event names, so apps already in the field keep reporting normally.

CLI 0.5.0​

Wire the SDK with one command​

cmpatch wire installs the Patch SDK in a supported React Native or Expo project and wires it up. It sets the deployment key and server URLs, adds the native bundle-loading hooks, and wraps your root component with Patch.wrap. cmpatch init now runs it automatically; pass --skip-wire to only connect the app. Run cmpatch wire --dry-run --diff to preview the changes. When wire can't finish the setup automatically, it prints a Patch.wrap snippet to add by hand.

If CodePush or expo-updates is still in the project, init holds off on wiring until you remove it. See Native setup.

GitLab and Bitbucket in the self-host wizard​

cmpatch selfhost install now supports Bitbucket Cloud and GitLab sign-in, in the wizard and in non-interactive setup. For a self-managed GitLab instance, enter its address when asked or pass --gitlab-oauth-base-url.

  • Release conflict hints: When a release change is blocked by a 409 conflict, the CLI names the release to wait for and the cmpatch release inspect --release-id <id> --wait command to run before retrying.
  • React Native 0.87: cmpatch release-react works again on React Native 0.87, which removed react-native/cli.js from its package exports. Before this fix the command failed with "Could not resolve react-native from project root", mostly in npm projects.
  • Binary version detection: iOS and Android version detection is more accurate, so OTA releases target the right app version. It handles Android versionNameSuffix and asks you to pass the target explicitly when the project is ambiguous.
  • cmpatch doctor: No longer fails the credential check for logins made with cmpatch login --token. It also accepts --xcode-project-file, --xcode-target-name, and --build-configuration-name.
  • CI logs: Progress steps now show up in non-interactive output, so long builds and bundle uploads no longer look stuck.
  • cmpatch debug: Shows only Patch SDK logs and filters out unrelated system messages.
  • cmpatch release metrics: Columns are now labeled ready and applied.

See the CLI reference and CLI release.

React Native SDK 0.5.0​

Integrate with Patch.wrap​

Wrap your root component, and the SDK runs an update check after it mounts:

import * as Patch from "@codemagic/react-native-patch";

export default Patch.wrap(App);

The app renders immediately and never waits for the check. Set checkFrequency: CheckFrequency.ON_APP_RESUME to also check whenever the app returns to the foreground. Other options are passed through to sync(), so install behavior is unchanged. Mounting the wrapped root marks the running update as healthy. If your app needs to finish an async startup step first, call sync() yourself at that point instead.

Configure the rollback launch budget​

The new optional CodemagicPatchMaxLaunchAttempts setting (Info.plist on iOS, strings.xml on Android) sets how many launches a pending update may make without notifyAppReady() before it is rolled back. The default is still 3. Expo projects can set it with the config plugin's maxLaunchAttempts option.

  • Lifecycle names: Installed is now Ready (the update is prepared for the next launch), and Success is now Applied (the update is running and confirmed by notifyAppReady()). Requires server 0.5.0; see the warning above.
  • Development warning: In development builds, a failed sync() logs a warning with the reason, even when nothing reads its result, as with Patch.wrap. Release builds stay silent. A wrong deployment key or server path returns "no update" and doesn't trigger the warning.
  • Duplicate Applied events: Concurrent notifyAppReady() calls no longer report the same update as applied more than once.
  • React Native 0.87: The SDK typechecks again in strict TypeScript apps.

See the SDK reference and SDK release.

Server and Dashboard 0.5.0​

GitLab sign-in​

Self-hosted servers can now use GitLab for sign-in, on gitlab.com or a self-managed instance set with GITLAB_OAUTH_BASE_URL. GitLab accounts that have only a confirmed primary email can sign in, and the sign-in button shows the GitLab name and icon.

Find your way around the dashboard​

A command palette (⌘K / Ctrl+K) jumps to apps, releases, metrics, and teams, and runs common actions. The deployment page now shows update adoption, the sidebar lists apps with their deployments, and the Metrics screens are available from a link on the deployment page. Release details add a cumulative Applied chart showing update adoption over time.

  • Lifecycle names: The server stores events from SDK 0.4.x and earlier under the new Ready and Applied names. Existing data is kept as is, and the metrics API response keys (installed, success) are unchanged.
  • Database migration: The upgrade runs migration 0016_metric_event_lifecycle_names, which rebuilds an index on the metric_event table while holding an exclusive lock on it. On servers with a large metrics history, expect the upgrade to take longer.
  • Dashboard fixes: Fixed page scrolling, removed blank space a hidden chart table added to the bottom of the page, and cleaned up how the deployment and release detail pages show status, metrics, charts, and history.

See the configuration reference and server release.

Version 0.4.0​

14th September 2026

Try an OTA update with a guided demo, diagnose your SDK setup, and configure external storage and DNS from the install wizard.

CLI 0.4.0​

Try an OTA update with a guided demo​

After starting the local evaluation stack, run cmpatch demo to see Patch in action before integrating it into your own app. The wizard checks prerequisites, builds a bundled demo on an iOS simulator or Android emulator, and shows a catalog bug. After you approve publishing the fix, it automatically resumes the app to download, install, and apply the update.

Diagnose setup before your first release​

cmpatch doctor checks React Native and Expo integration on iOS and Android, including native configuration, authentication, and deployment settings. Reports explain likely causes and distinguish confirmed failures from incomplete checks. Add --verify-delivery to probe manifests and artifacts, with JSON output available for CI. An optional --fix --server-url <url> can create missing server configuration after a readiness check and your approval.

Configure external storage and DNS from the wizard​

cmpatch selfhost install now offers Cloudflare R2, Amazon S3, and Google Cloud Storage alongside bundled MinIO. Automatic setup or guided console instructions help configure storage, then verify public downloads and private-object protection. DNS setup supports Cloudflare and compatible Domain Connect providers, with manual instructions as a fallback.

Failed setup steps offer correction and retry paths. These options apply to new installations; they do not migrate existing storage.

See the CLI reference and CLI release.

React Native SDK 0.4.0​

Know when an update is ready to activate​

The new isNextVersionReady() API reports whether a different OTA package is installed and waiting for the next reload. Use it to show an “Update ready” prompt while the current bundle continues running. It does not report a staged return to the embedded bundle.

  • Embedded revert fix: Returning to the embedded bundle now honors the selected install mode, including next suspend, resume, or restart.

See the SDK reference and SDK release.

Server and Dashboard 0.4.0​

  • Private storage: S3-compatible storage can use S3_INTERNAL_BUCKET to keep internal uploads and worker artifacts in a separate private bucket while serving release artifacts publicly. Leaving it unset keeps single-bucket routing.
  • Dashboard appearance: Light, dark, and system themes, refreshed branding, accessibility improvements, and a fix for translucent dark-mode callouts.
  • Delivery metrics: Release details drop Active counts; deployment summaries show successful installs, and release history includes downloads. Success counts represent installations, not users currently running a version.
  • Localhost HTTP: Run scripts/selfhost/install.sh --allow-http from a local clone to test the self-hosted stack without TLS certificates or public DNS. Service ports bind to loopback; OAuth setup is still required.

See the configuration reference and server release.

Version 0.3.0​

7th September 2026

CLI-first install, CloudFront as a delivery option, and metrics you can debug. You can put a server on a VPS or try the stack on a laptop from cmpatch, without cloning the repo first.

What's included:

If you already use Cloudflare

After you upgrade, delete the two-hour Edge TTL Cache Rule for .json from the previous setup guide, and remove any MANIFEST_CACHE_CONTROL line from .env.selfhost. The Cache Rule overrides the origin s-maxage and stretches the stale window from five minutes to two hours. A leftover MANIFEST_CACHE_CONTROL pins the old no-cache value, so manifests never enter the edge cache at all. See Cloudflare setup.

Self-host install wizard​

You can install and operate a production server from your own machine. The wizard pairs over SSH, checks the host, can install Docker and Git with your consent, then walks through domains, DNS, GitHub OAuth, and optional Cloudflare or CloudFront. The same CLI wraps backup, restore, and upgrade.

cmpatch selfhost install

cmpatch init offers this install when you have no server URL yet, then continues into sign-in and app creation. An interrupted backup restarts the server before it exits, so a killed backup does not leave the server stopped; interrupted restore and upgrade runs print the rollback command instead. The wizard sets up the bundled Postgres and MinIO stack with GitHub sign-in. Bitbucket, external databases, and S3/GCS stay on the direct install.sh path. See Install and Operations.

Improved CLI setup for local-eval​

The evaluation stack is the same as before. You no longer clone the repo first: cmpatch keeps its own copy and updates it on later runs. If Docker is missing or not running, it asks before installing or starting it.

cmpatch selfhost local-eval

See Local quickstart.

CloudFront in front of storage​

Devices can fetch artifacts from Amazon CloudFront instead of only Cloudflare or the origin host, for bundled MinIO or external S3/GCS. The install wizard prints the AWS Console values, generates the origin secret, and verifies the distribution before you move DNS. It does not create AWS resources or ask for AWS credentials beyond the scoped purge key. See CloudFront setup.

Drill into why installs failed​

A single network count is no longer a dead end. Failed installs carry a payload the dashboard can open: HTTP status, the origin or platform error message, and on Android 11+ the previous process exit reason. Open a failure reason on the metrics view to see codes, then the values behind a code.

A pending package now gets three consecutive launches to call notifyAppReady() before the SDK rolls back and reports Failed. That cuts false crash-rollbacks from OS process kills without stranding devices on a broken bundle. See Analytics and metrics.

Successful installs stop counting as failures​

Failures now come only from devices that never got the update, not from retries on a flaky network that later succeeded. When a device later installs the same package successfully, its earlier Failed events for that package are dropped. A late Failed after a Applied is acknowledged and discarded.

Server status in the dashboard​

You can check the Patch server without SSHing to the host. The dashboard has a Status page: API and database health, whether the download URL is reachable, disk use on a bundled single-host install, and the running server version compared with the latest GitHub release. Disk and version cards hide on topologies where they would not apply.

Version 0.2.0​

25th August 2026

Interactive CLI, fingerprint checks that can block a bad publish, failure reasons on each release, and Compose support for an external database or bucket.

What's included:

See which OTA bundle is running​

You can show which OTA release is active in the current process, for an in-app "About this build" screen or for QA. getRunningBundleUpdateMetadata() returns label, packageHash, and releaseNotes, or null when the app is still on the embedded store binary.

import { getRunningBundleUpdateMetadata } from "@codemagic/react-native-patch";

const running = await getRunningBundleUpdateMetadata();
if (running) {
console.log(running.label, running.packageHash, running.releaseNotes);
}

The value does not change until the next reload. See SDK reference.

Interactive CLI​

Missing flags no longer fail with a bare usage line. cmpatch prompts for them, shows progress, and offers sign-in and retry paths when browser login fails. CI and scripts stay non-interactive: pass the flags you need, or use --yes where supported. See CLI command reference.

Fingerprint mismatch blocks the release​

A release aimed at the wrong native binary is blocked unless you confirm it. The CLI and dashboard compare the release fingerprint against the value already recorded for that deployment and binary version. When they disagree, you see the evidence and can cancel or proceed.

In CI, where there is no prompt, pass --allow-fingerprint-mismatch only after you have verified the release targets the intended native binary:

cmpatch release-react \
--deployment Production \
--allow-fingerprint-mismatch \
--yes

Uploads can send block_on_fingerprint_mismatch: true so a disagreement returns 409 with no release created. The current CLI and dashboard send that flag by default; older clients and explicit overrides keep the previous warning-only behavior. See Fingerprinting.

Failure reasons on each release​

You can see whether failures cluster on integrity, signature, rollout, or another category, instead of one opaque failed number. Metrics APIs and the dashboard expose failure_reasons on each release; those counts sum to failed. Use the deployment metrics view or cmpatch release metrics during a rollout. See Analytics and metrics.

External Postgres and object storage​

You can point Compose at a managed PostgreSQL database and S3-compatible bucket instead of the bundled Postgres and MinIO containers, when MinIO on the same host is not enough. The default scripts/selfhost/install.sh run still creates the bundled stack. For external storage or database, pass its storage and database flags, then configure adapters as described in Infrastructure adapters and Configuration reference.

Backups and restores remain mode-aware: external databases and buckets are not copied by the default backup script. Plan provider-level backups for those components. See Operations.