Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
44ea676
classCastException caught in loadBundle
naveen-bitrise May 19, 2025
b39a094
removed debug comments
naveen-bitrise Jun 6, 2025
214ced1
Added Expo Example Project
naveen-bitrise Jun 7, 2025
e02e868
updated android bundle name to index.android.bundle
naveen-bitrise Jun 7, 2025
30977cd
Added iOS instructions to Readme in CodePushExpoDemoApp
naveen-bitrise Jun 7, 2025
19ef43a
Updated iOS instructions in Readme in CodePushExpoDemoApp
naveen-bitrise Jun 7, 2025
3600002
Updated Readme in CodePushExpoDemoApp to mention codepush expo plugin
naveen-bitrise Jun 7, 2025
cd36a6d
updated Readme to include zipping the updates
naveen-bitrise Jun 15, 2025
003f334
minor Readme corrections
naveen-bitrise Jun 15, 2025
b958622
add expo test-app setup-1
CHOIMINSEOK Jun 15, 2025
b09bd49
refactored expo codepush plugin
naveen-bitrise Jun 15, 2025
687f40c
expo setup for test - 2
CHOIMINSEOK Jun 22, 2025
86d2e6d
expo setup for test - 3
CHOIMINSEOK Jun 22, 2025
d11cd1f
override TestAppName
CHOIMINSEOK Jun 22, 2025
133301d
fix android test
CHOIMINSEOK Jun 22, 2025
1cb55cc
fix bundling script
CHOIMINSEOK Jun 22, 2025
a9e5c41
fix bundling script
CHOIMINSEOK Jun 22, 2025
a1e6345
using react-native bundle instead of expo export during expo test
kmsbernard Jul 6, 2025
6e10766
moved expo plugin file to CodePushExpoDemoApp
naveen-bitrise Jul 6, 2025
8d811f4
Merge branch 'master' into expo-fix
CHOIMINSEOK Jul 6, 2025
83ed514
moved expo.js to root
naveen-bitrise Jul 6, 2025
400d726
1. Expo plugin refactor, and an issue in modifying buildTypes block i…
naveen-bitrise Jul 7, 2025
b34cf6e
expo plugin refactor, and README update
naveen-bitrise Jul 7, 2025
a6f6ad3
add expo plugin guide
Jul 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,6 @@ Examples/testapp_rn

# Android debug build files (conflict ignoring #Visual Studio files)
!android/app/src/debug/

#CodePushExpoDemoApp
*.rm
46 changes: 46 additions & 0 deletions Examples/CodePushExpoDemoApp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files

# dependencies
node_modules/

# Expo
.expo/
dist/
web-build/
expo-env.d.ts

# Native
.kotlin/
*.orig.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision

# Metro
.metro-health-check*

# debug
npm-debug.*
yarn-debug.*
yarn-error.*

# macOS
.DS_Store
*.pem

# local env files
.env*.local

# typescript
*.tsbuildinfo

