iOS react native app does not update from CodePush server - ios

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.
Define separate Build Schemes.
Add a custom script that changes Code Push keys with the environment change.
Build Schemes / Types
Android
android {
...
buildTypes {
releaseStaging {
...
buildConfigField "String", "CODEPUSH_KEY", '"<INSERT_STAGING_KEY>"'
...
}
release {
...
buildConfigField "String", "CODEPUSH_KEY", '"<INSERT_PRODUCTION_KEY>"'
...
}
}
...
}
Source
In the android/app/build.gradle you can defined the various buildTypes and build the app based on it
IOS
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
Custom Script
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.
change-environment.sh
#!/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",

The CodePush is not loading from exactly, it downloads the bundle from the CodePush server. So path you have seen is a path part of your simulator's file system.
Please refer here to know how to set deployment target
https://learn.microsoft.com/en-us/appcenter/distribution/codepush/react-native

Related

AWS CDK Pipeline: Assets stage fails to find buildSpec FileAsset.yaml when publishAssetsInParallel is disabled

We are trying to get our multi-stack application deployed using the cdk pipeline library.
We have recently disabled the publishAssetsInParallel flag, as with the default setting our pipeline would create >20 FileAsset objects under the Assets stage, which AWS then complains as being too many CodeBuild projects running parallel.
However, with this property now disabled, I'm getting the following error for the Assets stage:
[Container] 2022/11/14 12:04:24 Phase complete: DOWNLOAD_SOURCE State: FAILED
[Container] 2022/11/14 12:04:24 Phase context status code: YAML_FILE_ERROR Message: stat /codebuild/output/src112668013/src/buildspec-c866864112c35d54804951dbe96b99440c9b891fde-FileAsset.yaml: no such file or directory
I'm assuming this is supposed to be a build spec that is create by cdk pipeline, as we didn't need to create a build spec when things were running in parallel.
Here is the current pipeline code:
const pipeline = new CodePipeline(this, 'Pipeline', {
publishAssetsInParallel: false,
selfMutation: false,
pipelineName: fullStackName('Pipeline', app),
synth: new CodeBuildStep('SynthStep', {
input: CodePipelineSource.codeCommit(repo, repoBranchName, {codeBuildCloneOutput: true}),
buildEnvironment: {computeType: ComputeType.MEDIUM},
installCommands: [
'npm install -g yarn',
'yarn install',
'cd apps/cloud-app',
'yarn install',
'yarn global add aws-cdk'
],
commands: [
'yarn build',
'cdk synth'
],
primaryOutputDirectory: 'apps/cloud-app/cdk.out'
}
)
});
UPDATE:
I reverted the publishAssetsInParallel flag to its default setting to compare, and it seems there is a fundamental difference in the way it creates the FileAsset CodeBuild projects based on this flag. With it enabled, when I inspect the build details for one of the FileAsset projects that is created, I can see under the buildspec section it contains a concrete implementation of a build spec, eg:
{
"version": "0.2",
"phases": {
"install": {
"commands": [
"npm install -g cdk-assets#2"
]
},
"build": {
"commands": [
"cdk-assets --path \"MyStack.assets.json\" --verbose publish \"2357296280127ce793d8dbb13e6c907db22f5dcc57a173ba77fcd19a76d8f444:12345678910-eu-west-2\""
]
}
}
}
With the flag disabled, the buildspec simply contains a pointer to a buildspec file as below, which it then fails to find...
buildspec-c866864112c35d54804951dbe96b99440c9b891fde-FileAsset.yaml
Self-mutation has to be enabled - currently, asset updates mutate the pipeline.
Reference: https://github.com/aws/aws-cdk/issues/9080

Playwright - Test against different environments and different variables

Im looking to use Playwright to test against a web page.
The system im working on has 4 different environments that we need to deploy against,
for example the test urls may be
www.test1.com
www.test2.com
www.test3.com
www.test4.com
The first question is how do I target the different Environment? In my playwright config I had a baseUrl but I need to override that.
In addition each environment has different login credentials, how can I create and override these as parameters per environment?
Since Playwright v1.13.0, there is a baseURL option available. You can utilise that in this way probably
In your config.js file, you can have this
import { PlaywrightTestConfig } from '#playwright/test';
const config: PlaywrightTestConfig = {
use: {
baseURL: process.env.URL,
},
};
export default config;
Now in the package.json file, you can have the environment variables set in the test commands for various env in the scripts , like this
...
"scripts": {
"start": "node app.js",
"test1": "URL=www.test1.com mocha --reporter spec",
"test2": "URL=www.test2.com mocha --reporter spec",
.
.
},
...
Similarly you can set the environment variables for the login credentials also and then pass them in the script in the same way the URL is passed.
Another approach to this is to use a Bash script. I use something like the following to run tests across environments, to ensure that my Playwright tests will work in all environments they're run in -
#!/bin/bash
echo "Running tests against env 1";
ENV_URL=https://www.env1.com SOMESERVICE_ENV_URL=http://www.env1.com/scholarship npx playwright test $1;
echo "Running tests against env 2"
ENV_URL=https://env2.com SOMESERVICE_ENV_URL=http://env2.com:4008 npx playwright test $1;
echo "Running tests against env 3";
ENV_URL=http://localhost:3000 SOMESERVICE_ENV_URL=http://localhost:4008 npx playwright test $1;
And then run with ./myScript.sh myTest.test.ts
(In a Bash script, the first argument passed in is available via $1.)

