appcenter-cli
Version:
Command line tool for Visual Studio App Center
94 lines (79 loc) • 4.25 kB
text/typescript
import { clientRequest, AppCenterClient, models } from "../../../util/apis";
import { ErrorCodes, failure } from "../../../util/commandline";
import { DefaultApp } from "../../../util/profile";
import { inspect } from "util";
import AzureBlobUploadHelper from "./azure-blob-upload-helper";
// eventually we may want to support AndroidProGuard or UWP here
export enum SymbolType {
Apple = "Apple",
Breakpad = "Breakpad"
}
export default class SymbolsUploadingHelper {
constructor(private client: AppCenterClient, private app: DefaultApp, private debug: Function) {}
public async uploadSymbolsZip(zip: string, symbolType: SymbolType): Promise<void> {
// executing API request to get an upload URL
const uploadingBeginRequestResult = await this.executeSymbolsUploadingBeginRequest(this.client, this.app, symbolType);
// uploading
const symbolUploadId = uploadingBeginRequestResult.symbolUploadId;
try {
// putting ZIP to the specified URL
const uploadUrl: string = uploadingBeginRequestResult.uploadUrl;
await new AzureBlobUploadHelper(this.debug).upload(uploadUrl, zip);
// sending 'committed' API request to finish uploading
await this.executeSymbolsUploadingEndRequest(this.client, this.app, symbolUploadId, "committed");
} catch (error) {
// uploading failed, aborting upload request
await this.abortUploadingRequest(this.client, this.app, symbolUploadId);
throw error;
}
}
private async executeSymbolsUploadingBeginRequest(client: AppCenterClient, app: DefaultApp, symbolType: SymbolType): Promise<models.SymbolUploadBeginResponse> {
this.debug("Executing API request to get uploading URL");
const uploadingBeginResponse = await clientRequest<models.SymbolUploadBeginResponse>((cb) => client.symbolUploads.create(
{ symbolType },
app.ownerName,
app.appName,
cb)).catch((error: any) => {
this.debug(`Failed to start the symbol uploading - ${inspect(error)}`);
throw failure(ErrorCodes.Exception, "failed to start the symbol uploading");
});
this.debug("Analyzing upload start request response status code");
const uploadingBeginStatusCode = uploadingBeginResponse.response.statusCode;
const uploadingBeginStatusMessage = uploadingBeginResponse.response.statusMessage;
if (uploadingBeginStatusCode >= 400) {
throw failure(ErrorCodes.Exception,
`the symbol upload begin API request was rejected: HTTP ${uploadingBeginStatusCode} - ${uploadingBeginStatusMessage}`);
}
return uploadingBeginResponse.result;
}
private async executeSymbolsUploadingEndRequest(client: AppCenterClient, app: DefaultApp, symbolUploadId: string, desiredStatus: SymbolsUploadEndRequestStatus): Promise<models.SymbolUpload> {
this.debug(`Finishing symbols uploading with desired status: ${desiredStatus}`);
const uploadingEndResponse = await clientRequest<models.SymbolUpload>((cb) => client.symbolUploads.complete(
symbolUploadId,
app.ownerName,
app.appName,
desiredStatus,
cb,
)).catch((error: any) => {
this.debug(`Failed to finalize the symbol upload - ${inspect(error)}`);
throw failure(ErrorCodes.Exception, `failed to finalize the symbol upload with status`);
});
this.debug("Analyzing upload end request response status code");
const uploadingEndStatusCode = uploadingEndResponse.response.statusCode;
const uploadingEndStatusMessage = uploadingEndResponse.response.statusMessage;
if (uploadingEndStatusCode >= 400) {
throw failure(ErrorCodes.Exception,
`the symbol upload end API request was rejected: HTTP ${uploadingEndStatusCode} - ${uploadingEndStatusMessage}`);
}
return uploadingEndResponse.result;
}
private async abortUploadingRequest(client: AppCenterClient, app: DefaultApp, symbolUploadId: string): Promise<models.SymbolUpload> {
this.debug("Uploading failed, aborting upload request");
try {
return await this.executeSymbolsUploadingEndRequest(client, app, symbolUploadId, "aborted");
} catch (ex) {
this.debug("Failed to correctly abort the uploading request");
}
}
}
type SymbolsUploadEndRequestStatus = "committed" | "aborted";