#expo prebuild
android/*
ios/*

#build
build/*


82 changes: 82 additions & 0 deletions Examples/CodePushExpoDemoApp/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { StatusBar } from 'expo-status-bar';
import React, { useState, useEffect } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import codePush from '@code-push-next/react-native-code-push';

function App() {
// Log current package information on app start
useEffect(() => {
// Add custom error handler
const originalConsoleError = console.error.bind(console);
console.error = function (message, ...args) {
console.log("[CodePushDebug] Error intercepted:", message, ...args);
return originalConsoleError(message, ...args);
};

// Monitor network requests
const originalFetch = global.fetch;
global.fetch = function (input, init) {
console.log("[CodePushDebug] Fetch request to:", typeof input === 'string' ? input : 'Request object');
return originalFetch(input, init)
.then(response => {
console.log("[CodePushDebug] Fetch success for:", typeof input === 'string' ? input : 'Request object');
return response;
})
.catch(error => {
console.log("[CodePushDebug] Fetch error:", error);
throw error;
});
};

codePush.getUpdateMetadata().then((metadata) => {
if (metadata) {
console.log('[CodePush] Running binary version: ' + metadata.appVersion);
console.log('[CodePush] Running with CodePush update: ' + metadata.label);
console.log('[CodePush] Package hash: ' + metadata.packageHash);
console.log('[CodePush] Package description: ' + metadata.description);
} else {
console.log('[CodePush] Running binary version with no CodePush updates installed');
}

// After getting metadata, check for updates
console.log('[CodePush] Checking for update.');
}).catch(err => {
console.log('[CodePush] Error getting metadata:', err);
});
}, []);

return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
<StatusBar style="auto" />
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});

// CodePush configuration (remains the same as your original file)
const codePushOptions = {
checkFrequency: codePush.CheckFrequency.ON_APP_START,
installMode: codePush.InstallMode.IMMEDIATE,
mandatoryInstallMode: codePush.InstallMode.IMMEDIATE,
updateDialog: {
appendReleaseDescription: true,
title: "Update Available",
descriptionPrefix: "\n\nRelease Notes:\n",
mandatoryContinueButtonLabel: "Install Now",
mandatoryUpdateMessage: "An update is available that must be installed.",
optionalIgnoreButtonLabel: "Later",
optionalInstallButtonLabel: "Install Now",
optionalUpdateMessage: "An update is available. Would you like to install it?"
}
};

export default codePush(codePushOptions)(App);
77 changes: 77 additions & 0 deletions Examples/CodePushExpoDemoApp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
This is a [**React Native Expo**](https://docs.expo.dev/) project, created using the command `npx create-expo-app@latest --template blank`. The App.js file was then modified to add CodePush functionality. An expo plugin was added for CodePush in `codepush-plugin.js` and is configured in `app.json`

# Testing Codepush functionality

## Step 1: Set Codepush Server and Codepush Deployment key in app.json

In app.json set `CodePushDeploymentKey` and `CodePushServerURL` for ios and android.

## Step 2: Run expo prebuild

run `npx expo prebuild --clean`

## Step 3: Create release bundle

### Android

run `cd android && ./gradlew assembleRelease`

The apk bundle will be here `<project folder>/android/app/build/outputs/apk/release/app-release.apk`

Install the bundle on your android device, and open the app

### iOS

Create a release build by opening the `ios/CodePushExpoDemoApp.xcworkspace` in Xcode. Make sure it is a release build (in Xcode go to Product > Scheme > Edit Scheme > Select Run from left bar menu > verify that Release is selected in Build Configuration.). Choose a Simulator as well in Xcode, and Run. Wait till the app loads in simulator.

## Step 4: Make a change to App.js

Make a visible update to the App, by modifying App.js

## Step 5: Generate update Bundle

Run the following command to generate updated bundle

### Android

From in the project folder, run:

```
npx expo export:embed \
--entry-file index.js \
--platform android \
--dev false \
--reset-cache \
--bundle-output ./build/index.android.bundle \
--assets-dest ./build \
--minify false
```

zip the build folder (include the build folder): `zip -r update.zip ./build`

### iOS

From the project folder, run:

```
npx expo export:embed \
--entry-file index.js \
--platform ios \
--dev false \
--reset-cache \
--bundle-output ./build/main.jsbundle \
--assets-dest ./build \
--minify false
```

zip the build folder (include the build folder): `zip -r update.zip ./build`

## Step 6: Upload the update bundle to codepush server

Upload the update bundle zip to your codepush server following the instructions from the codepush server that you use

## Step 7: Open the app on your device

Close/kill the app, and reopen the app. When the app is opened, it will show that there is an update you can install


54 changes: 54 additions & 0 deletions Examples/CodePushExpoDemoApp/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"expo": {
"name": "CodePushExpoDemoApp",
"slug": "CodePushExpoDemoApp",
"version": "1.2.1",
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "light",
"newArchEnabled": true,
"splash": {
"image": "./assets/splash-icon.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"ios": {
"supportsTablet": true,
"bundleIdentifier": "com.CodePushNext.ExpoDemoApp"
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#ffffff"
},
"edgeToEdgeEnabled": true,
"package": "com.CodePushNext.ExpoDemoApp"
},
"web": {
"favicon": "./assets/favicon.png"
},
"plugins": [
[
"@code-push-next/react-native-code-push/expo",
{
"ios": {
"CodePushDeploymentKey": "Tf2qo0NCNKloj8Ym2Z2Bk_VQ_zLDNzk2MGNjNDktNWFiZS00NTAwLWFlNDEtZjMzNzllNGU0MjE0",
"CodePushServerURL": "https://codepush.bitrise.io"
},
"android": {
"CodePushDeploymentKey": "rUV0_iNflPqa3aJhVpciLnwgAFOaMzFiZjhhNDMtMGEyNS00NTk5LTk2ODEtOWU1NTcwODUwZTgx",
"CodePushServerURL": "https://codepush.bitrise.io"
}
}
],
[
"expo-build-properties",
{
"ios": {
"deploymentTarget": "15.5"
}
}
]
]
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Examples/CodePushExpoDemoApp/assets/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Examples/CodePushExpoDemoApp/assets/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions Examples/CodePushExpoDemoApp/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { registerRootComponent } from 'expo';

import App from './App';

// registerRootComponent calls AppRegistry.registerComponent('main', () => App);
// It also ensures that whether you load the app in Expo Go or in a native build,
// the environment is set up appropriately
registerRootComponent(App);
Loading