This commit is contained in:
Anna Kocheshkova 2018-04-23 13:50:16 +03:00
Родитель 7ac6eb9c1e
Коммит 5fb1a6b9b4
13 изменённых файлов: 117 добавлений и 46 удалений

Просмотреть файл

@ -31,7 +31,7 @@ There are several possible scenarios this extension solves:
* Apps will be automatically linked with corresponding iOS/Android secret keys and CodePush deployment keys
* Changes will be pushed to your remote repository
* New Testers Distribution Group will be created for every new app in App Center
* App will be connected to your GH repository `master` branch and new build will be started
* [Optional - can be enabled in extension settings by turning `appcenter.api.configurebranchandstartnewbuild` on] App will be connected to your GH repository `master` branch and new build will be started
* You will be notified when finished and also we will automatically run `npm install` and `pod update` for you
2. Link an existing react-native application to App Center.

Просмотреть файл

@ -33,10 +33,16 @@ export default class ReleaseReact extends RNCPAppCommand {
}).then((currentApp: CurrentApp): any => {
p.report({ message: Strings.DetectingAppVersionMessage });
if (!currentApp) {
throw new Error(`No current app has been specified.`);
VsCodeUtils.ShowWarningMessage(Strings.NoCurrentAppSetMsg);
return;
}
if (!this.hasCodePushDeployments(currentApp)) {
VsCodeUtils.ShowWarningMessage(Strings.NoDeploymentsMsg);
return;
}
if (!currentApp.os || !reactNative.isValidOS(currentApp.os)) {
throw new Error(`OS must be "android", "ios", or "windows".`);
VsCodeUtils.ShowWarningMessage(Strings.UnsupportedOSMsg);
return;
}
codePushRelaseParams.app = currentApp;
codePushRelaseParams.deploymentName = currentApp.currentAppDeployments.currentDeploymentName;
@ -49,10 +55,16 @@ export default class ReleaseReact extends RNCPAppCommand {
case "android": return reactNative.getAndroidAppVersion(this.rootPath);
case "ios": return reactNative.getiOSAppVersion(this.rootPath);
case "windows": return reactNative.getWindowsAppVersion(this.rootPath);
default: throw new Error(`OS must be "android", "ios", or "windows".`);
default: {
VsCodeUtils.ShowInfoMessage(Strings.UnsupportedOSMsg);
return;
}
}
}
}).then((appVersion: string) => {
if (!appVersion) {
return null;
}
p.report({ message: Strings.RunningBundleCommandMessage });
codePushRelaseParams.appVersion = appVersion;
return reactNative.makeUpdateContents(<BundleConfig>{
@ -60,11 +72,17 @@ export default class ReleaseReact extends RNCPAppCommand {
projectRootPath: this.rootPath
});
}).then((pathToUpdateContents: string) => {
if (!pathToUpdateContents) {
return null;
}
p.report({ message: Strings.ArchivingUpdateContentsMessage });
updateContentsDirectory = pathToUpdateContents;
this.logger.log(`CodePush updated contents directory path: ${updateContentsDirectory}`, LogLevel.Debug);
return updateContents.zip(pathToUpdateContents, this.rootPath);
}).then((pathToZippedBundle: string) => {
if (!pathToZippedBundle) {
return null;
}
p.report({ message: Strings.ReleasingUpdateContentsMessage });
codePushRelaseParams.updatedContentZipPath = pathToZippedBundle;
codePushRelaseParams.isMandatory = isMandatory;
@ -78,6 +96,9 @@ export default class ReleaseReact extends RNCPAppCommand {
.catch((error: any) => publishReject(error));
});
}).then((response: any) => {
if (!response) {
return;
}
if (response.succeeded && response.result) {
VsCodeUtils.ShowInfoMessage(`Successfully released an update to the "${codePushRelaseParams.deploymentName}" deployment of the "${codePushRelaseParams.app.appName}" app`);
resolve(response.result);

Просмотреть файл

@ -1,5 +1,6 @@
import { Utils } from "../../../helpers/utils";
import { ReactNativeAppCommand } from "../reactNativeAppCommand";
import { CurrentApp } from "../../../helpers/interfaces";
export class RNCPAppCommand extends ReactNativeAppCommand {
public async runNoClient(): Promise<boolean | void> {
@ -21,4 +22,8 @@ export class RNCPAppCommand extends ReactNativeAppCommand {
}
return true;
}
protected hasCodePushDeployments(currentApp: CurrentApp): boolean {
return currentApp.currentAppDeployments && currentApp.currentAppDeployments.codePushDeployments && currentApp.currentAppDeployments.codePushDeployments.length > 0;
}
}

Просмотреть файл

@ -15,8 +15,12 @@ export default class SetCurrentDeployment extends RNCPAppCommand {
return;
}
this.getCurrentApp().then((currentApp: CurrentApp) => {
if (!currentApp || !currentApp.currentAppDeployments || !currentApp.currentAppDeployments.codePushDeployments) {
VsCodeUtils.ShowInfoMessage(Strings.NoCurrentAppSetMsg);
if (!currentApp) {
VsCodeUtils.ShowWarningMessage(Strings.NoCurrentAppSetMsg);
return;
}
if (!this.hasCodePushDeployments(currentApp)) {
VsCodeUtils.ShowWarningMessage(Strings.NoDeploymentsMsg);
return;
}
const deploymentOptions: string[] = currentApp.currentAppDeployments.codePushDeployments.map((deployment) => {

Просмотреть файл

@ -15,40 +15,52 @@ export default class SetTargetBinaryVersion extends RNCPAppCommand {
if (!await super.runNoClient()) {
return;
}
return vscode.window.showInputBox({ prompt: Strings.PleaseProvideTargetBinaryVersion, ignoreFocusOut: true })
.then(appVersion => {
if (!appVersion) {
// if user press esc do nothing then
return void 0;
}
if (appVersion !== Constants.AppCenterDefaultTargetBinaryVersion && !validRange(appVersion)) {
VsCodeUtils.ShowWarningMessage(Strings.InvalidAppVersionParamMsg);
return void 0;
}
return this.getCurrentApp().then((app: CurrentApp) => {
if (app) {
return this.saveCurrentApp(
app.identifier,
AppCenterOS[app.os], {
currentDeploymentName: app.currentAppDeployments.currentDeploymentName,
codePushDeployments: app.currentAppDeployments.codePushDeployments
},
appVersion,
app.type,
app.isMandatory,
app.appSecret
).then(() => {
if (appVersion) {
VsCodeUtils.ShowInfoMessage(`Changed target binary version to '${appVersion}'`);
} else {
VsCodeUtils.ShowInfoMessage(`Changed target binary version to automatically fetched`);
}
});
} else {
VsCodeUtils.ShowInfoMessage(Strings.NoCurrentAppSetMsg);
return this.getCurrentApp().then((app: CurrentApp) => {
if (!app) {
VsCodeUtils.ShowWarningMessage(Strings.NoCurrentAppSetMsg);
return null;
}
if (!this.hasCodePushDeployments(app)) {
VsCodeUtils.ShowWarningMessage(Strings.NoDeploymentsMsg);
return null;
}
return app;
}).then((app) => {
if (!app) {
return void 0;
}
return vscode.window.showInputBox({ prompt: Strings.PleaseProvideTargetBinaryVersion, ignoreFocusOut: true })
.then(appVersion => {
if (!appVersion) {
// if user press esc do nothing then
return void 0;
}
return void 0;
if (appVersion !== Constants.AppCenterDefaultTargetBinaryVersion && !validRange(appVersion)) {
VsCodeUtils.ShowWarningMessage(Strings.InvalidAppVersionParamMsg);
return void 0;
}
return this.saveCurrentApp(
app.identifier,
AppCenterOS[app.os], {
currentDeploymentName: app.currentAppDeployments.currentDeploymentName,
codePushDeployments: app.currentAppDeployments.codePushDeployments
},
appVersion,
app.type,
app.isMandatory,
app.appSecret
).then((currentApp) => {
if (!currentApp) {
return;
}
if (appVersion) {
VsCodeUtils.ShowInfoMessage(`Changed target binary version to '${appVersion}'`);
} else {
VsCodeUtils.ShowInfoMessage(`Changed target binary version to automatically fetched`);
}
});
});
});
});
}
}

Просмотреть файл

@ -32,7 +32,7 @@ export default class ShowMenu extends RNCPAppCommand {
description: Strings.OpenTabInBrowserMsg(Strings.DistributeCodePushTabMenuItem),
target: AppCenterDistributionTabs.CodePush
});
if (this.hasCodePushDeployments()) {
if (this.hasCodePushDeployments(currentApp)) {
menuOptions.push(<CustomQuickPickItem>{
label: Strings.releaseReactMenuText(currentApp),
description: "",
@ -58,10 +58,6 @@ export default class ShowMenu extends RNCPAppCommand {
});
}
private hasCodePushDeployments(): boolean {
return this.currentApp.currentAppDeployments && this.currentApp.currentAppDeployments.codePushDeployments && this.currentApp.currentAppDeployments.codePushDeployments.length > 0;
}
private showQuickPick(menuOptions: CustomQuickPickItem[]): Promise<void> {
return new Promise((resolve) => {
return vscode.window.showQuickPick(menuOptions, { placeHolder: Strings.MenuTitlePlaceholder })

Просмотреть файл

@ -16,7 +16,11 @@ export default class SwitchMandatoryPropForRelease extends RNCPAppCommand {
this.getCurrentApp().then((app: CurrentApp) => {
if (!app) {
VsCodeUtils.ShowInfoMessage(Strings.NoCurrentAppSetMsg);
VsCodeUtils.ShowWarningMessage(Strings.NoCurrentAppSetMsg);
return;
}
if (!this.hasCodePushDeployments(app)) {
VsCodeUtils.ShowWarningMessage(Strings.NoDeploymentsMsg);
return;
}
const newMandatoryValue = !!!app.isMandatory;

Просмотреть файл

@ -23,6 +23,8 @@ export default class SimulateCrashes extends Command {
} catch {
VsCodeUtils.ShowErrorMessage(Strings.GenerateCrashesError);
}
} else {
VsCodeUtils.ShowWarningMessage(Strings.NoCurrentAppSetMsg);
}
return null;
});

Просмотреть файл

@ -2,3 +2,4 @@ export { default as AppCenter } from './appCenterCommandHandler';
export { default as Settings } from './settingsCommandHandler';
export { default as CodePush } from './codePushCommandHandler';
export { default as Test } from './testCommandHandler';
export { default as Tools } from './toolsCommandHandler';

Просмотреть файл

@ -0,0 +1,13 @@
import * as Tools from "../appcenter/commands/tools";
import BaseCommandHandler from "./baseCommandHandler";
export default class TolsCommandHandler extends BaseCommandHandler {
public async showMenu(): Promise<void> {
await new Tools.ShowTools(this.getCommandParams()).runNoClient();
}
public async simulateCrashes(): Promise<void> {
const cmd = new Tools.SimulateCrashes(this.getCommandParams());
await cmd.run();
}
}

Просмотреть файл

@ -72,6 +72,11 @@ function registerAppCenterCommands(context: vscode.ExtensionContext): void {
context.subscriptions.push(vscode.commands.registerCommand(CommandNames.CodePush.SetTargetBinaryVersion,
() => _extensionManager.RunCommand(() => codepushCommandHandler.SetTargetBinaryVersion())));
// Tools commands
const toolsCommandHandler = _extensionManager.commandHandlers.toolsCommandHandler;
context.subscriptions.push(vscode.commands.registerCommand(CommandNames.Tools.SimulateCrashes,
() => _extensionManager.RunCommand(() => toolsCommandHandler.simulateCrashes())));
// Test commands
const testCommandHandler = _extensionManager.commandHandlers.testCommandHandler;
context.subscriptions.push(vscode.commands.registerCommand(CommandNames.Test.ShowMenu,

Просмотреть файл

@ -4,23 +4,25 @@ import VstsAuth from './appcenter/auth/vstsAuth';
import * as CommandHandlers from './commandHandlers';
import { AuthProvider, CommandNames } from './constants';
import { Profile } from './helpers/interfaces';
import { Utils } from './helpers/utils';
import { VsCodeUtils } from './helpers/vsCodeUtils';
import { ConsoleLogger } from './log/consoleLogger';
import { ILogger } from './log/logHelper';
import { Strings } from './strings';
import { Utils } from './helpers/utils';
class CommandHandlersContainer {
private _appCenterCommandHandler: CommandHandlers.AppCenter;
private _settingsCommandHandler: CommandHandlers.Settings;
private _codePushCommandHandler: CommandHandlers.CodePush;
private _testCommandHandler: CommandHandlers.Test;
private _toolsCommandHandler: CommandHandlers.Tools;
constructor(private manager: ExtensionManager, private logger: ILogger, private appCenterAuth: AppCenterAuth, private vstsAuth: VstsAuth) {
this._appCenterCommandHandler = new CommandHandlers.AppCenter(this.manager, this.logger, this.appCenterAuth, this.vstsAuth);
this._settingsCommandHandler = new CommandHandlers.Settings(this.manager, this.logger, this.appCenterAuth, this.vstsAuth);
this._codePushCommandHandler = new CommandHandlers.CodePush(this.manager, this.logger, this.appCenterAuth, this.vstsAuth);
this._testCommandHandler = new CommandHandlers.Test(this.manager, this.logger, this.appCenterAuth, this.vstsAuth);
this._toolsCommandHandler = new CommandHandlers.Tools(this.manager, this.logger, this.appCenterAuth, this.vstsAuth);
}
public get appCenterCommandHandler(): CommandHandlers.AppCenter {
@ -38,6 +40,10 @@ class CommandHandlersContainer {
public get testCommandHandler(): CommandHandlers.Test {
return this._testCommandHandler;
}
public get toolsCommandHandler(): CommandHandlers.Tools {
return this._toolsCommandHandler;
}
}
export class ExtensionManager implements Disposable {

Просмотреть файл

@ -108,6 +108,8 @@ export class Strings {
public static FailedToConfigureBranchAndStartNewBuild: string = "Sorry, we failed to configure the branch for build.";
public static FailedToCreateDistributionGroup: string = "Sorry, we failed to create any distribution groups.";
public static NoCurrentAppSetMsg: string = "You haven't specified an App Center app for this project.";
public static UnsupportedOSMsg: string = `OS must be "android", "ios", or "windows".`;
public static NoDeploymentsMsg: string = "There are no deployments for current app.";
public static NoProjectRootFolderFound: string = "Please open a project before using this command.";
public static UnknownError: string = "An unknown error has occured. Please check the output window for more details.";
public static GenerateCrashesError: string = "An error occurred while generating crashes. Please check the output window for more details.";