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:
| Surface | Upgrade |
|---|---|
| React Native SDK | npm install @codemagic/react-native-patch@latest |
| CLI | npm 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.
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> --waitcommand to run before retrying. - React Native 0.87:
cmpatch release-reactworks again on React Native 0.87, which removedreact-native/cli.jsfrom 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
versionNameSuffixand asks you to pass the target explicitly when the project is ambiguous. cmpatch doctor: No longer fails the credential check for logins made withcmpatch 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 labeledreadyandapplied.
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:
Installedis nowReady(the update is prepared for the next launch), andSuccessis nowApplied(the update is running and confirmed bynotifyAppReady()). 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 withPatch.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
ReadyandAppliednames. 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 themetric_eventtable 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_BUCKETto 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-httpfrom 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:
- Self-host install wizard
- Improved CLI setup for local-eval
- CloudFront in front of storage
- Drill into why installs failed
- Successful installs stop counting as failures
- Server status in the dashboard
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
- Interactive CLI
- Fingerprint mismatch blocks the release
- Failure reasons on each release
- External Postgres and object storage
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.