@bravemobile/react-native-code-push 8.3.0 → 9.0.0-alpha.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/CodePush.js +107 -136
- package/README.md +0 -5
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateUtils.java +1 -4
- package/babel-plugin-code-push/index.js +197 -0
- package/babel-plugin-code-push/package-lock.json +10463 -0
- package/babel-plugin-code-push/package.json +26 -0
- package/babel-plugin-code-push/test/.babelrc.js +12 -0
- package/babel-plugin-code-push/test/cases/test1-config +15 -0
- package/babel-plugin-code-push/test/cases/test1-input +3 -0
- package/babel-plugin-code-push/test/cases/test1-output +11 -0
- package/babel-plugin-code-push/test/cases/test2-config +9 -0
- package/babel-plugin-code-push/test/cases/test2-input +3 -0
- package/babel-plugin-code-push/test/cases/test2-output +7 -0
- package/babel-plugin-code-push/test/codepush.config.js +15 -0
- package/babel-plugin-code-push/test/plugin.test.js +44 -0
- package/babel.config.js +3 -0
- package/cli/commands/bundleCommand/bundleCodePush.js +49 -0
- package/cli/commands/bundleCommand/index.js +25 -0
- package/cli/commands/createHistoryCommand/createReleaseHistory.js +53 -0
- package/cli/commands/createHistoryCommand/index.js +28 -0
- package/cli/commands/releaseCommand/addToReleaseHistory.js +75 -0
- package/cli/commands/releaseCommand/index.js +61 -0
- package/cli/commands/releaseCommand/release.js +88 -0
- package/cli/commands/showHistoryCommand/index.js +28 -0
- package/cli/commands/updateHistoryCommand/index.js +49 -0
- package/cli/commands/updateHistoryCommand/updateReleaseHistory.js +62 -0
- package/cli/constant.js +3 -0
- package/cli/functions/getReactTempDir.js +16 -0
- package/cli/functions/makeCodePushBundle.js +27 -0
- package/cli/functions/prepareToBundleJS.js +12 -0
- package/cli/functions/runHermesEmitBinaryCommand.js +213 -0
- package/cli/functions/runReactNativeBundleCommand.js +59 -0
- package/cli/index.js +43 -0
- package/cli/utils/file-utils.js +42 -0
- package/cli/utils/fsUtils.js +49 -0
- package/cli/utils/hash-utils.js +227 -0
- package/cli/utils/promisfied-fs.js +29 -0
- package/cli/utils/showLogo.js +23 -0
- package/cli/utils/zip.js +89 -0
- package/code-push.config.example.supabase.ts +114 -0
- package/docs/setup-android.md +3 -11
- package/eslint.config.mjs +32 -0
- package/package-mixins.js +1 -8
- package/package.json +26 -23
- package/react-native.config.js +3 -1
- package/typings/react-native-code-push.d.ts +91 -16
- package/versioning/BaseVersioning.js +126 -0
- package/versioning/BaseVersioning.test.js +15 -0
- package/versioning/IncrementalVersioning.js +9 -0
- package/versioning/IncrementalVersioning.test.js +186 -0
- package/versioning/SemverVersioning.js +10 -0
- package/versioning/SemverVersioning.test.js +205 -0
- package/versioning/index.js +7 -0
- package/.azurepipelines/build-rn-code-push-1es.yml +0 -104
- package/.azurepipelines/test-rn-code-push.yml +0 -94
- package/.config/CredScanSuppressions.json +0 -14
- package/docs/setup-windows.md +0 -121
- package/request-fetch-adapter.js +0 -52
- package/scripts/postlink/android/postlink.js +0 -87
- package/scripts/postlink/ios/postlink.js +0 -116
- package/scripts/postlink/run.js +0 -11
- package/scripts/postunlink/android/postunlink.js +0 -74
- package/scripts/postunlink/ios/postunlink.js +0 -87
- package/scripts/postunlink/run.js +0 -11
- package/scripts/tools/linkToolsAndroid.js +0 -57
- package/scripts/tools/linkToolsIos.js +0 -130
|
@@ -13,6 +13,26 @@ export interface UpdateCheckRequest {
|
|
|
13
13
|
package_hash?: string;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Alias for a string representing a released CodePush update version.
|
|
18
|
+
*/
|
|
19
|
+
export type ReleaseVersion = string;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The interface representing the release information that the `releaseHistoryFetcher` function must return.
|
|
23
|
+
*/
|
|
24
|
+
export type ReleaseHistoryInterface = Record<ReleaseVersion, ReleaseInfo>;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The interface that represents a single deployment history entry, which the `releaseHistoryFetcher` function should return.
|
|
28
|
+
*/
|
|
29
|
+
export interface ReleaseInfo {
|
|
30
|
+
enabled: boolean;
|
|
31
|
+
mandatory: boolean;
|
|
32
|
+
downloadUrl: string;
|
|
33
|
+
packageHash: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
16
36
|
// from code-push SDK
|
|
17
37
|
export interface UpdateCheckResponse {
|
|
18
38
|
download_url?: string;
|
|
@@ -35,21 +55,9 @@ export interface CodePushOptions extends SyncOptions {
|
|
|
35
55
|
*/
|
|
36
56
|
checkFrequency: CodePush.CheckFrequency;
|
|
37
57
|
/**
|
|
38
|
-
* Specifies
|
|
39
|
-
* It is used for self-hosting.
|
|
40
|
-
* Defaults to AppCenter storage.
|
|
58
|
+
* Specifies a function to get the release history.
|
|
41
59
|
*/
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Specify a function to perform the update check.
|
|
45
|
-
* It can be used for self-hosting.
|
|
46
|
-
* Defaults to AppCenter update_check REST API request.
|
|
47
|
-
*/
|
|
48
|
-
updateChecker?: (updateRequest: UpdateCheckRequest) => Promise<{ update_info: UpdateCheckResponse }>;
|
|
49
|
-
/**
|
|
50
|
-
* Specifies whether to run the original action, which queries AppCenter if an error occurs while running the `updateChecker` function.
|
|
51
|
-
*/
|
|
52
|
-
fallbackToAppCenter?: boolean;
|
|
60
|
+
releaseHistoryFetcher: (updateRequest: UpdateCheckRequest) => Promise<ReleaseHistoryInterface>;
|
|
53
61
|
}
|
|
54
62
|
|
|
55
63
|
export interface DownloadProgress {
|
|
@@ -186,6 +194,14 @@ export interface SyncOptions {
|
|
|
186
194
|
* one or more of the default values.
|
|
187
195
|
*/
|
|
188
196
|
rollbackRetryOptions?: RollbackRetryOptions;
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Specifies whether to ignore the update if the installation fails.
|
|
200
|
+
* If set to false, the update will be retried when the sync method is called, even if the previous installation attempt failed.
|
|
201
|
+
* However, depending on the deployment strategy, if an update that cannot be successfully installed is deployed, this option could result in an infinite update retry loop.
|
|
202
|
+
* Defaults to true.
|
|
203
|
+
*/
|
|
204
|
+
ignoreFailedUpdates?: boolean;
|
|
189
205
|
}
|
|
190
206
|
|
|
191
207
|
export interface UpdateDialog {
|
|
@@ -286,7 +302,7 @@ declare function CodePush(options?: CodePushOptions): (x: any) => any;
|
|
|
286
302
|
*
|
|
287
303
|
* @param x the React Component that will decorated
|
|
288
304
|
*/
|
|
289
|
-
declare function CodePush(x: any): any
|
|
305
|
+
declare function CodePush(x: any): any;
|
|
290
306
|
|
|
291
307
|
declare namespace CodePush {
|
|
292
308
|
/**
|
|
@@ -309,7 +325,7 @@ declare namespace CodePush {
|
|
|
309
325
|
*
|
|
310
326
|
* @param updateState The state of the update you want to retrieve the metadata for. Defaults to UpdateState.RUNNING.
|
|
311
327
|
*/
|
|
312
|
-
function getUpdateMetadata(updateState?: UpdateState)
|
|
328
|
+
function getUpdateMetadata(updateState?: UpdateState): Promise<LocalPackage|null>;
|
|
313
329
|
|
|
314
330
|
/**
|
|
315
331
|
* Notifies the CodePush runtime that an installed update is considered successful.
|
|
@@ -495,3 +511,62 @@ declare namespace CodePush {
|
|
|
495
511
|
}
|
|
496
512
|
|
|
497
513
|
export default CodePush;
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* Interface for the config file required for `npx code-push` CLI operation.
|
|
517
|
+
*
|
|
518
|
+
* Please refer to the example code for implementation guidance.
|
|
519
|
+
*/
|
|
520
|
+
export interface CliConfigInterface {
|
|
521
|
+
/**
|
|
522
|
+
* Interface that must be implemented to upload CodePush bundle files to an arbitrary infrastructure.
|
|
523
|
+
*
|
|
524
|
+
* Used in the `release` command, and must return a URL that allows downloading the file after the upload is completed.
|
|
525
|
+
* The URL is recorded in the ReleaseHistory, and the CodePush runtime library downloads the bundle file from this address.
|
|
526
|
+
*
|
|
527
|
+
* @param source The relative path of the generated bundle file. (e.g., ./2f156929-e474-46cd-9c9c-27a841043d98)
|
|
528
|
+
* @param platform The target platform of the bundle file. This is the string passed when executing the CLI command. ('ios'/'android')
|
|
529
|
+
* @param identifier An additional identifier string. This can be used to distinguish execution environments by incorporating it into the upload path or file name. This string is passed when executing the CLI command.
|
|
530
|
+
*/
|
|
531
|
+
bundleUploader: (
|
|
532
|
+
source: string,
|
|
533
|
+
platform: "ios" | "android",
|
|
534
|
+
identifier?: string,
|
|
535
|
+
) => Promise<{downloadUrl: string}>;
|
|
536
|
+
|
|
537
|
+
/**
|
|
538
|
+
* Interface that must be implemented to retrieve ReleaseHistory information.
|
|
539
|
+
*
|
|
540
|
+
* Use `fetch`, `axios`, or similar methods to fetch the data and return it.
|
|
541
|
+
*
|
|
542
|
+
* @param targetBinaryVersion The target binary app version for which ReleaseHistory information is retrieved. This string is passed when executing the CLI command. (e.g., '1.0.0')
|
|
543
|
+
* @param platform The target platform for which the information is retrieved. This string is passed when executing the CLI command. ('ios'/'android')
|
|
544
|
+
* @param identifier An additional identifier string. This string is passed when executing the CLI command.
|
|
545
|
+
*/
|
|
546
|
+
getReleaseHistory: (
|
|
547
|
+
targetBinaryVersion: string,
|
|
548
|
+
platform: "ios" | "android",
|
|
549
|
+
identifier?: string,
|
|
550
|
+
) => Promise<ReleaseHistoryInterface>;
|
|
551
|
+
|
|
552
|
+
/**
|
|
553
|
+
* Interface that must be implemented to create or update ReleaseHistory information.
|
|
554
|
+
*
|
|
555
|
+
* Used in the `create-history`, `release`, and `update-history` commands.
|
|
556
|
+
* The created or modified object and the JSON file path containing the result of the command execution are provided.
|
|
557
|
+
* Implement this function to upload the file or call a REST API to update the release history.
|
|
558
|
+
*
|
|
559
|
+
* @param targetBinaryVersion The target binary app version for the ReleaseHistory. This string is passed when executing the CLI command. (e.g., '1.0.0')
|
|
560
|
+
* @param jsonFilePath The absolute path to a JSON file following the `ReleaseHistoryInterface` structure. The file is created in the project's root directory and deleted when the command execution completes.
|
|
561
|
+
* @param releaseInfo A plain object following the `ReleaseHistoryInterface` structure.
|
|
562
|
+
* @param platform The target platform. This string is passed when executing the CLI command. ('ios'/'android')
|
|
563
|
+
* @param identifier An additional identifier string. This string is passed when executing the CLI command.
|
|
564
|
+
*/
|
|
565
|
+
setReleaseHistory: (
|
|
566
|
+
targetBinaryVersion: string,
|
|
567
|
+
jsonFilePath: string,
|
|
568
|
+
releaseInfo: ReleaseHistoryInterface,
|
|
569
|
+
platform: "ios" | "android",
|
|
570
|
+
identifier?: string,
|
|
571
|
+
) => Promise<void>;
|
|
572
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @type {BaseVersioning}
|
|
3
|
+
*/
|
|
4
|
+
class BaseVersioning {
|
|
5
|
+
/**
|
|
6
|
+
* @param {ReleaseHistoryInterface} releaseHistory
|
|
7
|
+
* @param {SortingMethod} sortingMethod
|
|
8
|
+
*/
|
|
9
|
+
constructor(releaseHistory, sortingMethod) {
|
|
10
|
+
if (this.constructor == BaseVersioning) {
|
|
11
|
+
throw new Error("Abstract classes can't be instantiated.");
|
|
12
|
+
}
|
|
13
|
+
if (releaseHistory == null || sortingMethod == null) {
|
|
14
|
+
throw new Error("param releaseHistory and sortingMethod is needed");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** @type {SortingMethod} */
|
|
18
|
+
this.sortingMethod = sortingMethod;
|
|
19
|
+
|
|
20
|
+
/** @type {ReleaseHistoryInterface} */
|
|
21
|
+
this.originalReleaseHistory = releaseHistory;
|
|
22
|
+
|
|
23
|
+
/** @type {[ReleaseVersion, ReleaseInfo][]} */
|
|
24
|
+
this.sortedReleaseHistory = Object.entries(releaseHistory).sort(
|
|
25
|
+
([a], [b]) => this.sortingMethod(a, b)
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @return {[ReleaseVersion, ReleaseInfo][]}
|
|
31
|
+
*/
|
|
32
|
+
get sortedEnabledReleaseHistory() {
|
|
33
|
+
return this.sortedReleaseHistory.filter(([_, bundle]) => bundle.enabled);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @return {[ReleaseVersion, ReleaseInfo][]}
|
|
38
|
+
*/
|
|
39
|
+
get sortedMandatoryReleaseHistory() {
|
|
40
|
+
return this.sortedEnabledReleaseHistory.filter(
|
|
41
|
+
([_, bundle]) => bundle.mandatory
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* find latest release in releaseHistory
|
|
47
|
+
* @return {[ReleaseVersion, ReleaseInfo]}
|
|
48
|
+
*/
|
|
49
|
+
findLatestRelease() {
|
|
50
|
+
const latestReleaseInfo = this.sortedEnabledReleaseHistory.at(0);
|
|
51
|
+
|
|
52
|
+
if (!latestReleaseInfo) {
|
|
53
|
+
throw new Error("There is no latest release.");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return latestReleaseInfo;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* check if the update is mandatory
|
|
61
|
+
* @param {ReleaseVersion|undefined} runtimeVersion
|
|
62
|
+
* @return {boolean}
|
|
63
|
+
*/
|
|
64
|
+
checkIsMandatory(runtimeVersion) {
|
|
65
|
+
if (this.shouldRollback(runtimeVersion)) {
|
|
66
|
+
// rollback is always mandatory
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (this.sortedMandatoryReleaseHistory.length === 0) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (!runtimeVersion) {
|
|
75
|
+
// This means that there is at least one mandatory update, but the update has not been installed yet.
|
|
76
|
+
// So, the update is mandatory.
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const [latestMandatoryVersion, _] = this.sortedMandatoryReleaseHistory[0];
|
|
81
|
+
const [larger] = [latestMandatoryVersion, runtimeVersion].sort(this.sortingMethod);
|
|
82
|
+
|
|
83
|
+
return runtimeVersion !== latestMandatoryVersion && larger === latestMandatoryVersion;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* determine whether to rollback and execute it
|
|
88
|
+
* @param {ReleaseVersion|undefined} runtimeVersion
|
|
89
|
+
* @return {boolean}
|
|
90
|
+
*/
|
|
91
|
+
shouldRollback(runtimeVersion) {
|
|
92
|
+
if (!runtimeVersion) {
|
|
93
|
+
// Rollback is not possible because no updates have been installed.
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const [latestRelease] = this.findLatestRelease();
|
|
98
|
+
const [larger] = [latestRelease, runtimeVersion].sort(this.sortingMethod);
|
|
99
|
+
|
|
100
|
+
return runtimeVersion !== latestRelease && larger === runtimeVersion;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Determine whether to clear the currently running bundle.
|
|
105
|
+
* If it returns true, the CodePush bundle will be erased, and the app will restart.
|
|
106
|
+
* @param {ReleaseVersion} runtimeVersion
|
|
107
|
+
* @return {boolean}
|
|
108
|
+
*/
|
|
109
|
+
shouldRollbackToBinary(runtimeVersion) {
|
|
110
|
+
if (!runtimeVersion) {
|
|
111
|
+
// Rollback is not possible because no updates have been installed.
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const [latestReleaseVersion] = this.findLatestRelease();
|
|
116
|
+
const [binaryAppVersion] = this.sortedReleaseHistory.at(-1);
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
runtimeVersion !== latestReleaseVersion &&
|
|
120
|
+
this.shouldRollback(runtimeVersion) &&
|
|
121
|
+
latestReleaseVersion === binaryAppVersion
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
module.exports = { BaseVersioning: BaseVersioning };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BaseVersioning } from "./BaseVersioning"
|
|
2
|
+
|
|
3
|
+
describe('BaseVersioning', () => {
|
|
4
|
+
describe('constructor', () => {
|
|
5
|
+
it('should throw an error if it is directly instantiated', () => {
|
|
6
|
+
expect(() => new BaseVersioning({})).toThrow("Abstract classes can't be instantiated.")
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
it('should throw an error if releaseHistory is not defined', () => {
|
|
10
|
+
class TestVersioning extends BaseVersioning {}
|
|
11
|
+
expect(() => new TestVersioning()).toThrow("param releaseHistory and sortingMethod is needed")
|
|
12
|
+
expect(() => new TestVersioning({}, () => {})).not.toThrow("param releaseHistory and sortingMethod is needed")
|
|
13
|
+
})
|
|
14
|
+
})
|
|
15
|
+
})
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { IncrementalVersioning } from "./IncrementalVersioning"
|
|
2
|
+
|
|
3
|
+
describe('Incremental Versioning Test', () => {
|
|
4
|
+
const MOCK_INFOS = { downloadUrl: '', packageHash: '' }
|
|
5
|
+
|
|
6
|
+
// When major version is released, it must be considered like below
|
|
7
|
+
const FIRST_RELEASE_INFO = { enabled: true, mandatory: false, ...MOCK_INFOS };
|
|
8
|
+
|
|
9
|
+
describe('findLatestRelease', () => {
|
|
10
|
+
it('should throw error when there is no releases', () => {
|
|
11
|
+
const RELEASED_BUNDLES_1 = {}
|
|
12
|
+
const RELEASED_BUNDLES_2 = {'1': { enabled: false, mandatory: false, downloadUrl: 'R1', packageHash: 'P1' }}
|
|
13
|
+
expect(() => new IncrementalVersioning(RELEASED_BUNDLES_1).findLatestRelease())
|
|
14
|
+
.toThrow("There is no latest release.")
|
|
15
|
+
expect(() => new IncrementalVersioning(RELEASED_BUNDLES_2).findLatestRelease())
|
|
16
|
+
.toThrow("There is no latest release.")
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
it('should return latest release', () => {
|
|
20
|
+
const RELEASED_BUNDLES = {
|
|
21
|
+
'1': { enabled: true, mandatory: false, downloadUrl: 'R1', packageHash: 'P1' },
|
|
22
|
+
'2': { enabled: true, mandatory: false, downloadUrl: 'R2', packageHash: 'P2' },
|
|
23
|
+
'3': { enabled: true, mandatory: true, downloadUrl: 'R3', packageHash: 'P3' },
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
expect(new IncrementalVersioning(RELEASED_BUNDLES).findLatestRelease()).toEqual([
|
|
27
|
+
'3',
|
|
28
|
+
{ enabled: true, mandatory: true, downloadUrl: 'R3', packageHash: 'P3' }
|
|
29
|
+
])
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('should ignore not-enabled bundles and return latest release', () => {
|
|
33
|
+
const RELEASED_BUNDLES_1 = {
|
|
34
|
+
'1': { enabled: true, mandatory: false, downloadUrl: 'R1', packageHash: 'P1' },
|
|
35
|
+
'2': { enabled: false, mandatory: false, downloadUrl: 'R2', packageHash: 'P2' },
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const RELEASED_BUNDLES_2 = {
|
|
39
|
+
'1': { enabled: true, mandatory: false, downloadUrl: 'R1', packageHash: 'P1' },
|
|
40
|
+
'2': { enabled: false, mandatory: false, downloadUrl: 'R2', packageHash: 'P2' },
|
|
41
|
+
'3': { enabled: true, mandatory: true, downloadUrl: 'R3', packageHash: 'P3' },
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
expect(new IncrementalVersioning(RELEASED_BUNDLES_1).findLatestRelease()).toEqual([
|
|
45
|
+
'1',
|
|
46
|
+
{ enabled: true, mandatory: false, downloadUrl: 'R1', packageHash: 'P1' }
|
|
47
|
+
])
|
|
48
|
+
|
|
49
|
+
expect(new IncrementalVersioning(RELEASED_BUNDLES_2).findLatestRelease()).toEqual([
|
|
50
|
+
'3',
|
|
51
|
+
{ enabled: true, mandatory: true, downloadUrl: 'R3', packageHash: 'P3' }
|
|
52
|
+
])
|
|
53
|
+
})
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
describe('checkIsMandatory', () => {
|
|
57
|
+
describe('not-mandatory cases', () => {
|
|
58
|
+
it('should consider not-mandatory when the first major version is released', () => {
|
|
59
|
+
const RUNTIME_VERSION = '1';
|
|
60
|
+
const RELEASED_BUNDLES = {
|
|
61
|
+
'1': FIRST_RELEASE_INFO,
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory(RUNTIME_VERSION)).toBe(false);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should consider not-mandatory when latest version is running', () => {
|
|
68
|
+
const RUNTIME_VERSION = '3';
|
|
69
|
+
const RELEASED_BUNDLES = {
|
|
70
|
+
'1': FIRST_RELEASE_INFO,
|
|
71
|
+
'2': { enabled: true, mandatory: false, ...MOCK_INFOS },
|
|
72
|
+
'3': { enabled: true, mandatory: true, ...MOCK_INFOS },
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory(RUNTIME_VERSION)).toBe(false);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('should consider not-mandatory when only not-mandatory version is released', () => {
|
|
79
|
+
const RUNTIME_VERSION = '1';
|
|
80
|
+
const RELEASED_BUNDLES = {
|
|
81
|
+
'1': FIRST_RELEASE_INFO,
|
|
82
|
+
'2': { enabled: true, mandatory: false, ...MOCK_INFOS },
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory(RUNTIME_VERSION)).toBe(false);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('should consider not-mandatory when only not-mandatory version is released after current runtime version', () => {
|
|
89
|
+
const RUNTIME_VERSION = '2';
|
|
90
|
+
const RELEASED_BUNDLES = {
|
|
91
|
+
'1': FIRST_RELEASE_INFO,
|
|
92
|
+
'2': { enabled: true, mandatory: true, ...MOCK_INFOS },
|
|
93
|
+
'3': { enabled: true, mandatory: false, ...MOCK_INFOS },
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory(RUNTIME_VERSION)).toBe(false);
|
|
97
|
+
});
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
describe('mandatory cases', () => {
|
|
101
|
+
it('should consider mandatory when mandatory release exists', () => {
|
|
102
|
+
const RUNTIME_VERSION = '1';
|
|
103
|
+
const RELEASED_BUNDLES = {
|
|
104
|
+
'1': FIRST_RELEASE_INFO,
|
|
105
|
+
'2': { enabled: true, mandatory: true, ...MOCK_INFOS },
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory(RUNTIME_VERSION)).toBe(true);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("should consider mandatory if there's a mandatory release between the runtime version and the latest", () => {
|
|
112
|
+
const RUNTIME_VERSION = '1'
|
|
113
|
+
const RELEASED_BUNDLES = {
|
|
114
|
+
'1': FIRST_RELEASE_INFO,
|
|
115
|
+
'2': { enabled: true, mandatory: true, ...MOCK_INFOS },
|
|
116
|
+
'3': { enabled: true, mandatory: false, ...MOCK_INFOS },
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory(RUNTIME_VERSION)).toBe(true);
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
it('should consider mandatory when latest version < current runtime version (ROLLBACK)', () => {
|
|
123
|
+
const RELEASED_BUNDLES = {
|
|
124
|
+
'1': FIRST_RELEASE_INFO,
|
|
125
|
+
};
|
|
126
|
+
const currentVersion = '2'
|
|
127
|
+
|
|
128
|
+
expect(new IncrementalVersioning(RELEASED_BUNDLES).shouldRollback(currentVersion)).toBe(true)
|
|
129
|
+
})
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
describe('scenario test', () => {
|
|
133
|
+
it('Major Release > Mandatory > Not-mandatory > Mandatory > Not-mandatory', () => {
|
|
134
|
+
const RELEASED_BUNDLES = {
|
|
135
|
+
'1': FIRST_RELEASE_INFO,
|
|
136
|
+
'2': { enabled: true, mandatory: true, ...MOCK_INFOS },
|
|
137
|
+
'3': { enabled: true, mandatory: false, ...MOCK_INFOS },
|
|
138
|
+
'4': { enabled: true, mandatory: true, ...MOCK_INFOS },
|
|
139
|
+
'5': { enabled: true, mandatory: false, ...MOCK_INFOS },
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory('1')).toBe(true);
|
|
143
|
+
expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory('2')).toBe(true);
|
|
144
|
+
expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory('3')).toBe(true);
|
|
145
|
+
expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory('4')).toBe(false);
|
|
146
|
+
expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory('5')).toBe(false);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it('When having not-enabled releases', () => {
|
|
150
|
+
const RELEASED_BUNDLES = {
|
|
151
|
+
'1': FIRST_RELEASE_INFO,
|
|
152
|
+
'2': { enabled: true, mandatory: true, ...MOCK_INFOS },
|
|
153
|
+
'3': { enabled: false, mandatory: false, ...MOCK_INFOS },
|
|
154
|
+
'4': { enabled: true, mandatory: true, ...MOCK_INFOS },
|
|
155
|
+
'5': { enabled: false, mandatory: false, ...MOCK_INFOS },
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory('1')).toBe(true);
|
|
159
|
+
expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory('2')).toBe(true);
|
|
160
|
+
expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory('3')).toBe(true);
|
|
161
|
+
expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory('4')).toBe(false);
|
|
162
|
+
expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory('5')).toBe(true);
|
|
163
|
+
});
|
|
164
|
+
})
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
describe('shouldRollbackToBinary', () => {
|
|
168
|
+
it('should return true when destination version is the first major version', () => {
|
|
169
|
+
const RELEASED_BUNDLES = {
|
|
170
|
+
'1': FIRST_RELEASE_INFO,
|
|
171
|
+
'2': { enabled: false, mandatory: true, ...MOCK_INFOS },
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
expect(new IncrementalVersioning(RELEASED_BUNDLES).shouldRollbackToBinary('2')).toBe(true)
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
it('should return false when runtime version is the same as destination version', () => {
|
|
178
|
+
const RELEASED_BUNDLES = {
|
|
179
|
+
'1': FIRST_RELEASE_INFO,
|
|
180
|
+
'2': { enabled: false, mandatory: true, ...MOCK_INFOS },
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
expect(new IncrementalVersioning(RELEASED_BUNDLES).shouldRollbackToBinary('1')).toBe(false)
|
|
184
|
+
})
|
|
185
|
+
})
|
|
186
|
+
})
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const Semver = require("semver");
|
|
2
|
+
const { BaseVersioning } = require("./BaseVersioning");
|
|
3
|
+
|
|
4
|
+
class SemverVersioning extends BaseVersioning {
|
|
5
|
+
constructor(releaseHistory) {
|
|
6
|
+
super(releaseHistory, (v1, v2) => (Semver.gt(v1, v2) ? -1 : 1));
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
module.exports = { SemverVersioning };
|