@bravemobile/react-native-code-push 8.2.5 → 8.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.azurepipelines/test-rn-code-push.yml +94 -0
- package/CodePush.js +20 -21
- package/android/app/src/debug/AndroidManifest.xml +10 -0
- package/android/app/src/main/AndroidManifest.xml +1 -5
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateUtils.java +1 -1
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUtils.java +3 -1
- package/android/codepush.gradle +50 -14
- package/package.json +2 -2
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
trigger:
|
|
2
|
+
- master
|
|
3
|
+
|
|
4
|
+
pr:
|
|
5
|
+
- master
|
|
6
|
+
|
|
7
|
+
variables:
|
|
8
|
+
- name: api-level
|
|
9
|
+
value: '27'
|
|
10
|
+
|
|
11
|
+
pool:
|
|
12
|
+
vmImage: 'macOS-12'
|
|
13
|
+
|
|
14
|
+
stages:
|
|
15
|
+
- stage: RunTests
|
|
16
|
+
displayName: 'Run Android & IOS tests'
|
|
17
|
+
jobs:
|
|
18
|
+
- job: TestAndroid
|
|
19
|
+
timeoutInMinutes: 120
|
|
20
|
+
displayName: 'Test android'
|
|
21
|
+
steps:
|
|
22
|
+
|
|
23
|
+
- script: |
|
|
24
|
+
adb devices
|
|
25
|
+
displayName: 'Start adb server'
|
|
26
|
+
|
|
27
|
+
- script: |
|
|
28
|
+
$ANDROID_HOME/tools/bin/sdkmanager "system-images;android-$(api-level);google_apis;x86"
|
|
29
|
+
displayName: 'Download system image'
|
|
30
|
+
|
|
31
|
+
- script: |
|
|
32
|
+
$ANDROID_HOME/tools/bin/avdmanager create avd --force --name TestEmulator --abi google_apis/x86 --package 'system-images;android-$(api-level);google_apis;x86' --device "Nexus 6P"
|
|
33
|
+
displayName: 'Creating Android emulator'
|
|
34
|
+
|
|
35
|
+
- script: |
|
|
36
|
+
$ANDROID_HOME/emulator/emulator -avd TestEmulator -noaudio -no-window -no-snapshot-save -no-boot-anim -memory 6144 &
|
|
37
|
+
displayName: 'Start Android emulator'
|
|
38
|
+
|
|
39
|
+
- script: |
|
|
40
|
+
$ANDROID_HOME/platform-tools/adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed | tr -d '\r') ]]; do sleep 1; done'
|
|
41
|
+
displayName: 'Wait for emulator to boot'
|
|
42
|
+
|
|
43
|
+
- script: |
|
|
44
|
+
adb shell settings put global window_animation_scale 0.0
|
|
45
|
+
displayName: 'Disable animations and transitions'
|
|
46
|
+
|
|
47
|
+
- script: |
|
|
48
|
+
adb shell settings put global transition_animation_scale 0.0
|
|
49
|
+
displayName: 'Disable animations and transitions'
|
|
50
|
+
|
|
51
|
+
- script: |
|
|
52
|
+
adb shell settings put global animator_duration_scale 0.0
|
|
53
|
+
displayName: 'Disable animations and transitions'
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
- task: JavaToolInstaller@0
|
|
57
|
+
inputs:
|
|
58
|
+
versionSpec: '11'
|
|
59
|
+
jdkArchitectureOption: 'x64'
|
|
60
|
+
jdkSourceOption: 'PreInstalled'
|
|
61
|
+
displayName: 'Change Java version'
|
|
62
|
+
|
|
63
|
+
- script: |
|
|
64
|
+
npm install
|
|
65
|
+
displayName: 'Package Installation'
|
|
66
|
+
|
|
67
|
+
- script: |
|
|
68
|
+
npm run build:tests && npm run test:setup:android
|
|
69
|
+
displayName: 'Setup Android tests'
|
|
70
|
+
|
|
71
|
+
- script: |
|
|
72
|
+
npm run test:fast:android
|
|
73
|
+
displayName: 'Run Android test'
|
|
74
|
+
|
|
75
|
+
- job: TestIOS
|
|
76
|
+
timeoutInMinutes: 120
|
|
77
|
+
displayName: 'Test IOS'
|
|
78
|
+
steps:
|
|
79
|
+
|
|
80
|
+
- script: |
|
|
81
|
+
npm install
|
|
82
|
+
displayName: 'Install dependencies'
|
|
83
|
+
|
|
84
|
+
- script: |
|
|
85
|
+
npm run build:tests && npm run test:setup:ios
|
|
86
|
+
displayName: 'Setup iOS tests'
|
|
87
|
+
|
|
88
|
+
- script: |
|
|
89
|
+
npm run test:fast:ios
|
|
90
|
+
displayName: 'Run tests'
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
package/CodePush.js
CHANGED
|
@@ -625,42 +625,41 @@ function codePushify(options = {}) {
|
|
|
625
625
|
sharedCodePushOptions.setUpdateChecker(options.updateChecker);
|
|
626
626
|
sharedCodePushOptions.setFallbackToAppCenter(options.fallbackToAppCenter);
|
|
627
627
|
|
|
628
|
-
|
|
629
|
-
|
|
628
|
+
const decorator = (RootComponent) => {
|
|
629
|
+
class CodePushComponent extends React.Component {
|
|
630
|
+
constructor(props) {
|
|
631
|
+
super(props);
|
|
632
|
+
this.rootComponentRef = React.createRef();
|
|
633
|
+
}
|
|
634
|
+
|
|
630
635
|
componentDidMount() {
|
|
631
636
|
if (options.checkFrequency === CodePush.CheckFrequency.MANUAL) {
|
|
632
637
|
CodePush.notifyAppReady();
|
|
633
638
|
} else {
|
|
634
|
-
|
|
639
|
+
const rootComponentInstance = this.rootComponentRef.current;
|
|
635
640
|
|
|
636
641
|
let syncStatusCallback;
|
|
637
642
|
if (rootComponentInstance && rootComponentInstance.codePushStatusDidChange) {
|
|
638
|
-
syncStatusCallback = rootComponentInstance.codePushStatusDidChange;
|
|
639
|
-
if (rootComponentInstance instanceof React.Component) {
|
|
640
|
-
syncStatusCallback = syncStatusCallback.bind(rootComponentInstance);
|
|
641
|
-
}
|
|
643
|
+
syncStatusCallback = rootComponentInstance.codePushStatusDidChange.bind(rootComponentInstance);
|
|
642
644
|
}
|
|
643
645
|
|
|
644
646
|
let downloadProgressCallback;
|
|
645
647
|
if (rootComponentInstance && rootComponentInstance.codePushDownloadDidProgress) {
|
|
646
|
-
downloadProgressCallback = rootComponentInstance.codePushDownloadDidProgress;
|
|
647
|
-
if (rootComponentInstance instanceof React.Component) {
|
|
648
|
-
downloadProgressCallback = downloadProgressCallback.bind(rootComponentInstance);
|
|
649
|
-
}
|
|
648
|
+
downloadProgressCallback = rootComponentInstance.codePushDownloadDidProgress.bind(rootComponentInstance);
|
|
650
649
|
}
|
|
651
650
|
|
|
652
651
|
let handleBinaryVersionMismatchCallback;
|
|
653
652
|
if (rootComponentInstance && rootComponentInstance.codePushOnBinaryVersionMismatch) {
|
|
654
|
-
handleBinaryVersionMismatchCallback = rootComponentInstance.codePushOnBinaryVersionMismatch;
|
|
655
|
-
if (rootComponentInstance instanceof React.Component) {
|
|
656
|
-
handleBinaryVersionMismatchCallback = handleBinaryVersionMismatchCallback.bind(rootComponentInstance);
|
|
657
|
-
}
|
|
653
|
+
handleBinaryVersionMismatchCallback = rootComponentInstance.codePushOnBinaryVersionMismatch.bind(rootComponentInstance);
|
|
658
654
|
}
|
|
659
655
|
|
|
660
656
|
CodePush.sync(options, syncStatusCallback, downloadProgressCallback, handleBinaryVersionMismatchCallback);
|
|
657
|
+
|
|
661
658
|
if (options.checkFrequency === CodePush.CheckFrequency.ON_APP_RESUME) {
|
|
662
659
|
ReactNative.AppState.addEventListener("change", (newState) => {
|
|
663
|
-
newState === "active"
|
|
660
|
+
if (newState === "active") {
|
|
661
|
+
CodePush.sync(options, syncStatusCallback, downloadProgressCallback);
|
|
662
|
+
}
|
|
664
663
|
});
|
|
665
664
|
}
|
|
666
665
|
}
|
|
@@ -669,17 +668,17 @@ function codePushify(options = {}) {
|
|
|
669
668
|
render() {
|
|
670
669
|
const props = {...this.props};
|
|
671
670
|
|
|
672
|
-
//
|
|
673
|
-
//
|
|
674
|
-
if (RootComponent.prototype.render) {
|
|
675
|
-
props.ref =
|
|
671
|
+
// We can set ref property on class components only (not stateless)
|
|
672
|
+
// Check it by render method
|
|
673
|
+
if (RootComponent.prototype && RootComponent.prototype.render) {
|
|
674
|
+
props.ref = this.rootComponentRef;
|
|
676
675
|
}
|
|
677
676
|
|
|
678
677
|
return <RootComponent {...props} />
|
|
679
678
|
}
|
|
680
679
|
}
|
|
681
680
|
|
|
682
|
-
return hoistStatics(
|
|
681
|
+
return hoistStatics(CodePushComponent, RootComponent);
|
|
683
682
|
}
|
|
684
683
|
|
|
685
684
|
if (typeof options === "function") {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
2
|
+
package="com.microsoft.codepush.react">
|
|
3
|
+
|
|
4
|
+
<uses-permission android:name="android.permission.INTERNET" />
|
|
5
|
+
|
|
6
|
+
<application>
|
|
7
|
+
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
|
|
8
|
+
</application>
|
|
9
|
+
|
|
10
|
+
</manifest>
|
|
@@ -98,7 +98,7 @@ public class CodePushUpdateUtils {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
public static void copyNecessaryFilesFromCurrentPackage(String diffManifestFilePath, String currentPackageFolderPath, String newPackageFolderPath) throws IOException {
|
|
101
|
-
FileUtils.copyDirectoryContents(currentPackageFolderPath, newPackageFolderPath);
|
|
101
|
+
FileUtils.copyDirectoryContents(currentPackageFolderPath, newPackageFolderPath);
|
|
102
102
|
JSONObject diffManifest = CodePushUtils.getJsonObjectFromFile(diffManifestFilePath);
|
|
103
103
|
try {
|
|
104
104
|
JSONArray deletedFiles = diffManifest.getJSONArray("deletedFiles");
|
|
@@ -67,7 +67,9 @@ public class CodePushUtils {
|
|
|
67
67
|
String key = it.next();
|
|
68
68
|
Object obj = null;
|
|
69
69
|
try {
|
|
70
|
-
|
|
70
|
+
if (!jsonObj.isNull(key)) {
|
|
71
|
+
obj = jsonObj.get(key);
|
|
72
|
+
}
|
|
71
73
|
} catch (JSONException jsonException) {
|
|
72
74
|
// Should not happen.
|
|
73
75
|
throw new CodePushUnknownException("Key " + key + " should exist in " + jsonObj.toString() + ".", jsonException);
|
package/android/codepush.gradle
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import java.nio.file.Paths;
|
|
4
4
|
|
|
5
|
-
def config = project.extensions.findByName("react") ?: []
|
|
6
|
-
def bundleAssetName = config.bundleAssetName.get()
|
|
5
|
+
def config = project.extensions.findByName("react") ?: [:]
|
|
6
|
+
def bundleAssetName = config.bundleAssetName ? config.bundleAssetName.get() : "index.android.bundle"
|
|
7
7
|
|
|
8
8
|
// because elvis operator
|
|
9
9
|
def elvisFile(thing) {
|
|
@@ -17,6 +17,41 @@ void runBefore(String dependentTaskName, Task task) {
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Finds the path of the installed npm package with the given name using Node's
|
|
22
|
+
* module resolution algorithm, which searches "node_modules" directories up to
|
|
23
|
+
* the file system root. This handles various cases, including:
|
|
24
|
+
*
|
|
25
|
+
* - Working in the open-source RN repo:
|
|
26
|
+
* Gradle: /path/to/react-native/ReactAndroid
|
|
27
|
+
* Node module: /path/to/react-native/node_modules/[package]
|
|
28
|
+
*
|
|
29
|
+
* - Installing RN as a dependency of an app and searching for hoisted
|
|
30
|
+
* dependencies:
|
|
31
|
+
* Gradle: /path/to/app/node_modules/react-native/ReactAndroid
|
|
32
|
+
* Node module: /path/to/app/node_modules/[package]
|
|
33
|
+
*
|
|
34
|
+
* - Working in a larger repo (e.g., Facebook) that contains RN:
|
|
35
|
+
* Gradle: /path/to/repo/path/to/react-native/ReactAndroid
|
|
36
|
+
* Node module: /path/to/repo/node_modules/[package]
|
|
37
|
+
*
|
|
38
|
+
* The search begins at the given base directory (a File object). The returned
|
|
39
|
+
* path is a string.
|
|
40
|
+
*/
|
|
41
|
+
static def findNodeModulePath(baseDir, packageName) {
|
|
42
|
+
def basePath = baseDir.toPath().normalize()
|
|
43
|
+
// Node's module resolution algorithm searches up to the root directory,
|
|
44
|
+
// after which the base path will be null
|
|
45
|
+
while (basePath) {
|
|
46
|
+
def candidatePath = Paths.get(basePath.toString(), "node_modules", packageName)
|
|
47
|
+
if (candidatePath.toFile().exists()) {
|
|
48
|
+
return candidatePath.toString()
|
|
49
|
+
}
|
|
50
|
+
basePath = basePath.getParent()
|
|
51
|
+
}
|
|
52
|
+
return null
|
|
53
|
+
}
|
|
54
|
+
|
|
20
55
|
android.buildTypes.each { buildType ->
|
|
21
56
|
// to prevent incorrect long value restoration from strings.xml we need to wrap it with double quotes
|
|
22
57
|
// https://github.com/microsoft/cordova-plugin-code-push/issues/264
|
|
@@ -24,7 +59,7 @@ android.buildTypes.each { buildType ->
|
|
|
24
59
|
}
|
|
25
60
|
|
|
26
61
|
gradle.projectsEvaluated {
|
|
27
|
-
def debuggableVariants = config.debuggableVariants.get()
|
|
62
|
+
def debuggableVariants = config.debuggableVariants ? config.debuggableVariants.get() : ['debug']
|
|
28
63
|
|
|
29
64
|
android.applicationVariants.all { variant ->
|
|
30
65
|
// No code push for debuggable variants
|
|
@@ -34,11 +69,9 @@ gradle.projectsEvaluated {
|
|
|
34
69
|
|
|
35
70
|
def nodeModulesPath;
|
|
36
71
|
if (project.hasProperty('nodeModulesPath')) {
|
|
37
|
-
nodeModulesPath = project.nodeModulesPath
|
|
38
|
-
} else if (config.root) {
|
|
39
|
-
nodeModulesPath = Paths.get(config.root.asFile.get().absolutePath, "/node_modules");
|
|
72
|
+
nodeModulesPath = "${project.nodeModulesPath}/react-native-code-push"
|
|
40
73
|
} else {
|
|
41
|
-
nodeModulesPath = "
|
|
74
|
+
nodeModulesPath = findNodeModulePath(projectDir, "react-native-code-push")
|
|
42
75
|
}
|
|
43
76
|
|
|
44
77
|
def targetName = variant.name.capitalize()
|
|
@@ -49,8 +82,8 @@ gradle.projectsEvaluated {
|
|
|
49
82
|
def jsBundleFile;
|
|
50
83
|
|
|
51
84
|
// Additional node commandline arguments
|
|
52
|
-
def nodeExecutableAndArgs = config.nodeExecutableAndArgs.get()
|
|
53
|
-
def extraPackagerArgs = config.extraPackagerArgs.get()
|
|
85
|
+
def nodeExecutableAndArgs = config.nodeExecutableAndArgs ? config.nodeExecutableAndArgs.get(): ["node"]
|
|
86
|
+
def extraPackagerArgs = config.extraPackagerArgs ? config.extraPackagerArgs.get() : []
|
|
54
87
|
|
|
55
88
|
// Make this task run right after the bundle task
|
|
56
89
|
def generateBundledResourcesHash;
|
|
@@ -59,6 +92,9 @@ gradle.projectsEvaluated {
|
|
|
59
92
|
if (reactBundleTask) {
|
|
60
93
|
jsBundleDir = reactBundleTask.property('jsBundleDir').asFile.get()
|
|
61
94
|
resourcesDir = reactBundleTask.property('resourcesDir').asFile.get()
|
|
95
|
+
|
|
96
|
+
// mitigates Resource and asset merger: Duplicate resources error
|
|
97
|
+
project.delete(files("${jsBundleDir}"))
|
|
62
98
|
|
|
63
99
|
jsBundleDir.mkdirs()
|
|
64
100
|
resourcesDir.mkdirs()
|
|
@@ -68,7 +104,7 @@ gradle.projectsEvaluated {
|
|
|
68
104
|
generateBundledResourcesHash = tasks.create(
|
|
69
105
|
name: "generateBundledResourcesHash${targetName}",
|
|
70
106
|
type: Exec) {
|
|
71
|
-
commandLine (*nodeExecutableAndArgs, "${nodeModulesPath}/
|
|
107
|
+
commandLine (*nodeExecutableAndArgs, "${nodeModulesPath}/scripts/generateBundledResourcesHash.js", resourcesDir, jsBundleFile, jsBundleDir)
|
|
72
108
|
|
|
73
109
|
enabled !debuggableVariants.contains(variant.name) ?: targetName.toLowerCase().contains("release")
|
|
74
110
|
}
|
|
@@ -77,11 +113,11 @@ gradle.projectsEvaluated {
|
|
|
77
113
|
runBefore("merge${targetName}Assets", generateBundledResourcesHash)
|
|
78
114
|
} else {
|
|
79
115
|
def jsBundleDirConfigName = "jsBundleDir${targetName}"
|
|
80
|
-
jsBundleDir = elvisFile(config."$jsBundleDirConfigName").get()
|
|
116
|
+
jsBundleDir = elvisFile(config."$jsBundleDirConfigName") ? elvisFile(config."$jsBundleDirConfigName").get():
|
|
81
117
|
file("$buildDir/intermediates/assets/${targetPath}")
|
|
82
118
|
|
|
83
119
|
def resourcesDirConfigName = "resourcesDir${targetName}"
|
|
84
|
-
resourcesDir = elvisFile(config."${resourcesDirConfigName}").get()
|
|
120
|
+
resourcesDir = elvisFile(config."${resourcesDirConfigName}") ? elvisFile(config."${resourcesDirConfigName}").get():
|
|
85
121
|
file("$buildDir/intermediates/res/merged/${targetPath}")
|
|
86
122
|
|
|
87
123
|
// In case version of 'Android Plugin for Gradle'' is lower than 1.3.0
|
|
@@ -98,14 +134,14 @@ gradle.projectsEvaluated {
|
|
|
98
134
|
generateBundledResourcesHash = tasks.create(
|
|
99
135
|
name: "generateBundledResourcesHash${targetName}",
|
|
100
136
|
type: Exec) {
|
|
101
|
-
commandLine (*nodeExecutableAndArgs, "${nodeModulesPath}/
|
|
137
|
+
commandLine (*nodeExecutableAndArgs, "${nodeModulesPath}/scripts/generateBundledResourcesHash.js", resourcesDir, jsBundleFile, jsBundleDir, resourcesMapTempFileName)
|
|
102
138
|
}
|
|
103
139
|
|
|
104
140
|
// Make this task run right before the bundle task
|
|
105
141
|
def recordFilesBeforeBundleCommand = tasks.create(
|
|
106
142
|
name: "recordFilesBeforeBundleCommand${targetName}",
|
|
107
143
|
type: Exec) {
|
|
108
|
-
commandLine (*nodeExecutableAndArgs, "${nodeModulesPath}/
|
|
144
|
+
commandLine (*nodeExecutableAndArgs, "${nodeModulesPath}/scripts/recordFilesBeforeBundleCommand.js", resourcesDir, resourcesMapTempFileName)
|
|
109
145
|
}
|
|
110
146
|
|
|
111
147
|
recordFilesBeforeBundleCommand.dependsOn("merge${targetName}Resources")
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bravemobile/react-native-code-push",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.3.1",
|
|
4
4
|
"description": "React Native plugin for the CodePush service",
|
|
5
5
|
"main": "CodePush.js",
|
|
6
6
|
"typings": "typings/react-native-code-push.d.ts",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"url": "https://github.com/Soomgo-Mobile/react-native-code-push"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"code-push": "^4.2.
|
|
39
|
+
"code-push": "^4.2.2",
|
|
40
40
|
"glob": "^7.1.7",
|
|
41
41
|
"hoist-non-react-statics": "^3.3.2",
|
|
42
42
|
"inquirer": "^8.1.5",
|