Verify a test release
Verify a test release
Publishing with cmpatch release-react only confirms the server accepted the bundle. This page closes the loop for your app: install a native build, publish a JS change, confirm the device picks it up.
The repo includes a ready-made on-device demo wired to the local evaluation stack. Use that if you want to try an OTA without integrating Patch into your own app first. Come back here when verifying a Staging build of your product.
Use Staging (or your local evaluation deployment) until you are confident, not Production.
Before you start
The app on device must already satisfy:
| Requirement | Why |
|---|---|
| Patch SDK in the native binary | OTA cannot add the SDK after install, Core concepts |
CodemagicPatchDeploymentKey matches the deployment you publish to | Wrong key → manifest 404 or wrong channel |
CodemagicPatchApiUrl and CodemagicPatchDownloadBaseUrl reachable from the device | Simulator can use localhost; phone and test-track builds need your Install HTTPS domains |
Running binary version matches the release's targetBinaryVersion | Mismatch → server offers no update |
sync() (or manual check/download/install) runs on launch or resume | No check → no download, Checking for updates |
If you have not published yet, start with First release.
Choose how the test app is installed
Where the app runs determines which server URLs work. Two common setups:
| Setup | Typical use | Server URLs |
|---|---|---|
| Local + simulator | Local evaluation stack on your Mac, app in iOS Simulator or a same-machine Android emulator | http://localhost:3000 + http://localhost:9100/codemagic-patch, Local quickstart |
| Server + phone | Phone or test-track build (TestFlight, Play internal testing) talking to a real Patch install | Public HTTPS API + storage domains from Install |
You do not need separate guides for each path; the test loop is the same. Only the URLs and how you install the binary differ.
For Staging on a public install, most teams ship an internal or TestFlight build with the Staging deployment key embedded, then OTA against https://updates.example.com. Production users stay on the Production key until you promote.
The test loop
Make one visible change in JS (e.g. button label or debug banner), then run through this sequence.
1. Confirm the release is published on the server
cmpatch release inspect --app MyApp-iOS --deployment Staging --label v1 --wait
Status should reach published (not stuck in uploaded or processing). In the dashboard, open the deployment release table and confirm the label appears as Published.
2. Publish the JS change
cmpatch release-react \
--platform ios \
--deployment Staging \
--release-notes "Verify OTA" \
--yes
Wait for processing again (inspect --wait or dashboard).
3. Trigger an update check on device
Cold-start the app or bring it to foreground, however you wired sync() (Checking for updates).
Default sync() uses ON_NEXT_RESTART for non-mandatory releases, so you may need to kill and reopen the app twice: once to download, once to run the new bundle.
For faster iteration during testing, use immediate apply:
import { sync } from "@codemagic/react-native-patch";
void sync({ installMode: "IMMEDIATE" });
4. Confirm it worked
| Signal | What to look for |
|---|---|
| UI | Your JS change is visible after reload |
| SDK | sync() resolves to "update-installed" (or "up-to-date" if already on latest) |
| Dashboard | Download / success metrics tick up on the release, Analytics |
| CLI | cmpatch release inspect … shows client activity for the label |
Repeat on Android if you ship both platforms, separate apps and deployment keys per platform.
Quick checks if nothing updates
| Symptom | Likely cause |
|---|---|
| Release Published but device unchanged | Install mode needs a second launch; or sync() not called |
| No update offered | Binary version mismatch, compare app version to --target-binary-version on the release |
| Network errors in logs | Device cannot reach API or storage URL (common when a phone still points at localhost) |
| Wrong bundle | Deployment key in the binary does not match the deployment you published to |
Full list: Troubleshooting. CLI sanity check before publishing:
cmpatch doctor --app MyApp-iOS --deployment Staging --verbose
After Staging looks good
When QA is satisfied on Staging, follow Preparing for production before your first Production release. In short:
- Promote the release to Production with no rebuild required, or publish a new release directly to Production when ready
- Use Production control for rollouts and rollbacks on live users
Production devices must use a native binary built with the Production deployment key. Staging OTAs never reach them.
Related
- First release: initial publish
- Releasing updates: Staging → Production workflow
- Local quickstart: local evaluation stack and on-device demo
- Native setup: SDK and config keys