Next.js: how to use different env file for different environment?

Below is the code from package.json file
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
},
Below is my next.config.js file, here console.log always undefined
require("dotenv").config();
console.log(process.env.BASE_URL)
module.exports = {
env: {
API_BASE_URL: process.env.BASE_URL
},
reactStrictMode: true,
}
And this is in the .env.development
BASE_URL: 'http://localhost:3000'
When I ran the npm run dev command,
it prints on terminal "Loaded env from /var/www/html/next/next-SC/.env.development"
So, why the console prints undefined always.
I'm using next js version "10.0.4"
I assume you are using React with nextjs. If not, then please disregard this answer. I am doing the same thing. React has built in support for env vars. All you need to do is to prefix REACT_APP to your environment vars. So, in your .env.development or .env.staging, etc., you can have REACT_APP_BASE_URL=https://blah.com. You can then access them in your app using process.env.REACT_APP_BASE_URL. Then to build based on environment, I have (I am using craco, you would just use your normal build command)
"build:nightly": "env-cmd -f .env.nightly craco build",
"build:nightly": "env-cmd -f .env.staging craco build",
"build:nightly": "env-cmd -f .env.beta craco build",
...
For development environment, name the file .env.development, for production .env.production.
Next.js has built-in loader for environment variables. So dotenv or similar packages aren't needed. Just add the files. It will be loaded automatically (see documentation).

How to publish electron app to GitHub releases using electron builder?

I am trying to publish my electron app to GitHub releases but I cannot get it to work.
This is what I have:
package.json
....
"scripts": {
"start": "electron . --disable-gpu",
"test": "echo \"Error: no test specified\" && exit 1",
"win": "electron-builder --windows nsis:ia32",
"linux": "electron-builder --linux",
"publish":"electron-builder -p onTag"
},
....
"build": {
"publish": [
"github"
],
....
}
when I run npm run publish it creates the executable but it does not publish on my GitHub releases repository:
$ npm run publish
> Inventory-pro#1.0.1 publish /home/xander/Develop/Electron/InventoryV2
> electron-builder -p onTag
• electron-builder version=21.2.0 os=5.3.0-26-generic
• loaded configuration file=package.json ("build" field)
• writing effective config file=dist/builder-effective-config.yaml
• packaging platform=linux arch=x64 electron=7.1.3 appOutDir=dist/linux-unpacked
• building target=deb arch=x64 file=dist/Inventory-pro_1.0.1_amd64.deb
I want to publish it so that I can include auto-update on my app on every release.
Don't specify the -p option and it will always publish a release because your script in the package.json is named release.
But please consider using automatic rules instead of explicitly specifying publish:
If npm script named release, — always.
Source: https://www.electron.build/configuration/publish#how-to-publish
...
"scripts": {
...
"publish":"electron-builder"
},
...

How to create release channels with electron/electron-builder?

I have an Electron app where I want to introduce parallel release channels: stable, next (for early adopters) and dev (for testing the latest build).
These will have a branch each, with new features appearing first in dev, progressing to next for beta testing and finally moving into stable.
I'm using electron-builder to make these release packages, and I want each to have its own auto-updates - so when I publish a new next release all the users with it get the update.
I want the applications to be independent - a user can have two channels installed and run both at the same time. They'll have different names and different icons.
I can manually set these up in the branches, but really I want to automate this as much as possible - a publish from the next branch should use the right name, icons, IDs and updater without risk of it going to the wrong channel.
Is there a way to do this with electron or electron-builder?
It's possible with electron-builder. I would have several build configurations and tell electron-builder which to use when building.
For example, create file config/beta.json with the following setup:
{
"appId": "com.company.beta",
"productName": "App Beta",
"directories": {
"buildResources": "build/beta" // directory containing your build-specific assets (e.g., beta icons - icon.icns, icon.ico & background.png)
},
"mac": {
"category": "public.app-category.finance"
},
"win": {
"target": [
"nsis"
]
},
"nsis": {
"perMachine": false
},
"publish": [
{
"provider": "s3",
"bucket": "com-app-beta" // dedicated S3 bucket for each build
}
],
}
And duplicate config/beta.json for next.json and current.json (make sure to edit settings accordingly).
In package.json, add the following build scripts (note --em.name=app-beta to overwrite package.json's "name" value):
{
"scripts": {
"build": "build -owl --x64 --config ./config/current.json -p always --em.name=app",
"build-beta": "build -owl --x64 --config ./config/beta.json -p always --em.name=app-beta",
"build-next": "build -owl --x64 --config ./config/next.json -p always --em.name=app-next"
}
}
Run build script when ready to deploy:
npm run build-beta
Using electron-builder version 20.15.1 and MacOS, #Jon Saw's solution needs a minor change because em option is not valid:
"build-beta": "build -owl --x64 --config ./config/beta.json -p always -c.extraMetadata.name=app-beta"

Resources