@revopush/code-push-cli 0.0.5 → 0.0.8-rc.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/bin/script/command-executor.js +116 -74
- package/bin/script/command-parser.js +16 -1
- package/bin/script/management-sdk.js +5 -3
- package/bin/script/react-native-utils.js +207 -16
- package/bin/script/utils/file-utils.js +27 -2
- package/bin/test/management-sdk.js +7 -0
- package/package.json +5 -2
- package/script/command-executor.ts +163 -104
- package/script/command-parser.ts +17 -3
- package/script/management-sdk.ts +8 -3
- package/script/react-native-utils.ts +236 -21
- package/script/types/cli.ts +3 -0
- package/script/types/rest-definitions.ts +12 -0
- package/script/types.ts +1 -0
- package/script/utils/file-utils.ts +30 -1
- package/test/management-sdk.ts +9 -0
- package/test.json +5963 -0
- package/test2.json +5844 -0
|
@@ -1,35 +1,17 @@
|
|
|
1
1
|
// Copyright (c) Microsoft Corporation.
|
|
2
2
|
// Licensed under the MIT License.
|
|
3
3
|
|
|
4
|
-
import AccountManager = require("./management-sdk");
|
|
5
|
-
|
|
6
4
|
const childProcess = require("child_process");
|
|
7
5
|
import debugCommand from "./commands/debug";
|
|
8
6
|
import * as fs from "fs";
|
|
9
7
|
import * as chalk from "chalk";
|
|
10
|
-
|
|
11
|
-
const g2js = require("gradle-to-js/lib/parser");
|
|
12
8
|
import * as moment from "moment";
|
|
13
|
-
|
|
14
|
-
const opener = require("opener");
|
|
15
9
|
import * as os from "os";
|
|
16
10
|
import * as path from "path";
|
|
17
|
-
|
|
18
|
-
const plist = require("plist");
|
|
19
|
-
const progress = require("progress");
|
|
20
|
-
const prompt = require("prompt");
|
|
21
11
|
import * as Q from "q";
|
|
22
|
-
|
|
23
|
-
const rimraf = require("rimraf");
|
|
24
12
|
import * as semver from "semver";
|
|
25
|
-
|
|
26
|
-
const Table = require("cli-table");
|
|
27
|
-
const which = require("which");
|
|
28
|
-
import wordwrap = require("wordwrap");
|
|
29
13
|
import * as cli from "../script/types/cli";
|
|
30
14
|
import sign from "./sign";
|
|
31
|
-
|
|
32
|
-
const xcode = require("xcode");
|
|
33
15
|
import {
|
|
34
16
|
AccessKey,
|
|
35
17
|
Account,
|
|
@@ -45,14 +27,40 @@ import {
|
|
|
45
27
|
Session,
|
|
46
28
|
UpdateMetrics,
|
|
47
29
|
} from "../script/types";
|
|
48
|
-
import {
|
|
49
|
-
|
|
30
|
+
import {
|
|
31
|
+
getBundleSourceMapOutput,
|
|
32
|
+
getMinifyParams,
|
|
33
|
+
getReactNativePackagePath,
|
|
34
|
+
isHermesEnabled,
|
|
35
|
+
isValidVersion,
|
|
36
|
+
runHermesEmitBinaryCommand,
|
|
37
|
+
takeHermesBaseBytecode,
|
|
38
|
+
} from "./react-native-utils";
|
|
39
|
+
import { fileDoesNotExistOrIsDirectory, fileExists, isBinaryOrZip } from "./utils/file-utils";
|
|
40
|
+
|
|
41
|
+
import AccountManager = require("./management-sdk");
|
|
42
|
+
import wordwrap = require("wordwrap");
|
|
43
|
+
import Promise = Q.Promise;
|
|
44
|
+
import { ReactNativePackageInfo } from "./types/rest-definitions";
|
|
45
|
+
|
|
46
|
+
const g2js = require("gradle-to-js/lib/parser");
|
|
47
|
+
|
|
48
|
+
const opener = require("opener");
|
|
49
|
+
|
|
50
|
+
const plist = require("plist");
|
|
51
|
+
const progress = require("progress");
|
|
52
|
+
const prompt = require("prompt");
|
|
53
|
+
|
|
54
|
+
const rimraf = require("rimraf");
|
|
55
|
+
|
|
56
|
+
const Table = require("cli-table");
|
|
57
|
+
|
|
58
|
+
const xcode = require("xcode");
|
|
50
59
|
|
|
51
60
|
const configFilePath: string = path.join(process.env.LOCALAPPDATA || process.env.HOME, ".revopush.config");
|
|
52
61
|
const emailValidator = require("email-validator");
|
|
53
62
|
const packageJson = require("../../package.json");
|
|
54
63
|
const parseXml = Q.denodeify(require("xml2js").parseString);
|
|
55
|
-
import Promise = Q.Promise;
|
|
56
64
|
|
|
57
65
|
const properties = require("properties");
|
|
58
66
|
|
|
@@ -358,9 +366,11 @@ export const deploymentList = (command: cli.IDeploymentListCommand, showPackage:
|
|
|
358
366
|
};
|
|
359
367
|
|
|
360
368
|
function deploymentRemove(command: cli.IDeploymentRemoveCommand): Promise<void> {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
369
|
+
const confirmation = command.isForce
|
|
370
|
+
? Q.resolve(true)
|
|
371
|
+
: confirm("Are you sure you want to remove this deployment? Note that its deployment key will be PERMANENTLY unrecoverable.");
|
|
372
|
+
|
|
373
|
+
return confirmation.then((wasConfirmed: boolean): Promise<void> => {
|
|
364
374
|
if (wasConfirmed) {
|
|
365
375
|
return sdk.removeDeployment(command.appName, command.deploymentName).then((): void => {
|
|
366
376
|
log('Successfully removed the "' + command.deploymentName + '" deployment from the "' + command.appName + '" app.');
|
|
@@ -1200,75 +1210,33 @@ function patch(command: cli.IPatchCommand): Promise<void> {
|
|
|
1200
1210
|
}
|
|
1201
1211
|
|
|
1202
1212
|
export const release = (command: cli.IReleaseCommand): Promise<void> => {
|
|
1203
|
-
|
|
1204
|
-
throw new Error(
|
|
1205
|
-
"It is unnecessary to package releases in a .zip or binary file. Please specify the direct path to the update content's directory (e.g. /platforms/ios/www) or file (e.g. main.jsbundle)."
|
|
1206
|
-
);
|
|
1207
|
-
}
|
|
1208
|
-
|
|
1209
|
-
throwForInvalidSemverRange(command.appStoreVersion);
|
|
1210
|
-
const filePath: string = command.package;
|
|
1211
|
-
let isSingleFilePackage: boolean = true;
|
|
1212
|
-
|
|
1213
|
-
if (fs.lstatSync(filePath).isDirectory()) {
|
|
1214
|
-
isSingleFilePackage = false;
|
|
1215
|
-
}
|
|
1216
|
-
|
|
1217
|
-
let lastTotalProgress = 0;
|
|
1218
|
-
const progressBar = new progress("Upload progress:[:bar] :percent :etas", {
|
|
1219
|
-
complete: "=",
|
|
1220
|
-
incomplete: " ",
|
|
1221
|
-
width: 50,
|
|
1222
|
-
total: 100,
|
|
1223
|
-
});
|
|
1224
|
-
|
|
1225
|
-
const uploadProgress = (currentProgress: number): void => {
|
|
1226
|
-
progressBar.tick(currentProgress - lastTotalProgress);
|
|
1227
|
-
lastTotalProgress = currentProgress;
|
|
1228
|
-
};
|
|
1229
|
-
|
|
1213
|
+
// for initial release we explicitly define release as optional, disabled, without rollout, with a special description
|
|
1230
1214
|
const updateMetadata: PackageInfo = {
|
|
1231
|
-
description: command.description,
|
|
1232
|
-
isDisabled: command.disabled,
|
|
1233
|
-
isMandatory: command.mandatory,
|
|
1234
|
-
|
|
1215
|
+
description: command.initial ? `Zero release for v${command.appStoreVersion}` : command.description,
|
|
1216
|
+
isDisabled: command.initial ? true : command.disabled,
|
|
1217
|
+
isMandatory: command.initial ? false : command.mandatory,
|
|
1218
|
+
isInitial: command.initial,
|
|
1219
|
+
rollout: command.initial ? undefined : command.rollout,
|
|
1220
|
+
appVersion: command.appStoreVersion,
|
|
1235
1221
|
};
|
|
1236
1222
|
|
|
1237
|
-
return
|
|
1238
|
-
.isAuthenticated(true)
|
|
1239
|
-
.then((isAuth: boolean): Promise<void> => {
|
|
1240
|
-
return sdk.release(command.appName, command.deploymentName, filePath, command.appStoreVersion, updateMetadata, uploadProgress);
|
|
1241
|
-
})
|
|
1242
|
-
.then((): void => {
|
|
1243
|
-
log(
|
|
1244
|
-
'Successfully released an update containing the "' +
|
|
1245
|
-
command.package +
|
|
1246
|
-
'" ' +
|
|
1247
|
-
(isSingleFilePackage ? "file" : "directory") +
|
|
1248
|
-
' to the "' +
|
|
1249
|
-
command.deploymentName +
|
|
1250
|
-
'" deployment of the "' +
|
|
1251
|
-
command.appName +
|
|
1252
|
-
'" app.'
|
|
1253
|
-
);
|
|
1254
|
-
})
|
|
1255
|
-
.catch((err: CodePushError) => releaseErrorHandler(err, command));
|
|
1223
|
+
return doRelease(command, updateMetadata);
|
|
1256
1224
|
};
|
|
1257
1225
|
|
|
1258
1226
|
export const releaseReact = (command: cli.IReleaseReactCommand): Promise<void> => {
|
|
1259
1227
|
let bundleName: string = command.bundleName;
|
|
1260
1228
|
let entryFile: string = command.entryFile;
|
|
1261
1229
|
const outputFolder: string = command.outputDir || path.join(os.tmpdir(), "CodePush");
|
|
1230
|
+
const sourcemapOutputFolder: string = command.sourcemapOutput || path.join(os.tmpdir(), "CodePushSourceMap");
|
|
1231
|
+
const baseReleaseTmpFolder: string = path.join(os.tmpdir(), "CodePushBaseRelease");
|
|
1262
1232
|
const platform: string = (command.platform = command.platform.toLowerCase());
|
|
1263
|
-
const releaseCommand: cli.
|
|
1233
|
+
const releaseCommand: cli.IReleaseReactCommand = <any>command;
|
|
1264
1234
|
// Check for app and deployment exist before releasing an update.
|
|
1265
1235
|
// This validation helps to save about 1 minute or more in case user has typed wrong app or deployment name.
|
|
1266
1236
|
return (
|
|
1267
1237
|
sdk
|
|
1268
1238
|
.getDeployment(command.appName, command.deploymentName)
|
|
1269
|
-
.then(()
|
|
1270
|
-
releaseCommand.package = outputFolder;
|
|
1271
|
-
|
|
1239
|
+
.then(async () => {
|
|
1272
1240
|
switch (platform) {
|
|
1273
1241
|
case "android":
|
|
1274
1242
|
case "ios":
|
|
@@ -1282,6 +1250,10 @@ export const releaseReact = (command: cli.IReleaseReactCommand): Promise<void> =
|
|
|
1282
1250
|
throw new Error('Platform must be either "android", "ios" or "windows".');
|
|
1283
1251
|
}
|
|
1284
1252
|
|
|
1253
|
+
releaseCommand.package = outputFolder;
|
|
1254
|
+
releaseCommand.outputDir = outputFolder;
|
|
1255
|
+
releaseCommand.bundleName = bundleName;
|
|
1256
|
+
|
|
1285
1257
|
let projectName: string;
|
|
1286
1258
|
|
|
1287
1259
|
try {
|
|
@@ -1319,8 +1291,9 @@ export const releaseReact = (command: cli.IReleaseReactCommand): Promise<void> =
|
|
|
1319
1291
|
? Q(command.appStoreVersion)
|
|
1320
1292
|
: getReactNativeProjectAppVersion(command, projectName);
|
|
1321
1293
|
|
|
1322
|
-
if (
|
|
1323
|
-
|
|
1294
|
+
if (!sourcemapOutputFolder.endsWith(".map") && !command.sourcemapOutput) {
|
|
1295
|
+
// create tmp dir only if no dir was given by user. User must crete a directory if --sourcemapOutput is passes
|
|
1296
|
+
await createEmptyTempReleaseFolder(sourcemapOutputFolder);
|
|
1324
1297
|
}
|
|
1325
1298
|
|
|
1326
1299
|
return appVersionPromise;
|
|
@@ -1334,31 +1307,34 @@ export const releaseReact = (command: cli.IReleaseReactCommand): Promise<void> =
|
|
|
1334
1307
|
// This is needed to clear the react native bundler cache:
|
|
1335
1308
|
// https://github.com/facebook/react-native/issues/4289
|
|
1336
1309
|
.then(() => deleteFolder(`${os.tmpdir()}/react-*`))
|
|
1337
|
-
.then(() =>
|
|
1338
|
-
runReactNativeBundleCommand(
|
|
1310
|
+
.then(async () => {
|
|
1311
|
+
await runReactNativeBundleCommand(
|
|
1312
|
+
command,
|
|
1339
1313
|
bundleName,
|
|
1340
1314
|
command.development || false,
|
|
1341
1315
|
entryFile,
|
|
1342
1316
|
outputFolder,
|
|
1317
|
+
sourcemapOutputFolder,
|
|
1343
1318
|
platform,
|
|
1344
|
-
command.sourcemapOutput,
|
|
1345
1319
|
command.extraBundlerOptions
|
|
1346
|
-
)
|
|
1347
|
-
)
|
|
1320
|
+
);
|
|
1321
|
+
})
|
|
1348
1322
|
.then(async () => {
|
|
1349
|
-
const isHermesEnabled
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1323
|
+
const isHermes = await isHermesEnabled(command, platform);
|
|
1324
|
+
|
|
1325
|
+
if (isHermes) {
|
|
1326
|
+
await createEmptyTempReleaseFolder(baseReleaseTmpFolder);
|
|
1327
|
+
const baseBytecode = await takeHermesBaseBytecode(command, baseReleaseTmpFolder, outputFolder, bundleName);
|
|
1353
1328
|
|
|
1354
|
-
if (isHermesEnabled) {
|
|
1355
1329
|
log(chalk.cyan("\nRunning hermes compiler...\n"));
|
|
1356
1330
|
await runHermesEmitBinaryCommand(
|
|
1331
|
+
command,
|
|
1357
1332
|
bundleName,
|
|
1358
1333
|
outputFolder,
|
|
1359
|
-
|
|
1334
|
+
sourcemapOutputFolder,
|
|
1360
1335
|
command.extraHermesFlags,
|
|
1361
|
-
command.gradleFile
|
|
1336
|
+
command.gradleFile,
|
|
1337
|
+
baseBytecode
|
|
1362
1338
|
);
|
|
1363
1339
|
}
|
|
1364
1340
|
})
|
|
@@ -1372,20 +1348,90 @@ export const releaseReact = (command: cli.IReleaseReactCommand): Promise<void> =
|
|
|
1372
1348
|
})
|
|
1373
1349
|
.then(() => {
|
|
1374
1350
|
log(chalk.cyan("\nReleasing update contents to CodePush:\n"));
|
|
1375
|
-
return
|
|
1351
|
+
return releaseReactNative(releaseCommand);
|
|
1376
1352
|
})
|
|
1377
|
-
.then(() => {
|
|
1353
|
+
.then(async () => {
|
|
1378
1354
|
if (!command.outputDir) {
|
|
1379
|
-
deleteFolder(outputFolder);
|
|
1355
|
+
await deleteFolder(outputFolder);
|
|
1380
1356
|
}
|
|
1357
|
+
|
|
1358
|
+
if (!command.sourcemapOutput) {
|
|
1359
|
+
await deleteFolder(sourcemapOutputFolder);
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
await deleteFolder(baseReleaseTmpFolder);
|
|
1381
1363
|
})
|
|
1382
|
-
.catch((err: Error) => {
|
|
1383
|
-
deleteFolder(outputFolder);
|
|
1364
|
+
.catch(async (err: Error) => {
|
|
1384
1365
|
throw err;
|
|
1385
1366
|
})
|
|
1386
1367
|
);
|
|
1387
1368
|
};
|
|
1388
1369
|
|
|
1370
|
+
const releaseReactNative = (command: cli.IReleaseReactCommand): Promise<void> => {
|
|
1371
|
+
// for initial release we explicitly define release as optional, disabled, without rollout, with a special description
|
|
1372
|
+
const updateMetadata: ReactNativePackageInfo = {
|
|
1373
|
+
description: command.initial ? `Zero release for v${command.appStoreVersion}` : command.description,
|
|
1374
|
+
isDisabled: command.initial ? true : command.disabled,
|
|
1375
|
+
isMandatory: command.initial ? false : command.mandatory,
|
|
1376
|
+
isInitial: command.initial,
|
|
1377
|
+
bundleName: command.bundleName,
|
|
1378
|
+
outputDir: command.outputDir,
|
|
1379
|
+
rollout: command.initial ? undefined : command.rollout,
|
|
1380
|
+
appVersion: command.appStoreVersion,
|
|
1381
|
+
};
|
|
1382
|
+
|
|
1383
|
+
return doRelease(command, updateMetadata);
|
|
1384
|
+
};
|
|
1385
|
+
|
|
1386
|
+
const doRelease = (command: cli.IReleaseCommand | cli.IReleaseReactCommand, updateMetadata: PackageInfo): Promise<void> => {
|
|
1387
|
+
if (isBinaryOrZip(command.package)) {
|
|
1388
|
+
throw new Error(
|
|
1389
|
+
"It is unnecessary to package releases in a .zip or binary file. Please specify the direct path to the update content's directory (e.g. /platforms/ios/www) or file (e.g. main.jsbundle)."
|
|
1390
|
+
);
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
throwForInvalidSemverRange(command.appStoreVersion);
|
|
1394
|
+
const filePath: string = command.package;
|
|
1395
|
+
let isSingleFilePackage: boolean = true;
|
|
1396
|
+
|
|
1397
|
+
if (fs.lstatSync(filePath).isDirectory()) {
|
|
1398
|
+
isSingleFilePackage = false;
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
let lastTotalProgress = 0;
|
|
1402
|
+
const progressBar = new progress("Upload progress:[:bar] :percent :etas", {
|
|
1403
|
+
complete: "=",
|
|
1404
|
+
incomplete: " ",
|
|
1405
|
+
width: 50,
|
|
1406
|
+
total: 100,
|
|
1407
|
+
});
|
|
1408
|
+
|
|
1409
|
+
const uploadProgress = (currentProgress: number): void => {
|
|
1410
|
+
progressBar.tick(currentProgress - lastTotalProgress);
|
|
1411
|
+
lastTotalProgress = currentProgress;
|
|
1412
|
+
};
|
|
1413
|
+
|
|
1414
|
+
return sdk
|
|
1415
|
+
.isAuthenticated(true)
|
|
1416
|
+
.then((isAuth: boolean): Promise<void> => {
|
|
1417
|
+
return sdk.release(command.appName, command.deploymentName, filePath, updateMetadata, uploadProgress);
|
|
1418
|
+
})
|
|
1419
|
+
.then((): void => {
|
|
1420
|
+
log(
|
|
1421
|
+
'Successfully released an update containing the "' +
|
|
1422
|
+
command.package +
|
|
1423
|
+
'" ' +
|
|
1424
|
+
(isSingleFilePackage ? "file" : "directory") +
|
|
1425
|
+
' to the "' +
|
|
1426
|
+
command.deploymentName +
|
|
1427
|
+
'" deployment of the "' +
|
|
1428
|
+
command.appName +
|
|
1429
|
+
'" app.'
|
|
1430
|
+
);
|
|
1431
|
+
})
|
|
1432
|
+
.catch((err: CodePushError) => releaseErrorHandler(err, command));
|
|
1433
|
+
};
|
|
1434
|
+
|
|
1389
1435
|
function rollback(command: cli.IRollbackCommand): Promise<void> {
|
|
1390
1436
|
return confirm().then((wasConfirmed: boolean) => {
|
|
1391
1437
|
if (!wasConfirmed) {
|
|
@@ -1427,15 +1473,16 @@ function requestAccessKey(): Promise<string> {
|
|
|
1427
1473
|
});
|
|
1428
1474
|
}
|
|
1429
1475
|
|
|
1430
|
-
export const runReactNativeBundleCommand = (
|
|
1476
|
+
export const runReactNativeBundleCommand = async (
|
|
1477
|
+
command: cli.IReleaseReactCommand,
|
|
1431
1478
|
bundleName: string,
|
|
1432
1479
|
development: boolean,
|
|
1433
1480
|
entryFile: string,
|
|
1434
1481
|
outputFolder: string,
|
|
1482
|
+
sourcemapOutputFolder: string,
|
|
1435
1483
|
platform: string,
|
|
1436
|
-
sourcemapOutput: string,
|
|
1437
1484
|
extraBundlerOptions: string[]
|
|
1438
|
-
)
|
|
1485
|
+
) => {
|
|
1439
1486
|
const reactNativeBundleArgs: string[] = [];
|
|
1440
1487
|
const envNodeArgs: string = process.env.CODE_PUSH_NODE_ARGS;
|
|
1441
1488
|
|
|
@@ -1443,10 +1490,12 @@ export const runReactNativeBundleCommand = (
|
|
|
1443
1490
|
Array.prototype.push.apply(reactNativeBundleArgs, envNodeArgs.trim().split(/\s+/));
|
|
1444
1491
|
}
|
|
1445
1492
|
|
|
1446
|
-
const
|
|
1493
|
+
const reactNativePackagePath = getReactNativePackagePath();
|
|
1494
|
+
const oldCliPath = path.join(reactNativePackagePath, "local-cli", "cli.js");
|
|
1495
|
+
const cliPath = fs.existsSync(oldCliPath) ? oldCliPath : path.join(reactNativePackagePath, "cli.js");
|
|
1447
1496
|
|
|
1448
1497
|
Array.prototype.push.apply(reactNativeBundleArgs, [
|
|
1449
|
-
|
|
1498
|
+
cliPath,
|
|
1450
1499
|
"bundle",
|
|
1451
1500
|
"--assets-dest",
|
|
1452
1501
|
outputFolder,
|
|
@@ -1458,12 +1507,22 @@ export const runReactNativeBundleCommand = (
|
|
|
1458
1507
|
entryFile,
|
|
1459
1508
|
"--platform",
|
|
1460
1509
|
platform,
|
|
1510
|
+
"--reset-cache",
|
|
1461
1511
|
]);
|
|
1462
1512
|
|
|
1463
|
-
if (
|
|
1464
|
-
|
|
1513
|
+
if (sourcemapOutputFolder) {
|
|
1514
|
+
let bundleSourceMapOutput = sourcemapOutputFolder;
|
|
1515
|
+
if (!sourcemapOutputFolder.endsWith(".map")) {
|
|
1516
|
+
// user defined full path to source map. let's use that instead
|
|
1517
|
+
bundleSourceMapOutput = await getBundleSourceMapOutput(command, bundleName, sourcemapOutputFolder);
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
reactNativeBundleArgs.push("--sourcemap-output", bundleSourceMapOutput);
|
|
1465
1521
|
}
|
|
1466
1522
|
|
|
1523
|
+
const minifyValue = await getMinifyParams(command);
|
|
1524
|
+
Array.prototype.push.apply(reactNativeBundleArgs, minifyValue);
|
|
1525
|
+
|
|
1467
1526
|
if (extraBundlerOptions.length > 0) {
|
|
1468
1527
|
reactNativeBundleArgs.push(...extraBundlerOptions);
|
|
1469
1528
|
}
|
package/script/command-parser.ts
CHANGED
|
@@ -247,7 +247,13 @@ function deploymentRemove(commandName: string, yargs: yargs.Argv): void {
|
|
|
247
247
|
yargs
|
|
248
248
|
.usage(USAGE_PREFIX + " deployment " + commandName + " <appName> <deploymentName>")
|
|
249
249
|
.demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments
|
|
250
|
-
.example("deployment " + commandName + " MyApp MyDeployment", 'Removes deployment "MyDeployment" from app "MyApp"')
|
|
250
|
+
.example("deployment " + commandName + " MyApp MyDeployment", 'Removes deployment "MyDeployment" from app "MyApp"')
|
|
251
|
+
.option("force", {
|
|
252
|
+
default: false,
|
|
253
|
+
demand: false,
|
|
254
|
+
description: "Bypass confirmation when removing deployments",
|
|
255
|
+
type: "boolean",
|
|
256
|
+
});
|
|
251
257
|
|
|
252
258
|
addCommonConfiguration(yargs);
|
|
253
259
|
}
|
|
@@ -732,6 +738,13 @@ yargs
|
|
|
732
738
|
demand: false,
|
|
733
739
|
description: "Path to the gradle file which specifies the binary version you want to target this release at (android only).",
|
|
734
740
|
})
|
|
741
|
+
.option("initial", {
|
|
742
|
+
alias: "i",
|
|
743
|
+
default: false,
|
|
744
|
+
demand: false,
|
|
745
|
+
description: "Specifies whether release is initial (base) for given targetBinaryVersion.",
|
|
746
|
+
type: "boolean",
|
|
747
|
+
})
|
|
735
748
|
.option("mandatory", {
|
|
736
749
|
alias: "m",
|
|
737
750
|
default: false,
|
|
@@ -844,8 +857,7 @@ yargs
|
|
|
844
857
|
alias: "eo",
|
|
845
858
|
default: [],
|
|
846
859
|
demand: false,
|
|
847
|
-
description:
|
|
848
|
-
"Option that gets passed to react-native bundler. Can be specified multiple times.",
|
|
860
|
+
description: "Option that gets passed to react-native bundler. Can be specified multiple times.",
|
|
849
861
|
type: "array",
|
|
850
862
|
})
|
|
851
863
|
.check((argv: any, aliases: { [aliases: string]: string }): any => {
|
|
@@ -1107,6 +1119,7 @@ export function createCommand(): cli.ICommand {
|
|
|
1107
1119
|
|
|
1108
1120
|
deploymentRemoveCommand.appName = arg2;
|
|
1109
1121
|
deploymentRemoveCommand.deploymentName = arg3;
|
|
1122
|
+
deploymentRemoveCommand.isForce = argv["force"] as any;
|
|
1110
1123
|
}
|
|
1111
1124
|
break;
|
|
1112
1125
|
|
|
@@ -1240,6 +1253,7 @@ export function createCommand(): cli.ICommand {
|
|
|
1240
1253
|
releaseReactCommand.entryFile = argv["entryFile"] as any;
|
|
1241
1254
|
releaseReactCommand.gradleFile = argv["gradleFile"] as any;
|
|
1242
1255
|
releaseReactCommand.mandatory = argv["mandatory"] as any;
|
|
1256
|
+
releaseReactCommand.initial = argv["initial"] as any;
|
|
1243
1257
|
releaseReactCommand.noDuplicateReleaseError = argv["noDuplicateReleaseError"] as any;
|
|
1244
1258
|
releaseReactCommand.plistFile = argv["plistFile"] as any;
|
|
1245
1259
|
releaseReactCommand.plistFilePrefix = argv["plistFilePrefix"] as any;
|
package/script/management-sdk.ts
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
PackageInfo,
|
|
27
27
|
ServerAccessKey,
|
|
28
28
|
Session,
|
|
29
|
+
BaseRelease,
|
|
29
30
|
} from "./types";
|
|
30
31
|
|
|
31
32
|
const packageJson = require("../../package.json");
|
|
@@ -273,6 +274,12 @@ class AccountManager {
|
|
|
273
274
|
return this.get(urlEncode([`/apps/${appName}/deployments/${deploymentName}`])).then((res: JsonResponse) => res.body.deployment);
|
|
274
275
|
}
|
|
275
276
|
|
|
277
|
+
public getBaseRelease(appName: string, deploymentName: string, appVerison: string): Promise<BaseRelease> {
|
|
278
|
+
return this.get(urlEncode([`/apps/${appName}/deployments/${deploymentName}/basebundle?appVersion=${appVerison}`])).then(
|
|
279
|
+
(res: JsonResponse) => res.body.basebundle
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
|
|
276
283
|
public renameDeployment(appName: string, oldDeploymentName: string, newDeploymentName: string): Promise<void> {
|
|
277
284
|
return this.patch(
|
|
278
285
|
urlEncode([`/apps/${appName}/deployments/${oldDeploymentName}`]),
|
|
@@ -300,12 +307,10 @@ class AccountManager {
|
|
|
300
307
|
appName: string,
|
|
301
308
|
deploymentName: string,
|
|
302
309
|
filePath: string,
|
|
303
|
-
targetBinaryVersion: string,
|
|
304
310
|
updateMetadata: PackageInfo,
|
|
305
311
|
uploadProgressCallback?: (progress: number) => void
|
|
306
312
|
): Promise<void> {
|
|
307
313
|
return Promise<void>((resolve, reject, notify) => {
|
|
308
|
-
updateMetadata.appVersion = targetBinaryVersion;
|
|
309
314
|
const request: superagent.Request<any> = superagent.post(
|
|
310
315
|
this._serverUrl + urlEncode([`/apps/${appName}/deployments/${deploymentName}/release`])
|
|
311
316
|
);
|
|
@@ -569,7 +574,7 @@ class AccountManager {
|
|
|
569
574
|
|
|
570
575
|
request.set("Accept", `application/vnd.code-push.v${AccountManager.API_VERSION}+json`);
|
|
571
576
|
request.set("Authorization", `Bearer ${this._accessKey}`);
|
|
572
|
-
request.set("X-CodePush-SDK-Version", packageJson.version);
|
|
577
|
+
request.set("X-CodePush-SDK-Version", packageJson.version); // TODO get version differently without require("../../package.json");
|
|
573
578
|
}
|
|
574
579
|
}
|
|
575
580
|
|