Skip to content
This repository was archived by the owner on May 20, 2025. It is now read-only.

Commit 6f6f145

Browse files
implement script to generate CodePushified React Native apps (#958)
* implement fully automatic script to generate CodePushified React Native apps * fix compatibility issues, remove generate-app.sh * update docs, improve react-native version detection
1 parent 416af9b commit 6f6f145

File tree

3 files changed

+571
-63
lines changed

3 files changed

+571
-63
lines changed

Examples/create-app.js

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
/*
2+
The script serves to generate CodePushified React Native app to reproduce issues or for testing purposes.
3+
4+
Requirements:
5+
1. npm i -g react-native-cli
6+
2. npm i -g code-push-cli
7+
3. code-push register
8+
9+
Usage: node create-app.js <appName> <reactNativeVersion> <reactNativeCodePushVersion>
10+
1. node create-app.js
11+
2. node create-app.js myapp
12+
3. node create-app.js myapp [email protected] [email protected]
13+
4. node create-app.js myapp react-native@latest Microsoft/react-native-code-push
14+
15+
Parameters:
16+
1. <appName> - CodePushDemoAppTest
17+
2. <reactNativeVersion> - react-native@latest
18+
3. <reactNativeCodePushVersion> - react-native-code-push@latest
19+
*/
20+
21+
let fs = require('fs');
22+
let path = require('path');
23+
let nexpect = require('./nexpect');
24+
let child_proces = require('child_process');
25+
let execSync = child_proces.execSync;
26+
27+
let args = process.argv.slice(2);
28+
let appName = args[0] || 'CodePushDemoAppTest';
29+
30+
if (fs.existsSync(appName)) {
31+
console.error(`Folder with name "${appName}" already exists! Please delete`);
32+
process.exit();
33+
}
34+
35+
let appNameAndroid = `${appName}-android`;
36+
let appNameIOS = `${appName}-ios`;
37+
let reactNativeVersion = args[1] || `react-native@${execSync('npm view react-native version')}`.trim();
38+
let reactNativeCodePushVersion = args[2] || `react-native-code-push@${execSync('npm view react-native-code-push version')}`.trim();
39+
40+
console.log(`App name: ${appName}`);
41+
console.log(`React Native version: ${reactNativeVersion}`);
42+
console.log(`React Native Module for CodePush version: ${reactNativeCodePushVersion} \n`);
43+
44+
let androidStagingDeploymentKey = null;
45+
let iosStagingDeploymentKey = null;
46+
47+
48+
49+
//GENERATE START
50+
createCodePushApp(appNameAndroid, 'android');
51+
createCodePushApp(appNameIOS, 'ios');
52+
53+
generatePlainReactNativeApp(appName, reactNativeVersion);
54+
process.chdir(appName);
55+
installCodePush(reactNativeCodePushVersion);
56+
linkCodePush(androidStagingDeploymentKey, iosStagingDeploymentKey);
57+
//GENERATE END
58+
59+
60+
61+
function createCodePushApp(name, platform) {
62+
try {
63+
console.log(`Creating CodePush app "${name}" to release updates for ${platform}...`);
64+
execSync(`code-push app add ${name} ${platform} react-native`);
65+
console.log(`App "${name}" has been created \n`);
66+
} catch (e) {
67+
console.log(`App "${name}" already exists \n`);
68+
}
69+
let deploymentKeys = JSON.parse(execSync(`code-push deployment ls ${name} -k --format json`));
70+
let stagingDeploymentKey = deploymentKeys[1].key;
71+
console.log(`Deployment key for ${platform}: ${stagingDeploymentKey}`);
72+
console.log(`Use "code-push release-react ${name} ${platform}" command to release updates for ${platform} \n`);
73+
74+
switch (platform) {
75+
case 'android':
76+
androidStagingDeploymentKey = stagingDeploymentKey;
77+
break;
78+
case 'ios':
79+
iosStagingDeploymentKey = stagingDeploymentKey;
80+
break;
81+
}
82+
}
83+
84+
function generatePlainReactNativeApp(appName, reactNativeVersion) {
85+
console.log(`Installing React Native...`);
86+
execSync(`react-native init ${appName} --version ${reactNativeVersion}`);
87+
console.log(`React Native has been installed \n`);
88+
}
89+
90+
function installCodePush(reactNativeCodePushVersion) {
91+
console.log(`Installing React Native Module for CodePush...`);
92+
execSync(`npm i --save ${reactNativeCodePushVersion}`);
93+
console.log(`React Native Module for CodePush has been installed \n`);
94+
}
95+
96+
function linkCodePush(androidStagingDeploymentKey, iosStagingDeploymentKey) {
97+
console.log(`Linking React Native Module for CodePush...`);
98+
nexpect.spawn(`react-native link react-native-code-push`)
99+
.wait("What is your CodePush deployment key for Android (hit <ENTER> to ignore)")
100+
.sendline(androidStagingDeploymentKey)
101+
.wait("What is your CodePush deployment key for iOS (hit <ENTER> to ignore)")
102+
.sendline(iosStagingDeploymentKey)
103+
.run(function (err) {
104+
if (!err) {
105+
console.log(`React Native Module for CodePush has been linked \n`);
106+
setupAssets();
107+
}
108+
else {
109+
console.log(err);
110+
}
111+
});
112+
}
113+
114+
function setupAssets() {
115+
fs.unlinkSync('./index.ios.js');
116+
fs.unlinkSync('./index.android.js');
117+
118+
fs.writeFileSync('demo.js', fs.readFileSync('../CodePushDemoApp/demo.js'));
119+
fs.writeFileSync('index.ios.js', fs.readFileSync('../CodePushDemoApp/index.ios.js'));
120+
fs.writeFileSync('index.android.js', fs.readFileSync('../CodePushDemoApp/index.android.js'));
121+
122+
copyRecursiveSync('../CodePushDemoApp/images', './images');
123+
124+
fs.readFile('demo.js', 'utf8', function (err, data) {
125+
if (err) {
126+
return console.error(err);
127+
}
128+
var result = data.replace(/CodePushDemoApp/g, appName);
129+
130+
fs.writeFile('demo.js', result, 'utf8', function (err) {
131+
if (err) return console.error(err);
132+
133+
if (!/^win/.test(process.platform)) {
134+
optimizeToTestInDebugMode();
135+
process.chdir('../');
136+
grantAccess(appName);
137+
}
138+
console.log(`\nReact Native app "${appName}" has been generated and CodePushified!`);
139+
process.exit();
140+
});
141+
});
142+
}
143+
144+
function optimizeToTestInDebugMode() {
145+
let rnXcodeShLocationFolder = 'scripts';
146+
try {
147+
let rnVersions = JSON.parse(execSync(`npm view react-native versions --json`));
148+
let currentRNversion = JSON.parse(fs.readFileSync('./package.json'))['dependencies']['react-native'];
149+
if (rnVersions.indexOf(currentRNversion) > -1 &&
150+
rnVersions.indexOf(currentRNversion) < rnVersions.indexOf("0.46.0-rc.0")) {
151+
rnXcodeShLocationFolder = 'packager';
152+
}
153+
} catch(e) {}
154+
155+
execSync(`perl -i -p0e 's/#ifdef DEBUG.*?#endif/jsCodeLocation = [CodePush bundleURL];/s' ios/${appName}/AppDelegate.m`);
156+
execSync(`sed -ie '17,20d' node_modules/react-native/${rnXcodeShLocationFolder}/react-native-xcode.sh`);
157+
execSync(`sed -ie 's/targetName.toLowerCase().contains("release")$/true/' node_modules/react-native/react.gradle`);
158+
}
159+
160+
function grantAccess(folderPath) {
161+
execSync('chown -R `whoami` ' + folderPath);
162+
execSync('chmod -R 755 ' + folderPath);
163+
}
164+
165+
function copyRecursiveSync(src, dest) {
166+
var exists = fs.existsSync(src);
167+
var stats = exists && fs.statSync(src);
168+
var isDirectory = exists && stats.isDirectory();
169+
if (exists && isDirectory) {
170+
fs.mkdirSync(dest);
171+
fs.readdirSync(src).forEach(function (childItemName) {
172+
copyRecursiveSync(path.join(src, childItemName),
173+
path.join(dest, childItemName));
174+
});
175+
} else {
176+
fs.linkSync(src, dest);
177+
}
178+
}

Examples/generate-app.sh

Lines changed: 0 additions & 63 deletions
This file was deleted.

0 commit comments

Comments
 (0)