@algocare/react-native-code-push 9.0.0-beta.6 → 9.1.0
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/cli/commands/bundleCommand/index.js +54 -28
- package/cli/commands/createHistoryCommand/index.js +42 -31
- package/cli/commands/releaseCommand/index.js +105 -62
- package/cli/commands/showHistoryCommand/index.js +42 -31
- package/cli/commands/updateHistoryCommand/index.js +57 -55
- package/code-push.config.js +25 -17
- package/code-push.config.ts +24 -17
- package/package.json +1 -1
|
@@ -1,29 +1,55 @@
|
|
|
1
|
-
const { program
|
|
2
|
-
const
|
|
3
|
-
const {
|
|
1
|
+
const { program } = require('commander')
|
|
2
|
+
const inquirer = require('inquirer').default
|
|
3
|
+
const { bundleCodePush } = require('./bundleCodePush')
|
|
4
|
+
const {
|
|
5
|
+
OUTPUT_BUNDLE_DIR,
|
|
6
|
+
ROOT_OUTPUT_DIR,
|
|
7
|
+
ENTRY_FILE,
|
|
8
|
+
} = require('../../constant')
|
|
4
9
|
|
|
5
|
-
program
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
10
|
+
program
|
|
11
|
+
.command('bundle')
|
|
12
|
+
.description('Creates a CodePush bundle file (assumes Hermes is enabled).')
|
|
13
|
+
.option(
|
|
14
|
+
'-o, --output-path <string>',
|
|
15
|
+
'path to output root directory',
|
|
16
|
+
ROOT_OUTPUT_DIR
|
|
17
|
+
)
|
|
18
|
+
.option('-e, --entry-file <string>', 'path to JS/TS entry file', ENTRY_FILE)
|
|
19
|
+
.option(
|
|
20
|
+
'-b, --bundle-name <string>',
|
|
21
|
+
'bundle file name (default-ios: "main.jsbundle" / default-android: "index.android.bundle")'
|
|
22
|
+
)
|
|
23
|
+
.option(
|
|
24
|
+
'--output-bundle-dir <string>',
|
|
25
|
+
'name of directory containing the bundle file created by the "bundle" command',
|
|
26
|
+
OUTPUT_BUNDLE_DIR
|
|
27
|
+
)
|
|
28
|
+
.action(async (options) => {
|
|
29
|
+
const answers = await inquirer.prompt([
|
|
30
|
+
{
|
|
31
|
+
type: 'list',
|
|
32
|
+
name: 'app',
|
|
33
|
+
message: 'Select the target app',
|
|
34
|
+
choices: ['user', 'device'],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
type: 'list',
|
|
38
|
+
name: 'platform',
|
|
39
|
+
message: 'Select the target platform',
|
|
40
|
+
choices: ['ios', 'android'],
|
|
41
|
+
when: (answers) => answers.app !== 'device',
|
|
42
|
+
},
|
|
43
|
+
])
|
|
44
|
+
if (answers.app === 'device') {
|
|
45
|
+
answers.platform = 'android'
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
bundleCodePush(
|
|
49
|
+
answers.platform,
|
|
50
|
+
options.outputPath,
|
|
51
|
+
options.entryFile,
|
|
52
|
+
options.bundleName,
|
|
53
|
+
`${options.outputPath}/${options.outputBundleDir}`
|
|
54
|
+
)
|
|
55
|
+
})
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
const { program
|
|
1
|
+
const { program } = require('commander')
|
|
2
|
+
const inquirer = require('inquirer').default
|
|
2
3
|
const { findAndReadConfigFile } = require('../../utils/fsUtils')
|
|
3
4
|
const { createReleaseHistory } = require('./createReleaseHistory')
|
|
4
5
|
const { COMPILED_CONFIG_FILE_NAME } = require('../../constant')
|
|
@@ -6,45 +7,55 @@ const { COMPILED_CONFIG_FILE_NAME } = require('../../constant')
|
|
|
6
7
|
program
|
|
7
8
|
.command('create-history')
|
|
8
9
|
.description('Creates a new release history for the binary app.')
|
|
9
|
-
.requiredOption(
|
|
10
|
-
'-a, --app <string>',
|
|
11
|
-
'(Required) The target app: user or device'
|
|
12
|
-
)
|
|
13
|
-
.requiredOption(
|
|
14
|
-
'-b, --binary-version <string>',
|
|
15
|
-
'(Required) The target binary version'
|
|
16
|
-
)
|
|
17
|
-
.addOption(
|
|
18
|
-
new Option('-p, --platform <type>', 'platform')
|
|
19
|
-
.choices(['ios', 'android'])
|
|
20
|
-
.default('ios')
|
|
21
|
-
)
|
|
22
|
-
.option(
|
|
23
|
-
'-i, --identifier <string>',
|
|
24
|
-
'reserved characters to distinguish the release.'
|
|
25
|
-
)
|
|
26
10
|
.option(
|
|
27
11
|
'-c, --config <path>',
|
|
28
12
|
'set config file name (JS/TS)',
|
|
29
13
|
COMPILED_CONFIG_FILE_NAME
|
|
30
14
|
)
|
|
31
|
-
/**
|
|
32
|
-
* @param {Object} options
|
|
33
|
-
* @param {string} options.app
|
|
34
|
-
* @param {string} options.binaryVersion
|
|
35
|
-
* @param {string} options.platform
|
|
36
|
-
* @param {string} options.identifier
|
|
37
|
-
* @param {string} options.config
|
|
38
|
-
* @return {void}
|
|
39
|
-
*/
|
|
40
15
|
.action(async (options) => {
|
|
16
|
+
const answers = await inquirer.prompt([
|
|
17
|
+
{
|
|
18
|
+
type: 'list',
|
|
19
|
+
name: 'app',
|
|
20
|
+
message: 'Select the target app',
|
|
21
|
+
choices: ['user', 'device'],
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
type: 'list',
|
|
25
|
+
name: 'platform',
|
|
26
|
+
message: 'Select the target platform',
|
|
27
|
+
choices: ['ios', 'android'],
|
|
28
|
+
when: (answers) => answers.app !== 'device',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
type: 'list',
|
|
32
|
+
name: 'identifier',
|
|
33
|
+
message: 'Select the target env identifier',
|
|
34
|
+
choices: ['stg', 'prd'],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
type: 'input',
|
|
38
|
+
name: 'binaryVersion',
|
|
39
|
+
message: 'Enter the target binary version',
|
|
40
|
+
validate: (input) => {
|
|
41
|
+
const semverRegex = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/
|
|
42
|
+
if (semverRegex.test(input)) return true
|
|
43
|
+
return 'Please enter a valid version number (x.y.z)'
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
])
|
|
47
|
+
|
|
48
|
+
if (answers.app === 'device') {
|
|
49
|
+
answers.platform = 'android'
|
|
50
|
+
}
|
|
51
|
+
|
|
41
52
|
const config = await findAndReadConfigFile(process.cwd(), options.config)
|
|
42
53
|
|
|
43
54
|
await createReleaseHistory(
|
|
44
|
-
|
|
45
|
-
|
|
55
|
+
answers.app,
|
|
56
|
+
answers.binaryVersion,
|
|
46
57
|
config.setReleaseHistory,
|
|
47
|
-
|
|
48
|
-
|
|
58
|
+
answers.platform,
|
|
59
|
+
answers.identifier
|
|
49
60
|
)
|
|
50
61
|
})
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
const { program
|
|
1
|
+
const { program } = require('commander')
|
|
2
|
+
const inquirer = require('inquirer').default
|
|
2
3
|
const { findAndReadConfigFile } = require('../../utils/fsUtils')
|
|
3
4
|
const { release } = require('./release')
|
|
4
5
|
const {
|
|
@@ -13,27 +14,11 @@ program
|
|
|
13
14
|
.description(
|
|
14
15
|
'Deploys a new CodePush update for a target binary app.\nAfter creating the CodePush bundle, it uploads the file and updates the ReleaseHistory information.\n`bundleUploader`, `getReleaseHistory`, and `setReleaseHistory` functions should be implemented in the config file.'
|
|
15
16
|
)
|
|
16
|
-
.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
)
|
|
20
|
-
.
|
|
21
|
-
'-b, --binary-version <string>',
|
|
22
|
-
'(Required) The target binary version'
|
|
23
|
-
)
|
|
24
|
-
.requiredOption(
|
|
25
|
-
'-v, --app-version <string>',
|
|
26
|
-
'(Required) The app version to be released. It must be greater than the binary version.'
|
|
27
|
-
)
|
|
28
|
-
.addOption(
|
|
29
|
-
new Option('-p, --platform <type>', 'platform')
|
|
30
|
-
.choices(['ios', 'android'])
|
|
31
|
-
.default('ios')
|
|
32
|
-
)
|
|
33
|
-
.option(
|
|
34
|
-
'-i, --identifier <string>',
|
|
35
|
-
'reserved characters to distinguish the release.'
|
|
36
|
-
)
|
|
17
|
+
.option('-a, --app <string>', 'target app (user/device)')
|
|
18
|
+
.option('-p, --platform <string>', 'target platform (ios/android)')
|
|
19
|
+
.option('-i, --identifier <string>', 'target env identifier (stg/prd)')
|
|
20
|
+
.option('-b, --binary-version <string>', 'target binary version (x.y.z)')
|
|
21
|
+
.option('-v, --app-version <string>', 'target codepush version (x.y.z)')
|
|
37
22
|
.option(
|
|
38
23
|
'-c, --config <path>',
|
|
39
24
|
'set config file name (JS/TS)',
|
|
@@ -49,55 +34,119 @@ program
|
|
|
49
34
|
'-j, --js-bundle-name <string>',
|
|
50
35
|
'JS bundle file name (default-ios: "main.jsbundle" / default-android: "index.android.bundle")'
|
|
51
36
|
)
|
|
37
|
+
.option('-m, --mandatory', 'make the release to be mandatory', false)
|
|
52
38
|
.option(
|
|
53
|
-
'
|
|
54
|
-
'make the release to be
|
|
55
|
-
parseBoolean,
|
|
56
|
-
false
|
|
57
|
-
)
|
|
58
|
-
.option(
|
|
59
|
-
'--enable <bool>',
|
|
60
|
-
'make the release to be enabled',
|
|
61
|
-
parseBoolean,
|
|
39
|
+
'--enable',
|
|
40
|
+
'make the release to be enabled (use --no-enable to disable)',
|
|
62
41
|
true
|
|
63
42
|
)
|
|
64
|
-
.option('--
|
|
65
|
-
.option('--skip-
|
|
43
|
+
.option('--no-enable', 'make the release to be disabled')
|
|
44
|
+
.option('--skip-bundle', 'skip bundle process', false)
|
|
45
|
+
.option('--skip-cleanup', 'skip cleanup process', false)
|
|
66
46
|
.option(
|
|
67
47
|
'--output-bundle-dir <string>',
|
|
68
48
|
'name of directory containing the bundle file created by the "bundle" command',
|
|
69
49
|
OUTPUT_BUNDLE_DIR
|
|
70
50
|
)
|
|
71
|
-
/**
|
|
72
|
-
* @param {Object} options
|
|
73
|
-
* @param {string} options.app
|
|
74
|
-
* @param {string} options.binaryVersion
|
|
75
|
-
* @param {string} options.appVersion
|
|
76
|
-
* @param {string} options.platform
|
|
77
|
-
* @param {string} options.identifier
|
|
78
|
-
* @param {string} options.config
|
|
79
|
-
* @param {string} options.outputPath
|
|
80
|
-
* @param {string} options.entryFile
|
|
81
|
-
* @param {string} options.bundleName
|
|
82
|
-
* @param {string} options.mandatory
|
|
83
|
-
* @param {string} options.enable
|
|
84
|
-
* @param {string} options.skipBundle
|
|
85
|
-
* @param {string} options.skipCleanup
|
|
86
|
-
* @param {string} options.outputBundleDir
|
|
87
|
-
* @return {void}
|
|
88
|
-
*/
|
|
89
51
|
.action(async (options) => {
|
|
52
|
+
if (options.app && !['user', 'device'].includes(options.app)) {
|
|
53
|
+
throw new Error('App must be either "user" or "device"')
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (options.platform && !['ios', 'android'].includes(options.platform)) {
|
|
57
|
+
throw new Error('Platform must be either "ios" or "android"')
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (options.app === 'device' && options.platform === 'ios') {
|
|
61
|
+
throw new Error('Device app is not supported on iOS')
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (options.identifier && !['stg', 'prd'].includes(options.identifier)) {
|
|
65
|
+
throw new Error('Identifier must be either "stg" or "prd"')
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const semverRegex = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/
|
|
69
|
+
if (options.binaryVersion && !semverRegex.test(options.binaryVersion)) {
|
|
70
|
+
throw new Error('Binary version must be a valid semver format (x.y.z)')
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (options.appVersion && !semverRegex.test(options.appVersion)) {
|
|
74
|
+
throw new Error('App version must be a valid semver format (x.y.z)')
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
let answers = {}
|
|
78
|
+
|
|
79
|
+
if (
|
|
80
|
+
options.app &&
|
|
81
|
+
options.identifier &&
|
|
82
|
+
options.binaryVersion &&
|
|
83
|
+
options.appVersion &&
|
|
84
|
+
(options.app === 'device' || options.platform)
|
|
85
|
+
) {
|
|
86
|
+
answers = {
|
|
87
|
+
app: options.app,
|
|
88
|
+
platform: options.platform || (options.app === 'device' && 'android'),
|
|
89
|
+
identifier: options.identifier,
|
|
90
|
+
binaryVersion: options.binaryVersion,
|
|
91
|
+
appVersion: options.appVersion,
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
answers = await inquirer.prompt([
|
|
95
|
+
{
|
|
96
|
+
type: 'list',
|
|
97
|
+
name: 'app',
|
|
98
|
+
message: 'Select the target app',
|
|
99
|
+
choices: ['user', 'device'],
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
type: 'list',
|
|
103
|
+
name: 'platform',
|
|
104
|
+
message: 'Select the target platform',
|
|
105
|
+
choices: ['ios', 'android'],
|
|
106
|
+
when: (answers) => answers.app !== 'device',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
type: 'list',
|
|
110
|
+
name: 'identifier',
|
|
111
|
+
message: 'Select the target env identifier',
|
|
112
|
+
choices: ['stg', 'prd'],
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
type: 'input',
|
|
116
|
+
name: 'binaryVersion',
|
|
117
|
+
message: 'Enter the target binary version',
|
|
118
|
+
validate: (input) => {
|
|
119
|
+
if (semverRegex.test(input)) return true
|
|
120
|
+
return 'Please enter a valid version number (x.y.z)'
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
type: 'input',
|
|
125
|
+
name: 'appVersion',
|
|
126
|
+
message: 'Enter the target codepush version',
|
|
127
|
+
validate: (input) => {
|
|
128
|
+
if (semverRegex.test(input)) return true
|
|
129
|
+
return 'Please enter a valid version number (x.y.z)'
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
])
|
|
133
|
+
|
|
134
|
+
if (answers.app === 'device') {
|
|
135
|
+
answers.platform = 'android'
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
90
139
|
const config = await findAndReadConfigFile(process.cwd(), options.config)
|
|
91
140
|
|
|
92
141
|
await release(
|
|
93
142
|
config.bundleUploader,
|
|
94
143
|
config.getReleaseHistory,
|
|
95
144
|
config.setReleaseHistory,
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
145
|
+
answers.app,
|
|
146
|
+
answers.binaryVersion,
|
|
147
|
+
answers.appVersion,
|
|
148
|
+
answers.platform,
|
|
149
|
+
answers.identifier,
|
|
101
150
|
options.outputPath,
|
|
102
151
|
options.entryFile,
|
|
103
152
|
options.bundleName,
|
|
@@ -110,9 +159,3 @@ program
|
|
|
110
159
|
|
|
111
160
|
console.log('🚀 Release completed.')
|
|
112
161
|
})
|
|
113
|
-
|
|
114
|
-
function parseBoolean(value) {
|
|
115
|
-
if (value === 'true') return true
|
|
116
|
-
if (value === 'false') return false
|
|
117
|
-
else return undefined
|
|
118
|
-
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
const { program
|
|
1
|
+
const { program } = require('commander')
|
|
2
|
+
const inquirer = require('inquirer').default
|
|
2
3
|
const { findAndReadConfigFile } = require('../../utils/fsUtils')
|
|
3
4
|
const { COMPILED_CONFIG_FILE_NAME } = require('../../constant')
|
|
4
5
|
|
|
@@ -7,45 +8,55 @@ program
|
|
|
7
8
|
.description(
|
|
8
9
|
'Retrieves and prints the release history of a specific binary version.\n`getReleaseHistory` function should be implemented in the config file.'
|
|
9
10
|
)
|
|
10
|
-
.requiredOption(
|
|
11
|
-
'-a, --app <string>',
|
|
12
|
-
'(Required) The target app: user or device'
|
|
13
|
-
)
|
|
14
|
-
.requiredOption(
|
|
15
|
-
'-b, --binary-version <string>',
|
|
16
|
-
'(Required) The target binary version for retrieving the release history.'
|
|
17
|
-
)
|
|
18
|
-
.addOption(
|
|
19
|
-
new Option('-p, --platform <type>', 'platform')
|
|
20
|
-
.choices(['ios', 'android'])
|
|
21
|
-
.default('ios')
|
|
22
|
-
)
|
|
23
|
-
.option(
|
|
24
|
-
'-i, --identifier <string>',
|
|
25
|
-
'reserved characters to distinguish the release.'
|
|
26
|
-
)
|
|
27
11
|
.option(
|
|
28
12
|
'-c, --config <path>',
|
|
29
13
|
'configuration file name (JS/TS)',
|
|
30
14
|
COMPILED_CONFIG_FILE_NAME
|
|
31
15
|
)
|
|
32
|
-
/**
|
|
33
|
-
* @param {Object} options
|
|
34
|
-
* @param {string} options.app
|
|
35
|
-
* @param {string} options.binaryVersion
|
|
36
|
-
* @param {string} options.platform
|
|
37
|
-
* @param {string} options.identifier
|
|
38
|
-
* @param {string} options.config
|
|
39
|
-
* @return {void}
|
|
40
|
-
*/
|
|
41
16
|
.action(async (options) => {
|
|
17
|
+
const answers = await inquirer.prompt([
|
|
18
|
+
{
|
|
19
|
+
type: 'list',
|
|
20
|
+
name: 'app',
|
|
21
|
+
message: 'Select the target app',
|
|
22
|
+
choices: ['user', 'device'],
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
type: 'list',
|
|
26
|
+
name: 'platform',
|
|
27
|
+
message: 'Select the target platform',
|
|
28
|
+
choices: ['ios', 'android'],
|
|
29
|
+
when: (answers) => answers.app !== 'device',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
type: 'list',
|
|
33
|
+
name: 'identifier',
|
|
34
|
+
message: 'Select the target env identifier',
|
|
35
|
+
choices: ['stg', 'prd'],
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
type: 'input',
|
|
39
|
+
name: 'binaryVersion',
|
|
40
|
+
message: 'Enter the target binary version',
|
|
41
|
+
validate: (input) => {
|
|
42
|
+
const semverRegex = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/
|
|
43
|
+
if (semverRegex.test(input)) return true
|
|
44
|
+
return 'Please enter a valid version number (x.y.z)'
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
])
|
|
48
|
+
|
|
49
|
+
if (answers.app === 'device') {
|
|
50
|
+
answers.platform = 'android'
|
|
51
|
+
}
|
|
52
|
+
|
|
42
53
|
const config = await findAndReadConfigFile(process.cwd(), options.config)
|
|
43
54
|
|
|
44
55
|
const releaseHistory = await config.getReleaseHistory(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
56
|
+
answers.app,
|
|
57
|
+
answers.binaryVersion,
|
|
58
|
+
answers.platform,
|
|
59
|
+
answers.identifier
|
|
49
60
|
)
|
|
50
61
|
|
|
51
62
|
console.log(JSON.stringify(releaseHistory, null, 2))
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
const { program
|
|
1
|
+
const { program } = require('commander')
|
|
2
|
+
const inquirer = require('inquirer').default
|
|
2
3
|
const { findAndReadConfigFile } = require('../../utils/fsUtils')
|
|
3
4
|
const { updateReleaseHistory } = require('./updateReleaseHistory')
|
|
4
5
|
const { COMPILED_CONFIG_FILE_NAME } = require('../../constant')
|
|
@@ -8,57 +9,64 @@ program
|
|
|
8
9
|
.description(
|
|
9
10
|
'Updates the release history for a specific binary version.\n`getReleaseHistory`, `setReleaseHistory` functions should be implemented in the config file.'
|
|
10
11
|
)
|
|
11
|
-
.requiredOption(
|
|
12
|
-
'-a, --app <string>',
|
|
13
|
-
'(Required) The target app: user or device'
|
|
14
|
-
)
|
|
15
|
-
.requiredOption(
|
|
16
|
-
'-v, --app-version <string>',
|
|
17
|
-
'(Required) The app version for which update information is to be modified.'
|
|
18
|
-
)
|
|
19
|
-
.requiredOption(
|
|
20
|
-
'-b, --binary-version <string>',
|
|
21
|
-
'(Required) The target binary version of the app for which update information is to be modified.'
|
|
22
|
-
)
|
|
23
|
-
.addOption(
|
|
24
|
-
new Option('-p, --platform <type>', 'platform')
|
|
25
|
-
.choices(['ios', 'android'])
|
|
26
|
-
.default('ios')
|
|
27
|
-
)
|
|
28
|
-
.option(
|
|
29
|
-
'-i, --identifier <string>',
|
|
30
|
-
'reserved characters to distinguish the release.'
|
|
31
|
-
)
|
|
32
12
|
.option(
|
|
33
13
|
'-c, --config <path>',
|
|
34
14
|
'set config file name (JS/TS)',
|
|
35
15
|
COMPILED_CONFIG_FILE_NAME
|
|
36
16
|
)
|
|
17
|
+
.option('-m, --mandatory', 'make the release to be mandatory', false)
|
|
37
18
|
.option(
|
|
38
|
-
'-
|
|
39
|
-
'make the release to be
|
|
40
|
-
|
|
41
|
-
undefined
|
|
19
|
+
'-e, --enable',
|
|
20
|
+
'make the release to be enabled (use --no-enable to disable)',
|
|
21
|
+
true
|
|
42
22
|
)
|
|
43
|
-
.option(
|
|
44
|
-
'-e, --enable <bool>',
|
|
45
|
-
'make the release to be enabled',
|
|
46
|
-
parseBoolean,
|
|
47
|
-
undefined
|
|
48
|
-
)
|
|
49
|
-
/**
|
|
50
|
-
* @param {Object} options
|
|
51
|
-
* @param {string} options.app
|
|
52
|
-
* @param {string} options.appVersion
|
|
53
|
-
* @param {string} options.binaryVersion
|
|
54
|
-
* @param {string} options.platform
|
|
55
|
-
* @param {string} options.identifier
|
|
56
|
-
* @param {string} options.config
|
|
57
|
-
* @param {string} options.mandatory
|
|
58
|
-
* @param {string} options.enable
|
|
59
|
-
* @return {void}
|
|
60
|
-
*/
|
|
23
|
+
.option('--no-enable', 'make the release to be disabled')
|
|
61
24
|
.action(async (options) => {
|
|
25
|
+
const semverRegex = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/
|
|
26
|
+
const answers = await inquirer.prompt([
|
|
27
|
+
{
|
|
28
|
+
type: 'list',
|
|
29
|
+
name: 'app',
|
|
30
|
+
message: 'Select the target app',
|
|
31
|
+
choices: ['user', 'device'],
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
type: 'list',
|
|
35
|
+
name: 'platform',
|
|
36
|
+
message: 'Select the target platform',
|
|
37
|
+
choices: ['ios', 'android'],
|
|
38
|
+
when: (answers) => answers.app !== 'device',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
type: 'list',
|
|
42
|
+
name: 'identifier',
|
|
43
|
+
message: 'Select the target env identifier',
|
|
44
|
+
choices: ['stg', 'prd'],
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
type: 'input',
|
|
48
|
+
name: 'binaryVersion',
|
|
49
|
+
message: 'Enter the target binary version',
|
|
50
|
+
validate: (input) => {
|
|
51
|
+
if (semverRegex.test(input)) return true
|
|
52
|
+
return 'Please enter a valid version number (x.y.z)'
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
type: 'input',
|
|
57
|
+
name: 'appVersion',
|
|
58
|
+
message: 'Enter the target codepush version',
|
|
59
|
+
validate: (input) => {
|
|
60
|
+
if (semverRegex.test(input)) return true
|
|
61
|
+
return 'Please enter a valid version number (x.y.z)'
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
])
|
|
65
|
+
|
|
66
|
+
if (answers.app === 'device') {
|
|
67
|
+
answers.platform = 'android'
|
|
68
|
+
}
|
|
69
|
+
|
|
62
70
|
const config = await findAndReadConfigFile(process.cwd(), options.config)
|
|
63
71
|
|
|
64
72
|
if (
|
|
@@ -70,20 +78,14 @@ program
|
|
|
70
78
|
}
|
|
71
79
|
|
|
72
80
|
await updateReleaseHistory(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
81
|
+
answers.app,
|
|
82
|
+
answers.appVersion,
|
|
83
|
+
answers.binaryVersion,
|
|
76
84
|
config.getReleaseHistory,
|
|
77
85
|
config.setReleaseHistory,
|
|
78
|
-
|
|
79
|
-
|
|
86
|
+
answers.platform,
|
|
87
|
+
answers.identifier,
|
|
80
88
|
options.mandatory,
|
|
81
89
|
options.enable
|
|
82
90
|
)
|
|
83
91
|
})
|
|
84
|
-
|
|
85
|
-
function parseBoolean(value) {
|
|
86
|
-
if (value === 'true') return true
|
|
87
|
-
if (value === 'false') return false
|
|
88
|
-
else return undefined
|
|
89
|
-
}
|
package/code-push.config.js
CHANGED
|
@@ -14,22 +14,34 @@ const s3Client = new S3Client({
|
|
|
14
14
|
},
|
|
15
15
|
})
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
function getBucketName(identifier) {
|
|
18
|
+
return identifier === 'prd'
|
|
19
|
+
? process.env.AWS_S3_BUCKET_PRD || 'codepush-bucket'
|
|
20
|
+
: process.env.AWS_S3_BUCKET_STG || 'codepush-bucket'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function getCDNUrl(identifier) {
|
|
24
|
+
const BUCKET_NAME = getBucketName(identifier)
|
|
25
|
+
return identifier === 'prd'
|
|
26
|
+
? process.env.CDN_URL_PRD || `https://${BUCKET_NAME}.s3.amazonaws.com`
|
|
27
|
+
: process.env.CDN_URL_STG || `https://${BUCKET_NAME}.s3.amazonaws.com`
|
|
28
|
+
}
|
|
19
29
|
|
|
20
|
-
function historyJsonFileRemotePath(app, platform,
|
|
21
|
-
return `histories/${app}/${platform}/${
|
|
30
|
+
function historyJsonFileRemotePath(app, platform, binaryVersion) {
|
|
31
|
+
return `histories/${app}/${platform}/${binaryVersion}.json`
|
|
22
32
|
}
|
|
23
33
|
|
|
24
|
-
function bundleFileRemotePath(app, platform,
|
|
25
|
-
return `bundles/${app}/${platform}/${
|
|
34
|
+
function bundleFileRemotePath(app, platform, fileName) {
|
|
35
|
+
return `bundles/${app}/${platform}/${fileName}`
|
|
26
36
|
}
|
|
27
37
|
|
|
28
38
|
const Config = {
|
|
29
|
-
bundleUploader: async (source, app, platform, identifier
|
|
39
|
+
bundleUploader: async (source, app, platform, identifier) => {
|
|
30
40
|
const fileName = source.split('/').pop()
|
|
31
41
|
const fileContent = fs.readFileSync(source)
|
|
32
|
-
const remotePath = bundleFileRemotePath(app, platform,
|
|
42
|
+
const remotePath = bundleFileRemotePath(app, platform, fileName)
|
|
43
|
+
const BUCKET_NAME = getBucketName(identifier)
|
|
44
|
+
const CDN_URL = getCDNUrl(identifier)
|
|
33
45
|
|
|
34
46
|
try {
|
|
35
47
|
await s3Client.send(
|
|
@@ -52,16 +64,11 @@ const Config = {
|
|
|
52
64
|
}
|
|
53
65
|
},
|
|
54
66
|
|
|
55
|
-
getReleaseHistory: async (
|
|
56
|
-
|
|
57
|
-
targetBinaryVersion,
|
|
58
|
-
platform,
|
|
59
|
-
identifier = 'staging'
|
|
60
|
-
) => {
|
|
67
|
+
getReleaseHistory: async (app, targetBinaryVersion, platform, identifier) => {
|
|
68
|
+
const CDN_URL = getCDNUrl(identifier)
|
|
61
69
|
const remoteJsonPath = historyJsonFileRemotePath(
|
|
62
70
|
app,
|
|
63
71
|
platform,
|
|
64
|
-
identifier,
|
|
65
72
|
targetBinaryVersion
|
|
66
73
|
)
|
|
67
74
|
const { data } = await axios.get(`${CDN_URL}/${remoteJsonPath}`)
|
|
@@ -74,15 +81,16 @@ const Config = {
|
|
|
74
81
|
releaseInfo,
|
|
75
82
|
app,
|
|
76
83
|
platform,
|
|
77
|
-
identifier
|
|
84
|
+
identifier
|
|
78
85
|
) => {
|
|
79
86
|
const fileContent = fs.readFileSync(jsonFilePath, 'utf8')
|
|
80
87
|
const remoteJsonPath = historyJsonFileRemotePath(
|
|
81
88
|
app,
|
|
82
89
|
platform,
|
|
83
|
-
identifier,
|
|
84
90
|
targetBinaryVersion
|
|
85
91
|
)
|
|
92
|
+
const BUCKET_NAME = getBucketName(identifier)
|
|
93
|
+
const CDN_URL = getCDNUrl(identifier)
|
|
86
94
|
|
|
87
95
|
try {
|
|
88
96
|
await s3Client.send(
|
package/code-push.config.ts
CHANGED
|
@@ -17,25 +17,33 @@ const s3Client = new S3Client({
|
|
|
17
17
|
},
|
|
18
18
|
})
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
function getBucketName(identifier: 'stg' | 'prd') {
|
|
21
|
+
return identifier === 'prd'
|
|
22
|
+
? process.env.AWS_S3_BUCKET_PRD || 'codepush-bucket'
|
|
23
|
+
: process.env.AWS_S3_BUCKET_STG || 'codepush-bucket'
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function getCDNUrl(identifier: 'stg' | 'prd') {
|
|
27
|
+
const BUCKET_NAME = getBucketName(identifier)
|
|
28
|
+
return identifier === 'prd'
|
|
29
|
+
? process.env.CDN_URL_PRD || `https://${BUCKET_NAME}.s3.amazonaws.com`
|
|
30
|
+
: process.env.CDN_URL_STG || `https://${BUCKET_NAME}.s3.amazonaws.com`
|
|
31
|
+
}
|
|
22
32
|
|
|
23
33
|
function historyJsonFileRemotePath(
|
|
24
34
|
app: 'user' | 'device',
|
|
25
35
|
platform: 'ios' | 'android',
|
|
26
|
-
identifier: string,
|
|
27
36
|
binaryVersion: string
|
|
28
37
|
) {
|
|
29
|
-
return `histories/${app}/${platform}/${
|
|
38
|
+
return `histories/${app}/${platform}/${binaryVersion}.json`
|
|
30
39
|
}
|
|
31
40
|
|
|
32
41
|
function bundleFileRemotePath(
|
|
33
42
|
app: 'user' | 'device',
|
|
34
43
|
platform: 'ios' | 'android',
|
|
35
|
-
identifier: string,
|
|
36
44
|
fileName: string
|
|
37
45
|
) {
|
|
38
|
-
return `bundles/${app}/${platform}/${
|
|
46
|
+
return `bundles/${app}/${platform}/${fileName}`
|
|
39
47
|
}
|
|
40
48
|
|
|
41
49
|
const Config: CliConfigInterface = {
|
|
@@ -43,16 +51,13 @@ const Config: CliConfigInterface = {
|
|
|
43
51
|
source: string,
|
|
44
52
|
app: 'user' | 'device',
|
|
45
53
|
platform: 'ios' | 'android',
|
|
46
|
-
identifier
|
|
54
|
+
identifier: 'stg' | 'prd'
|
|
47
55
|
): Promise<{ downloadUrl: string }> => {
|
|
48
56
|
const fileName = source.split('/').pop()
|
|
49
57
|
const fileContent = fs.readFileSync(source)
|
|
50
|
-
const remotePath = bundleFileRemotePath(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
identifier,
|
|
54
|
-
fileName!
|
|
55
|
-
)
|
|
58
|
+
const remotePath = bundleFileRemotePath(app, platform, fileName!)
|
|
59
|
+
const BUCKET_NAME = getBucketName(identifier)
|
|
60
|
+
const CDN_URL = getCDNUrl(identifier)
|
|
56
61
|
|
|
57
62
|
try {
|
|
58
63
|
await s3Client.send(
|
|
@@ -79,14 +84,15 @@ const Config: CliConfigInterface = {
|
|
|
79
84
|
app: 'user' | 'device',
|
|
80
85
|
targetBinaryVersion: string,
|
|
81
86
|
platform: 'ios' | 'android',
|
|
82
|
-
identifier
|
|
87
|
+
identifier: 'stg' | 'prd'
|
|
83
88
|
): Promise<ReleaseHistoryInterface> => {
|
|
84
89
|
const remoteJsonPath = historyJsonFileRemotePath(
|
|
85
90
|
app,
|
|
86
91
|
platform,
|
|
87
|
-
identifier,
|
|
88
92
|
targetBinaryVersion
|
|
89
93
|
)
|
|
94
|
+
const CDN_URL = getCDNUrl(identifier)
|
|
95
|
+
|
|
90
96
|
const { data } = await axios.get(`${CDN_URL}/${remoteJsonPath}`)
|
|
91
97
|
return data as ReleaseHistoryInterface
|
|
92
98
|
},
|
|
@@ -97,15 +103,16 @@ const Config: CliConfigInterface = {
|
|
|
97
103
|
releaseInfo: ReleaseHistoryInterface,
|
|
98
104
|
app: 'user' | 'device',
|
|
99
105
|
platform: 'ios' | 'android',
|
|
100
|
-
identifier
|
|
106
|
+
identifier: 'stg' | 'prd'
|
|
101
107
|
): Promise<void> => {
|
|
102
108
|
const fileContent = fs.readFileSync(jsonFilePath, 'utf8')
|
|
103
109
|
const remoteJsonPath = historyJsonFileRemotePath(
|
|
104
110
|
app,
|
|
105
111
|
platform,
|
|
106
|
-
identifier,
|
|
107
112
|
targetBinaryVersion
|
|
108
113
|
)
|
|
114
|
+
const BUCKET_NAME = getBucketName(identifier)
|
|
115
|
+
const CDN_URL = getCDNUrl(identifier)
|
|
109
116
|
|
|
110
117
|
try {
|
|
111
118
|
await s3Client.send(
|
package/package.json
CHANGED