I've followed the instructions to set up CodePush properly. First, I push to AppCenter:
$ appcenter codepush release-react -a myUser/appName -d Production
Detecting ios app version:
Using the target binary version value "1.0" from "ios/reactnative/Info.plist".
Running "react-native bundle" command:
node node_modules/react-native/local-cli/cli.js bundle --assets-dest /var/folders/gy/737c70fj7tq3pwdw758glxz00000gp/T/code-push118924-95814-1e6qqdj.df3g/CodePush --bundle-output /var/folders/gy/737c70fj7tq3pwdw758glxz00000gp/T/code-push118924-95814-1e6qqdj.df3g/CodePush/main.jsbundle --dev false --entry-file index.js --platform ios
Loading dependency graph, done.
bundle: Writing bundle output to: /var/folders/gy/737c70fj7tq3pwdw758glxz00000gp/T/code-push118924-95814-1e6qqdj.df3g/CodePush/main.jsbundle
bundle: Done writing bundle output
bundle: Copying 6 asset files
bundle: Done copying assets
Releasing update contents to CodePush:
Successfully released an update containing the "/var/folders/gy/737c70fj7tq3pwdw758glxz00000gp/T/code-push118924-95814-1e6qqdj.df3g/CodePush" directory to the "Production" deployment of the "appName" app.
Second, I go to the AppCenter website, select the successfully pushed version, and do a force roll out to every app.
I've tried to restart the app, reinstall the app, etc...but the app does not update from CodePush servers.
In my XCode console, I see:
loading - codepush2018-10-24 12:10:10.837955+0200 reactnative[5546:3916480]
[CodePush] Loading JS bundle from file:///Users/myUser/Library/Developer/CoreSimulator/Devices/4E7D0B07-B6B2-4D3C-B5B8-F28F3DA47077/data/Containers/Bundle/Application/081FD17C-B182-488D-B2D1-C786A3B25AAB/reactnative.app/main.jsbundle
Does this mean that CodePush is loading from local?
I believe I am running the release
scheme correctly:
class App extends React.Component {
constructor(props){
super(props)
}
componentDidMount() {
codePush.sync({
updateDialog: true,
installMode: codePush.InstallMode.IMMEDIATE
});
}
render(){
return <Main screenProps={this.props} />
}
}
const codePushOptions = { checkFrequency: codePush.CheckFrequency.ON_APP_RESUME };
const ConnectedApp = codePush(codePushOptions)(connect(state => state)(App))
firebase.auth().onAuthStateChanged(auth => {
if(auth){
store.dispatch(setUser(auth))
}else{
store.dispatch(logout())
}
})
export default () => (
<Provider store={store}>
<ConnectedApp />
</Provider>
)
I also do not see the updateDialog: true
when App mounts.
The Code Push keys must be same to the environment to which the application is being released and the one to which the application is built in order to receive the changes.
There are two possible solutions in order to avoid this conflict.
android {
...
buildTypes {
releaseStaging {
...
buildConfigField "String", "CODEPUSH_KEY", '"<INSERT_STAGING_KEY>"'
...
}
release {
...
buildConfigField "String", "CODEPUSH_KEY", '"<INSERT_PRODUCTION_KEY>"'
...
}
}
...
}
In the android/app/build.gradle
you can defined the various buildTypes
and build the app based on it
Under the Info tab click the +
button within Configurations
and Duplicate "Release" Configuration
and set its name to Staging
Now you can configure the User Defined Settings
and define a new setting CODEPUSH_KEY
and set ${CODEPUSH_KEY}
variable to the different schemes.
Elaborated steps are explained here: Source
Alternatively, if you don't want to add more Build Schemes / Types, you can add a custom script that changes keys based on the environment.
#!/usr/bin/env bash
#################################
# Change the environment variable
#################################
environment=$1
# Read Directory Path
parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
cd "$parent_path"
rm ../.env
# Set NODE_ENV in your .env file based on the script
echo "NODE_ENV=${environment}" > ../.env
#################################
# Change the code push key
#################################
if [ "$environment" = "staging" ]
then
echo "Change Code Push Key - Staging"
sed -i '' -E 's/CODEPUSH_KEY ?= ?".+"/CODEPUSH_KEY = "${YOUR_STAGING_IOS_CODEPUSH_KEY}"/' ../ios/YourProj.xcodeproj/project.pbxproj
sed -i '' -E 's/buildConfigField "String", "CODEPUSH_KEY", '\''".+"'\''/buildConfigField "String", "CODEPUSH_KEY", '\''"${YOUR_STAGING_ANDROID_CODEPUSH_KEY}"'\''/' ../android/app/build.gradle
elif [ "$environment" = "production" ]
then
echo "Change Code Push Key - Production"
sed -i '' -E 's/CODEPUSH_KEY ?= ?".+"/CODEPUSH_KEY = "${YOUR_PRODUCTION_IOS_CODEPUSH_KEY}"/' ../ios/YourProj.xcodeproj/project.pbxproj
sed -i '' -E 's/buildConfigField "String", "CODEPUSH_KEY", '\''".+"'\''/buildConfigField "String", "CODEPUSH_KEY", '\''"${YOUR_PRODUCTION_ANDROID_CODEPUSH_KEY}"'\''/' ../android/app/build.gradle
fi
Now you can run .${SCRIPT_PATH}/change-environment.sh ${ENV}
Example: ./change-environment.sh staging
This script changes the buildConfigField
in android buildTypes
and CODEPUSH_KEY
User Defined Settings to the pre defined schemes in ios.
It would be convenient combine this script with the react native's packager start command in your package.json
"start": "./change-environment.sh development && node node_modules/react-native/local-cli/cli.js start",
"start:staging": "./change-environment.sh staging && node node_modules/react-native/local-cli/cli.js start",
"start:production": "./change-environment.sh production && node node_modules/react-native/local-cli/cli.js start",