@appzung/react-native-code-push 6.4.2 → 8.3.2
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/build-rn-code-push-1es.yml +104 -0
- package/.azurepipelines/test-rn-code-push.yml +94 -0
- package/.config/CredScanSuppressions.json +14 -0
- package/CONTRIBUTING.md +3 -3
- package/CodePush.js +26 -28
- package/CodePush.podspec +1 -1
- package/README.md +8 -7
- package/SECURITY.md +41 -0
- package/android/app/build.gradle +1 -1
- package/android/app/src/main/AndroidManifest.xml +1 -5
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java +14 -5
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushConstants.java +1 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushNativeModule.java +19 -1
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateUtils.java +5 -4
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUtils.java +3 -1
- package/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java +8 -9
- package/android/build.gradle +3 -2
- package/android/codepush.gradle +79 -30
- package/docs/api-js.md +1 -1
- package/docs/setup-android.md +27 -3
- package/docs/setup-ios.md +1 -1
- package/docs/setup-windows.md +59 -3
- package/ios/CodePush/CodePushPackage.m +4 -0
- package/ios/CodePush/CodePushUpdateUtils.m +1 -1
- package/ios/CodePush.xcodeproj/project.pbxproj +2 -2
- package/package.json +11 -11
- package/typings/react-native-code-push.d.ts +1 -1
- package/windows/CodePush/CodePush.def +3 -0
- package/windows/CodePush/CodePush.vcxproj +198 -0
- package/windows/CodePush/CodePush.vcxproj.filters +91 -0
- package/windows/CodePush/CodePushConfig.cpp +104 -0
- package/windows/CodePush/CodePushConfig.h +66 -0
- package/windows/CodePush/CodePushConfig.idl +12 -0
- package/windows/CodePush/CodePushDownloadHandler.cpp +73 -0
- package/windows/CodePush/CodePushDownloadHandler.h +32 -0
- package/windows/CodePush/CodePushNativeModule.cpp +934 -0
- package/windows/CodePush/CodePushNativeModule.h +247 -0
- package/windows/CodePush/CodePushPackage.cpp +456 -0
- package/windows/CodePush/CodePushPackage.h +49 -0
- package/windows/CodePush/CodePushTelemetryManager.cpp +213 -0
- package/windows/CodePush/CodePushTelemetryManager.h +29 -0
- package/windows/CodePush/CodePushUpdateUtils.cpp +86 -0
- package/windows/CodePush/CodePushUpdateUtils.h +38 -0
- package/windows/CodePush/CodePushUtils.cpp +29 -0
- package/windows/CodePush/CodePushUtils.h +18 -0
- package/windows/CodePush/FileUtils.cpp +131 -0
- package/windows/CodePush/FileUtils.h +28 -0
- package/windows/CodePush/PropertySheet.props +16 -0
- package/windows/CodePush/ReactPackageProvider.cpp +15 -0
- package/windows/CodePush/ReactPackageProvider.h +22 -0
- package/windows/CodePush/ReactPackageProvider.idl +9 -0
- package/windows/CodePush/miniz/LICENSE +22 -0
- package/windows/CodePush/miniz/miniz.c +7657 -0
- package/windows/CodePush/miniz/miniz.h +1338 -0
- package/windows/CodePush/miniz/readme.md +37 -0
- package/windows/CodePush/packages.config +4 -0
- package/windows/CodePush/pch.cpp +1 -0
- package/windows/CodePush/pch.h +4 -0
- package/{windows → windows-legacy}/CodePush/CodePush.csproj +1 -1
- package/{windows → windows-legacy}/CodePush.Net46/CodePush.Net46.csproj +2 -2
- package/{windows → windows-legacy}/CodePush.Net46/packages.config +1 -1
- package/windows-legacy/CodePush.Net46.Test/ApplicationDataContainerTest.cs +105 -0
- package/windows-legacy/CodePush.Net46.Test/CodePush.Net46.Test.csproj +137 -0
- package/windows-legacy/CodePush.Net46.Test/Properties/AssemblyInfo.cs +36 -0
- package/windows-legacy/CodePush.Net46.Test/TelemetryManagerTest.cs +117 -0
- package/windows-legacy/CodePush.Net46.Test/app.config +11 -0
- package/windows-legacy/CodePush.Net46.Test/packages.config +4 -0
- /package/{windows → windows-legacy}/CodePush/CodePushUtils.cs +0 -0
- /package/{windows → windows-legacy}/CodePush/FileUtils.cs +0 -0
- /package/{windows → windows-legacy}/CodePush/Properties/AssemblyInfo.cs +0 -0
- /package/{windows → windows-legacy}/CodePush/Properties/CodePush.rd.xml +0 -0
- /package/{windows → windows-legacy}/CodePush/UpdateManager.cs +0 -0
- /package/{windows → windows-legacy}/CodePush/UpdateUtils.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Net46/Adapters/Http/HttpProgress.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Net46/Adapters/Storage/ApplicationDataContainer.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Net46/CodePushUtils.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Net46/FileUtils.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Net46/Properties/AssemblyInfo.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Net46/UpdateManager.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Net46/UpdateUtils.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Shared/CodePush.Shared.projitems +0 -0
- /package/{windows → windows-legacy}/CodePush.Shared/CodePush.Shared.shproj +0 -0
- /package/{windows → windows-legacy}/CodePush.Shared/CodePushConstants.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Shared/CodePushNativeModule.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Shared/CodePushReactPackage.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Shared/CodePushUtils.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Shared/InstallMode.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Shared/MinimumBackgroundListener.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Shared/SettingsManager.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Shared/TelemetryManager.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Shared/UpdateState.cs +0 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
trigger:
|
|
2
|
+
- master
|
|
3
|
+
|
|
4
|
+
pr:
|
|
5
|
+
- master
|
|
6
|
+
|
|
7
|
+
resources:
|
|
8
|
+
repositories:
|
|
9
|
+
- repository: 1ESPipelineTemplates
|
|
10
|
+
type: git
|
|
11
|
+
name: 1ESPipelineTemplates/1ESPipelineTemplates
|
|
12
|
+
ref: refs/tags/release
|
|
13
|
+
name: $(Build.SourceBranchName)_$(date:yyyyMMdd)$(rev:.r)
|
|
14
|
+
|
|
15
|
+
extends:
|
|
16
|
+
${{ if eq(variables['Build.SourceBranch'], 'refs/heads/master') }}:
|
|
17
|
+
template: v1/1ES.Official.PipelineTemplate.yml@1ESPipelineTemplates
|
|
18
|
+
${{ else }}:
|
|
19
|
+
template: v1/1ES.Unofficial.PipelineTemplate.yml@1ESPipelineTemplates
|
|
20
|
+
parameters:
|
|
21
|
+
pool:
|
|
22
|
+
name: 1ES-PT-CBL-Mariner-2.0-Gen2
|
|
23
|
+
os: linux
|
|
24
|
+
customBuildTags:
|
|
25
|
+
- ES365AIMigrationTooling-BulkMigrated
|
|
26
|
+
sdl:
|
|
27
|
+
sourceAnalysisPool: 1ES-PT-Windows-2022
|
|
28
|
+
credscan:
|
|
29
|
+
suppressionsFile: $(Build.SourcesDirectory)/.config/CredScanSuppressions.json
|
|
30
|
+
stages:
|
|
31
|
+
- stage: Stage
|
|
32
|
+
jobs:
|
|
33
|
+
- job: HostJob
|
|
34
|
+
templateContext:
|
|
35
|
+
outputs:
|
|
36
|
+
- output: pipelineArtifact
|
|
37
|
+
displayName: "Publish Artifact: artifacts"
|
|
38
|
+
path: '$(Build.ArtifactStagingDirectory)/npm'
|
|
39
|
+
artifactName: npm
|
|
40
|
+
|
|
41
|
+
steps:
|
|
42
|
+
- task: NodeTool@0
|
|
43
|
+
inputs:
|
|
44
|
+
versionSpec: '14.x'
|
|
45
|
+
displayName: 'Install Node.js'
|
|
46
|
+
|
|
47
|
+
- script: |
|
|
48
|
+
npm pack
|
|
49
|
+
npm install -g react-native-code-push*.tgz
|
|
50
|
+
displayName: 'Package react-native-code-push'
|
|
51
|
+
workingDirectory: $(Build.SourcesDirectory)
|
|
52
|
+
|
|
53
|
+
- task: DeleteFiles@1
|
|
54
|
+
inputs:
|
|
55
|
+
contents: node_modules
|
|
56
|
+
displayName: 'Delete node_modules'
|
|
57
|
+
|
|
58
|
+
- task: ArchiveFiles@2
|
|
59
|
+
inputs:
|
|
60
|
+
rootFolderOrFile: '$(Build.SourcesDirectory)'
|
|
61
|
+
includeRootFolder: false
|
|
62
|
+
archiveType: 'tar'
|
|
63
|
+
archiveFile: '$(Build.ArtifactStagingDirectory)/npm/$(Build.BuildId).tgz'
|
|
64
|
+
replaceExistingArchive: true
|
|
65
|
+
verbose: true
|
|
66
|
+
displayName: 'Prepare npm artifact'
|
|
67
|
+
|
|
68
|
+
- stage: APIScan
|
|
69
|
+
dependsOn: Stage
|
|
70
|
+
pool:
|
|
71
|
+
name: 1ES-PT-Windows-2022
|
|
72
|
+
os: windows
|
|
73
|
+
variables:
|
|
74
|
+
"agent.source.skip": true
|
|
75
|
+
jobs:
|
|
76
|
+
- job: APIScan
|
|
77
|
+
steps:
|
|
78
|
+
- task: DownloadPipelineArtifact@2
|
|
79
|
+
displayName: Download Build Artifacts for APIScan
|
|
80
|
+
inputs:
|
|
81
|
+
artifactName: npm
|
|
82
|
+
targetPath: '$(Agent.BuildDirectory)/npm'
|
|
83
|
+
- task: ExtractFiles@1
|
|
84
|
+
inputs:
|
|
85
|
+
archiveFilePatterns: '$(Agent.BuildDirectory)/npm/*.tgz'
|
|
86
|
+
destinationFolder: '$(Agent.BuildDirectory)/npm_extracted'
|
|
87
|
+
- task: AzureKeyVault@2
|
|
88
|
+
inputs:
|
|
89
|
+
azureSubscription: 'AC - Dev Infra & Build Pool'
|
|
90
|
+
KeyVaultName: 'mobile-center-sdk'
|
|
91
|
+
SecretsFilter: 'appcenter-sdk-managed-identity-clientid'
|
|
92
|
+
RunAsPreJob: false
|
|
93
|
+
- task: APIScan@2
|
|
94
|
+
displayName: 'Run APIScan'
|
|
95
|
+
inputs:
|
|
96
|
+
softwareFolder: '$(Agent.BuildDirectory)\npm_extracted'
|
|
97
|
+
softwareName: 'react-native-code-push'
|
|
98
|
+
softwareVersionNum: '$(Build.BuildId)'
|
|
99
|
+
isLargeApp: false
|
|
100
|
+
toolVersion: 'Latest'
|
|
101
|
+
verbosityLevel: verbose
|
|
102
|
+
condition: and(succeeded(), ne(variables['DisableAPIScan'], 'true'))
|
|
103
|
+
env:
|
|
104
|
+
AzureServicesAuthConnectionString: 'runAs=App;AppId=$(appcenter-sdk-managed-identity-clientid)'
|
|
@@ -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
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tool": "Credential Scanner",
|
|
3
|
+
"suppressions": [
|
|
4
|
+
{
|
|
5
|
+
"file": "/Examples/CodePushDemoApp/android/app/debug.keystore",
|
|
6
|
+
"_justification": "Used only in DemoApp"
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"file": "/Examples/CodePushDemoAppCpp/windows/CodePushDemoAppCpp/CodePushDemoAppCpp_TemporaryKey.pfx",
|
|
10
|
+
"_justification": "Used only in DemoApp"
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
|
package/CONTRIBUTING.md
CHANGED
|
@@ -37,10 +37,10 @@ Follow these steps to test your modifications to the plugin manually:
|
|
|
37
37
|
|
|
38
38
|
First, make sure you have installed the dependencies for the plugin by following the steps above.
|
|
39
39
|
|
|
40
|
-
Then, make sure you have installed `react-native
|
|
40
|
+
Then, make sure you have installed `react-native`.
|
|
41
41
|
|
|
42
42
|
```
|
|
43
|
-
npm install -g react-native
|
|
43
|
+
npm install -g react-native
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
To run Android tests, make sure you have `sdk\tools`, `sdk\emulator` and `sdk\platform-tools` in your PATH.
|
|
@@ -131,4 +131,4 @@ To run the core unit tests on Android and pull the plugin from NPM:
|
|
|
131
131
|
NPM=true CORE=true npm run test:android
|
|
132
132
|
```
|
|
133
133
|
|
|
134
|
-
...and so on!
|
|
134
|
+
...and so on!
|
package/CodePush.js
CHANGED
|
@@ -180,7 +180,7 @@ async function notifyApplicationReadyInternal() {
|
|
|
180
180
|
return statusReport;
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
-
async function tryReportStatus(statusReport,
|
|
183
|
+
async function tryReportStatus(statusReport, retryOnAppResume) {
|
|
184
184
|
const config = await getConfiguration();
|
|
185
185
|
const previousLabelOrAppVersion = statusReport.previousLabelOrAppVersion;
|
|
186
186
|
const previousDeploymentKey = statusReport.previousDeploymentKey || config.deploymentKey;
|
|
@@ -209,22 +209,21 @@ async function tryReportStatus(statusReport, resumeListener) {
|
|
|
209
209
|
}
|
|
210
210
|
|
|
211
211
|
NativeCodePush.recordStatusReported(statusReport);
|
|
212
|
-
|
|
212
|
+
retryOnAppResume && retryOnAppResume.remove();
|
|
213
213
|
} catch (e) {
|
|
214
214
|
log(`Report status failed: ${JSON.stringify(statusReport)}`);
|
|
215
215
|
NativeCodePush.saveStatusReportForRetry(statusReport);
|
|
216
216
|
// Try again when the app resumes
|
|
217
|
-
if (!
|
|
218
|
-
resumeListener = async (newState) => {
|
|
217
|
+
if (!retryOnAppResume) {
|
|
218
|
+
const resumeListener = AppState.addEventListener("change", async (newState) => {
|
|
219
219
|
if (newState !== "active") return;
|
|
220
220
|
const refreshedStatusReport = await NativeCodePush.getNewStatusReport();
|
|
221
221
|
if (refreshedStatusReport) {
|
|
222
222
|
tryReportStatus(refreshedStatusReport, resumeListener);
|
|
223
223
|
} else {
|
|
224
|
-
|
|
224
|
+
resumeListener && resumeListener.remove();
|
|
225
225
|
}
|
|
226
|
-
};
|
|
227
|
-
AppState.addEventListener("change", resumeListener);
|
|
226
|
+
});
|
|
228
227
|
}
|
|
229
228
|
}
|
|
230
229
|
}
|
|
@@ -532,42 +531,41 @@ function codePushify(options = {}) {
|
|
|
532
531
|
);
|
|
533
532
|
}
|
|
534
533
|
|
|
535
|
-
|
|
536
|
-
|
|
534
|
+
const decorator = (RootComponent) => {
|
|
535
|
+
class CodePushComponent extends React.Component {
|
|
536
|
+
constructor(props) {
|
|
537
|
+
super(props);
|
|
538
|
+
this.rootComponentRef = React.createRef();
|
|
539
|
+
}
|
|
540
|
+
|
|
537
541
|
componentDidMount() {
|
|
538
542
|
if (options.checkFrequency === CodePush.CheckFrequency.MANUAL) {
|
|
539
543
|
CodePush.notifyAppReady();
|
|
540
544
|
} else {
|
|
541
|
-
|
|
545
|
+
const rootComponentInstance = this.rootComponentRef.current;
|
|
542
546
|
|
|
543
547
|
let syncStatusCallback;
|
|
544
548
|
if (rootComponentInstance && rootComponentInstance.codePushStatusDidChange) {
|
|
545
|
-
syncStatusCallback = rootComponentInstance.codePushStatusDidChange;
|
|
546
|
-
if (rootComponentInstance instanceof React.Component) {
|
|
547
|
-
syncStatusCallback = syncStatusCallback.bind(rootComponentInstance);
|
|
548
|
-
}
|
|
549
|
+
syncStatusCallback = rootComponentInstance.codePushStatusDidChange.bind(rootComponentInstance);
|
|
549
550
|
}
|
|
550
551
|
|
|
551
552
|
let downloadProgressCallback;
|
|
552
553
|
if (rootComponentInstance && rootComponentInstance.codePushDownloadDidProgress) {
|
|
553
|
-
downloadProgressCallback = rootComponentInstance.codePushDownloadDidProgress;
|
|
554
|
-
if (rootComponentInstance instanceof React.Component) {
|
|
555
|
-
downloadProgressCallback = downloadProgressCallback.bind(rootComponentInstance);
|
|
556
|
-
}
|
|
554
|
+
downloadProgressCallback = rootComponentInstance.codePushDownloadDidProgress.bind(rootComponentInstance);
|
|
557
555
|
}
|
|
558
556
|
|
|
559
557
|
let handleBinaryVersionMismatchCallback;
|
|
560
558
|
if (rootComponentInstance && rootComponentInstance.codePushOnBinaryVersionMismatch) {
|
|
561
|
-
handleBinaryVersionMismatchCallback = rootComponentInstance.codePushOnBinaryVersionMismatch;
|
|
562
|
-
if (rootComponentInstance instanceof React.Component) {
|
|
563
|
-
handleBinaryVersionMismatchCallback = handleBinaryVersionMismatchCallback.bind(rootComponentInstance);
|
|
564
|
-
}
|
|
559
|
+
handleBinaryVersionMismatchCallback = rootComponentInstance.codePushOnBinaryVersionMismatch.bind(rootComponentInstance);
|
|
565
560
|
}
|
|
566
561
|
|
|
567
562
|
CodePush.sync(options, syncStatusCallback, downloadProgressCallback, handleBinaryVersionMismatchCallback);
|
|
563
|
+
|
|
568
564
|
if (options.checkFrequency === CodePush.CheckFrequency.ON_APP_RESUME) {
|
|
569
565
|
ReactNative.AppState.addEventListener("change", (newState) => {
|
|
570
|
-
newState === "active"
|
|
566
|
+
if (newState === "active") {
|
|
567
|
+
CodePush.sync(options, syncStatusCallback, downloadProgressCallback);
|
|
568
|
+
}
|
|
571
569
|
});
|
|
572
570
|
}
|
|
573
571
|
}
|
|
@@ -576,17 +574,17 @@ function codePushify(options = {}) {
|
|
|
576
574
|
render() {
|
|
577
575
|
const props = {...this.props};
|
|
578
576
|
|
|
579
|
-
//
|
|
580
|
-
//
|
|
581
|
-
if (RootComponent.prototype.render) {
|
|
582
|
-
props.ref =
|
|
577
|
+
// We can set ref property on class components only (not stateless)
|
|
578
|
+
// Check it by render method
|
|
579
|
+
if (RootComponent.prototype && RootComponent.prototype.render) {
|
|
580
|
+
props.ref = this.rootComponentRef;
|
|
583
581
|
}
|
|
584
582
|
|
|
585
583
|
return <RootComponent {...props} />
|
|
586
584
|
}
|
|
587
585
|
}
|
|
588
586
|
|
|
589
|
-
return hoistStatics(
|
|
587
|
+
return hoistStatics(CodePushComponent, RootComponent);
|
|
590
588
|
}
|
|
591
589
|
|
|
592
590
|
if (typeof options === "function") {
|
package/CodePush.podspec
CHANGED
|
@@ -10,7 +10,7 @@ Pod::Spec.new do |s|
|
|
|
10
10
|
s.license = package['license']
|
|
11
11
|
s.homepage = package['homepage']
|
|
12
12
|
s.source = { :git => 'https://github.com/appzung/react-native-code-push.git', :tag => "v#{s.version}"}
|
|
13
|
-
s.ios.deployment_target = '
|
|
13
|
+
s.ios.deployment_target = '9.0'
|
|
14
14
|
s.tvos.deployment_target = '9.0'
|
|
15
15
|
s.preserve_paths = '*.js'
|
|
16
16
|
s.library = 'z'
|
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ This plugin provides client-side integration for the [CodePush service](https://
|
|
|
39
39
|
|
|
40
40
|
## How does it work?
|
|
41
41
|
|
|
42
|
-
A React Native app is composed of JavaScript files and any accompanying [images](https://
|
|
42
|
+
A React Native app is composed of JavaScript files and any accompanying [images](https://reactnative.dev/docs/image), which are bundled together by the [metro bundler](https://github.com/facebook/metro) and distributed as part of a platform-specific binary (i.e. an `.ipa` or `.apk` file). Once the app is released, updating either the JavaScript code (e.g. making bug fixes, adding new features) or image assets, requires you to recompile and redistribute the entire binary, which of course, includes any review time associated with the store(s) you are publishing to.
|
|
43
43
|
|
|
44
44
|
The CodePush plugin helps get product improvements in front of your end users instantly, by keeping your JavaScript and images synchronized with updates you release to the CodePush server. This way, your app gets the benefits of an offline mobile experience, as well as the "web-like" agility of side-loading updates as soon as they are available. It's a win-win!
|
|
45
45
|
|
|
@@ -74,7 +74,9 @@ We try our best to maintain backwards compatibility of our plugin with previous
|
|
|
74
74
|
| v0.56-v0.58 | v5.4+ *(RN upgraded versions for Android tools)* |
|
|
75
75
|
| v0.59 | v5.6+ *(RN refactored js bundle loader code)* |
|
|
76
76
|
| v0.60-v0.61 | v6.0+ *(RN migrated to Autolinking)* |
|
|
77
|
-
| v0.62-v0.
|
|
77
|
+
| v0.62-v0.64 | v6.2+ *(RN removed LiveReload)* |
|
|
78
|
+
| v0.65-v0.70 | v7.0+ *(RN updated iPhone-target-version)* |
|
|
79
|
+
| v0.71 | v8.0+ *(RN moved to react-native-gradle-plugin)* |
|
|
78
80
|
|
|
79
81
|
*NOTE: `react-native-code-push` versions lower than **[v5.7.0](https://github.com/microsoft/react-native-code-push/releases/tag/v5.7.0)** will stop working in the near future. You can find more information in our [documentation](https://github.com/microsoft/code-push/blob/master/migration-notice.md).*
|
|
80
82
|
|
|
@@ -250,7 +252,7 @@ Android Google Play and iOS App Store have corresponding guidelines that have ru
|
|
|
250
252
|
|
|
251
253
|
#### Google play
|
|
252
254
|
|
|
253
|
-
Third paragraph of [Device and Network Abuse](https://support.google.com/googleplay/android-developer/answer/9888379?hl=en) topic describe that updating source code by any method other than Google Play's update mechanism is restricted. But this restriction
|
|
255
|
+
Third paragraph of [Device and Network Abuse](https://support.google.com/googleplay/android-developer/answer/9888379?hl=en) topic describe that updating source code by any method other than Google Play's update mechanism is restricted. But this restriction does not apply to updating javascript bundles.
|
|
254
256
|
> This restriction does not apply to code that runs in a virtual machine and has limited access to Android APIs (such as JavaScript in a webview or browser).
|
|
255
257
|
|
|
256
258
|
That fully allow CodePush as it updates just JS bundles and can't update native code part.
|
|
@@ -275,7 +277,7 @@ Once your app is configured and distributed to your users, and you have made som
|
|
|
275
277
|
|
|
276
278
|
*NOTE: Before you can start releasing updates, please log into App Center by running the `appcenter login` command.*
|
|
277
279
|
|
|
278
|
-
In
|
|
280
|
+
In its most basic form, this command only requires one parameter: your owner name + "/" + app name.
|
|
279
281
|
|
|
280
282
|
```shell
|
|
281
283
|
appcenter codepush release-react -a <ownerName>/<appName>
|
|
@@ -386,7 +388,6 @@ The React Native community has graciously created some awesome open source apps
|
|
|
386
388
|
|
|
387
389
|
Additionally, if you're looking to get started with React Native + CodePush, and are looking for an awesome starter kit, you should check out the following:
|
|
388
390
|
|
|
389
|
-
* [Native Starter Pro](http://strapmobile.com/native-starter-pro/)
|
|
390
391
|
* [Pepperoni](http://getpepperoni.com/)
|
|
391
392
|
|
|
392
393
|
*Note: If you've developed a React Native app using CodePush, that is also open-source, please let us know. We would love to add it to this list!*
|
|
@@ -426,12 +427,12 @@ Now you'll be able to see CodePush logs in either debug or release mode, on both
|
|
|
426
427
|
|
|
427
428
|
### Continuous Integration / Delivery
|
|
428
429
|
|
|
429
|
-
In addition to being able to use the CodePush CLI to "manually" release updates, we believe that it's important to create a repeatable and sustainable solution for contiously delivering updates to your app. That way, it's simple enough for you and/or your team to create and maintain the rhythm of performing agile deployments. In order to assist with
|
|
430
|
+
In addition to being able to use the CodePush CLI to "manually" release updates, we believe that it's important to create a repeatable and sustainable solution for contiously delivering updates to your app. That way, it's simple enough for you and/or your team to create and maintain the rhythm of performing agile deployments. In order to assist with setting up a CodePush-based CD pipeline, refer to the following integrations with various CI servers:
|
|
430
431
|
|
|
431
432
|
* [Visual Studio Team Services](https://marketplace.visualstudio.com/items?itemName=ms-vsclient.code-push) - *NOTE: VSTS also has extensions for publishing to [HockeyApp](https://marketplace.visualstudio.com/items?itemName=ms.hockeyapp) and the [Google Play](https://github.com/microsoft/google-play-vsts-extension) store, so it provides a pretty great mobile CD solution in general.*
|
|
432
433
|
* [Travis CI](https://github.com/mondora/code-push-travis-cli)
|
|
433
434
|
|
|
434
|
-
Additionally, if you'd like more details of what a complete mobile CI/CD workflow can look like, which includes CodePush, check out this [excellent article](https://zeemee
|
|
435
|
+
Additionally, if you'd like more details of what a complete mobile CI/CD workflow can look like, which includes CodePush, check out this [excellent article](https://medium.com/zeemee-engineering/zeemee-engineering-and-the-quest-for-the-holy-mobile-dev-grail-1310be4953d1) by the [ZeeMee engineering team](https://www.zeemee.com/).
|
|
435
436
|
|
|
436
437
|
### TypeScript Consumption
|
|
437
438
|
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.5 BLOCK -->
|
|
2
|
+
|
|
3
|
+
## Security
|
|
4
|
+
|
|
5
|
+
Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
|
|
6
|
+
|
|
7
|
+
If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below.
|
|
8
|
+
|
|
9
|
+
## Reporting Security Issues
|
|
10
|
+
|
|
11
|
+
**Please do not report security vulnerabilities through public GitHub issues.**
|
|
12
|
+
|
|
13
|
+
Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report).
|
|
14
|
+
|
|
15
|
+
If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc).
|
|
16
|
+
|
|
17
|
+
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc).
|
|
18
|
+
|
|
19
|
+
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
|
|
20
|
+
|
|
21
|
+
* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
|
|
22
|
+
* Full paths of source file(s) related to the manifestation of the issue
|
|
23
|
+
* The location of the affected source code (tag/branch/commit or direct URL)
|
|
24
|
+
* Any special configuration required to reproduce the issue
|
|
25
|
+
* Step-by-step instructions to reproduce the issue
|
|
26
|
+
* Proof-of-concept or exploit code (if possible)
|
|
27
|
+
* Impact of the issue, including how an attacker might exploit the issue
|
|
28
|
+
|
|
29
|
+
This information will help us triage your report more quickly.
|
|
30
|
+
|
|
31
|
+
If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs.
|
|
32
|
+
|
|
33
|
+
## Preferred Languages
|
|
34
|
+
|
|
35
|
+
We prefer all communications to be in English.
|
|
36
|
+
|
|
37
|
+
## Policy
|
|
38
|
+
|
|
39
|
+
Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd).
|
|
40
|
+
|
|
41
|
+
<!-- END MICROSOFT SECURITY.MD BLOCK -->
|
package/android/app/build.gradle
CHANGED
|
@@ -10,8 +10,8 @@ import com.facebook.react.ReactPackage;
|
|
|
10
10
|
import com.facebook.react.bridge.JavaScriptModule;
|
|
11
11
|
import com.facebook.react.bridge.NativeModule;
|
|
12
12
|
import com.facebook.react.bridge.ReactApplicationContext;
|
|
13
|
-
import com.facebook.react.devsupport.DevInternalSettings;
|
|
14
13
|
import com.facebook.react.devsupport.interfaces.DevSupportManager;
|
|
14
|
+
import com.facebook.react.modules.debug.interfaces.DeveloperSettings;
|
|
15
15
|
import com.facebook.react.uimanager.ViewManager;
|
|
16
16
|
|
|
17
17
|
import org.json.JSONException;
|
|
@@ -152,12 +152,12 @@ public class CodePush implements ReactPackage {
|
|
|
152
152
|
if (instanceManager != null) {
|
|
153
153
|
DevSupportManager devSupportManager = instanceManager.getDevSupportManager();
|
|
154
154
|
if (devSupportManager != null) {
|
|
155
|
-
|
|
156
|
-
Method[] methods =
|
|
155
|
+
DeveloperSettings devSettings = devSupportManager.getDevSettings();
|
|
156
|
+
Method[] methods = devSettings.getClass().getMethods();
|
|
157
157
|
for (Method m : methods) {
|
|
158
158
|
if (m.getName().equals("isReloadOnJSChangeEnabled")) {
|
|
159
159
|
try {
|
|
160
|
-
return (boolean) m.invoke(
|
|
160
|
+
return (boolean) m.invoke(devSettings);
|
|
161
161
|
} catch (Exception x) {
|
|
162
162
|
return false;
|
|
163
163
|
}
|
|
@@ -295,7 +295,16 @@ public class CodePush implements ReactPackage {
|
|
|
295
295
|
|
|
296
296
|
JSONObject pendingUpdate = mSettingsManager.getPendingUpdate();
|
|
297
297
|
if (pendingUpdate != null) {
|
|
298
|
-
JSONObject packageMetadata =
|
|
298
|
+
JSONObject packageMetadata = null;
|
|
299
|
+
|
|
300
|
+
try {
|
|
301
|
+
packageMetadata = this.mUpdateManager.getCurrentPackage();
|
|
302
|
+
} catch (CodePushMalformedDataException e) {
|
|
303
|
+
// We need to recover the app in case 'codepush.json' is corrupted
|
|
304
|
+
CodePushUtils.log(e);
|
|
305
|
+
clearUpdates();
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
299
308
|
if (packageMetadata == null || !isPackageBundleLatest(packageMetadata) && hasBinaryVersionChanged(packageMetadata)) {
|
|
300
309
|
CodePushUtils.log("Skipping initializeUpdateAfterRestart(), binary version is newer");
|
|
301
310
|
return;
|
|
@@ -31,4 +31,5 @@ public class CodePushConstants {
|
|
|
31
31
|
public static final String LATEST_ROLLBACK_PACKAGE_HASH_KEY = "packageHash";
|
|
32
32
|
public static final String LATEST_ROLLBACK_TIME_KEY = "time";
|
|
33
33
|
public static final String LATEST_ROLLBACK_COUNT_KEY = "count";
|
|
34
|
+
public static final String CLIENT_UNIQUE_ID_KEY = "clientUniqueId";
|
|
34
35
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
package com.microsoft.codepush.react;
|
|
2
2
|
|
|
3
3
|
import android.app.Activity;
|
|
4
|
+
import android.content.SharedPreferences;
|
|
4
5
|
import android.os.AsyncTask;
|
|
5
6
|
import android.os.Handler;
|
|
6
7
|
import android.os.Looper;
|
|
@@ -34,6 +35,7 @@ import java.util.Date;
|
|
|
34
35
|
import java.util.HashMap;
|
|
35
36
|
import java.util.List;
|
|
36
37
|
import java.util.Map;
|
|
38
|
+
import java.util.UUID;
|
|
37
39
|
|
|
38
40
|
public class CodePushNativeModule extends ReactContextBaseJavaModule {
|
|
39
41
|
private String mBinaryContentsHash = null;
|
|
@@ -60,7 +62,13 @@ public class CodePushNativeModule extends ReactContextBaseJavaModule {
|
|
|
60
62
|
|
|
61
63
|
// Initialize module state while we have a reference to the current context.
|
|
62
64
|
mBinaryContentsHash = CodePushUpdateUtils.getHashForBinaryContents(reactContext, mCodePush.isDebugMode());
|
|
63
|
-
|
|
65
|
+
|
|
66
|
+
SharedPreferences preferences = codePush.getContext().getSharedPreferences(CodePushConstants.CODE_PUSH_PREFERENCES, 0);
|
|
67
|
+
mClientUniqueId = preferences.getString(CodePushConstants.CLIENT_UNIQUE_ID_KEY, null);
|
|
68
|
+
if (mClientUniqueId == null) {
|
|
69
|
+
mClientUniqueId = UUID.randomUUID().toString();
|
|
70
|
+
preferences.edit().putString(CodePushConstants.CLIENT_UNIQUE_ID_KEY, mClientUniqueId).apply();
|
|
71
|
+
}
|
|
64
72
|
}
|
|
65
73
|
|
|
66
74
|
@Override
|
|
@@ -693,4 +701,14 @@ public class CodePushNativeModule extends ReactContextBaseJavaModule {
|
|
|
693
701
|
CodePushUtils.log("Clearing updates.");
|
|
694
702
|
mCodePush.clearUpdates();
|
|
695
703
|
}
|
|
704
|
+
|
|
705
|
+
@ReactMethod
|
|
706
|
+
public void addListener(String eventName) {
|
|
707
|
+
// Set up any upstream listeners or background tasks as necessary
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
@ReactMethod
|
|
711
|
+
public void removeListeners(Integer count) {
|
|
712
|
+
// Remove upstream listeners, stop unnecessary background tasks
|
|
713
|
+
}
|
|
696
714
|
}
|
|
@@ -3,11 +3,12 @@ package com.microsoft.codepush.react;
|
|
|
3
3
|
import android.content.Context;
|
|
4
4
|
import android.util.Base64;
|
|
5
5
|
|
|
6
|
+
import com.nimbusds.jose.JWSVerifier;
|
|
7
|
+
import com.nimbusds.jose.crypto.RSASSAVerifier;
|
|
8
|
+
import com.nimbusds.jwt.SignedJWT;
|
|
9
|
+
|
|
6
10
|
import java.security.interfaces.*;
|
|
7
11
|
|
|
8
|
-
import com.nimbusds.jose.*;
|
|
9
|
-
import com.nimbusds.jose.crypto.*;
|
|
10
|
-
import com.nimbusds.jwt.*;
|
|
11
12
|
|
|
12
13
|
import org.json.JSONArray;
|
|
13
14
|
import org.json.JSONException;
|
|
@@ -97,7 +98,7 @@ public class CodePushUpdateUtils {
|
|
|
97
98
|
}
|
|
98
99
|
|
|
99
100
|
public static void copyNecessaryFilesFromCurrentPackage(String diffManifestFilePath, String currentPackageFolderPath, String newPackageFolderPath) throws IOException {
|
|
100
|
-
FileUtils.copyDirectoryContents(currentPackageFolderPath, newPackageFolderPath);
|
|
101
|
+
FileUtils.copyDirectoryContents(currentPackageFolderPath, newPackageFolderPath);
|
|
101
102
|
JSONObject diffManifest = CodePushUtils.getJsonObjectFromFile(diffManifestFilePath);
|
|
102
103
|
try {
|
|
103
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);
|
|
@@ -123,14 +123,13 @@ public class FileUtils {
|
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
private static String validateFileName(String fileName,
|
|
127
|
-
|
|
128
|
-
String canonicalPath = file.getCanonicalPath();
|
|
126
|
+
private static String validateFileName(String fileName, File destinationFolder) throws IOException {
|
|
127
|
+
String destinationFolderCanonicalPath = destinationFolder.getCanonicalPath() + File.separator;
|
|
129
128
|
|
|
130
|
-
File
|
|
131
|
-
String
|
|
129
|
+
File file = new File(destinationFolderCanonicalPath, fileName);
|
|
130
|
+
String canonicalPath = file.getCanonicalPath();
|
|
132
131
|
|
|
133
|
-
if (!canonicalPath.startsWith(
|
|
132
|
+
if (!canonicalPath.startsWith(destinationFolderCanonicalPath)) {
|
|
134
133
|
throw new IllegalStateException("File is outside extraction target directory.");
|
|
135
134
|
}
|
|
136
135
|
|
|
@@ -151,13 +150,13 @@ public class FileUtils {
|
|
|
151
150
|
if (destinationFolder.exists()) {
|
|
152
151
|
deleteFileOrFolderSilently(destinationFolder);
|
|
153
152
|
}
|
|
154
|
-
|
|
153
|
+
|
|
155
154
|
destinationFolder.mkdirs();
|
|
156
155
|
|
|
157
156
|
byte[] buffer = new byte[WRITE_BUFFER_SIZE];
|
|
158
157
|
while ((entry = zipStream.getNextEntry()) != null) {
|
|
159
|
-
String fileName = validateFileName(entry.getName(),
|
|
160
|
-
File file = new File(
|
|
158
|
+
String fileName = validateFileName(entry.getName(), destinationFolder);
|
|
159
|
+
File file = new File(fileName);
|
|
161
160
|
if (entry.isDirectory()) {
|
|
162
161
|
file.mkdirs();
|
|
163
162
|
} else {
|