in Tasks/GooglePlayReleaseV4/main.ts [12:213]
async function run(): Promise<void> {
try {
tl.setResourcePath(path.join(__dirname, 'task.json'));
tl.debug('Prepare task inputs.');
// Authentication inputs
const key: googleutil.ClientKey = inputsHelper.getClientKey();
// General inputs
const action: inputsHelper.Action = inputsHelper.getAction();
tl.debug(`Action: ${action}`);
const packageName: string = tl.getInput('applicationId', true);
tl.debug(`Application identifier: ${packageName}`);
const bundleFileList: string[] = inputsHelper.getBundles(action);
tl.debug(`Bundles: ${bundleFileList}`);
const apkFileList: string[] = inputsHelper.getApks(action);
tl.debug(`APKs: ${apkFileList}`);
const shouldPickObb: boolean = tl.getBoolInput('shouldPickObbFile', false);
if (shouldPickObb && apkFileList.length === 0) {
throw new Error(tl.loc('MustProvideApkIfObb'));
}
if (action !== 'OnlyStoreListing' && bundleFileList.length === 0 && apkFileList.length === 0) {
throw new Error(tl.loc('MustProvideApkOrAab'));
}
const track: string = tl.getInput('track', true);
const shouldAttachMetadata: boolean = tl.getBoolInput('shouldAttachMetadata', false);
let changelogFile: string = null;
let languageCode: string = null;
let metadataRootPath: string = null;
if (shouldAttachMetadata) {
metadataRootPath = tl.getPathInput('metadataRootPath', true, true);
} else {
changelogFile = tl.getInput('changelogFile', false);
const defaultLanguageCode = 'en-US';
languageCode = tl.getInput('languageCode', false) || defaultLanguageCode;
}
// Advanced inputs
const updatePrioritySupplied: boolean = tl.getBoolInput('changeUpdatePriority');
const updatePriority: number = Number(updatePrioritySupplied ? tl.getInput('updatePriority', false) : 0);
const userFractionSupplied: boolean = tl.getBoolInput('rolloutToUserFraction');
const userFraction: number = Number(userFractionSupplied ? tl.getInput('userFraction', false) : 1.0);
const uploadMappingFile: boolean = tl.getBoolInput('shouldUploadMappingFile', false) && (action === 'SingleApk' || action === 'SingleBundle');
const mappingFilePattern: string = tl.getInput('mappingFilePath');
const changesNotSentForReview: boolean = tl.getBoolInput('changesNotSentForReview');
const releaseName: string = tl.getInput('releaseName', false);
const versionCodeFilterType: string = tl.getInput('versionCodeFilterType', false) || 'all';
let versionCodeFilter: string | number[] = null;
if (versionCodeFilterType === 'list') {
versionCodeFilter = inputsHelper.getVersionCodeListInput();
} else if (versionCodeFilterType === 'expression') {
versionCodeFilter = tl.getInput('replaceExpression', true);
}
inputsHelper.warnAboutUnusedInputs(action);
// The regular submission process is composed
// of a transction with the following steps:
// -----------------------------------------
// #1) Get an OAuth token by authenticating the service account
// #2) Create a new editing transaction
// #3) Upload the new APK(s) or AAB(s)
// #4) Specify the track that should be used for the new APK/AAB (e.g. alpha, beta)
// #5) Specify the new change log
// #6) Commit the edit transaction
const globalParams: googleapis.Common.GlobalOptions = { auth: null, params: {} };
googleutil.updateGlobalParams(globalParams, 'packageName', packageName);
tl.debug('Initializing JWT.');
const jwtClient: googleapis.Common.JWT = googleutil.getJWT(key);
globalParams.auth = jwtClient;
tl.debug('Initializing Google Play publisher API.');
const edits: pub3.Resource$Edits = googleutil.publisher.edits;
tl.debug('Authorize JWT.');
await jwtClient.authorize();
console.log(tl.loc('GetNewEditAfterAuth'));
tl.debug('Creating a new edit transaction in Google Play.');
const edit: pub3.Schema$AppEdit = await googleutil.getNewEdit(edits, packageName);
googleutil.updateGlobalParams(globalParams, 'editId', edit.id);
let requireTrackUpdate = false;
const versionCodes: number[] = [];
if (action === 'OnlyStoreListing') {
tl.debug('Selected store listing update only -> skip APK/AAB reading');
} else {
requireTrackUpdate = true;
tl.debug(`Uploading ${bundleFileList.length} AAB(s).`);
for (const bundleFile of bundleFileList) {
tl.debug(`Uploading bundle ${bundleFile}`);
const bundle: pub3.Schema$Bundle = await googleutil.addBundle(edits, packageName, bundleFile);
tl.debug(`Uploaded ${bundleFile} with the version code ${bundle.versionCode}`);
versionCodes.push(bundle.versionCode);
}
tl.debug(`Uploading ${apkFileList.length} APK(s).`);
for (const apkFile of apkFileList) {
tl.debug(`Uploading APK ${apkFile}`);
const apk: pub3.Schema$Apk = await googleutil.addApk(edits, packageName, apkFile);
tl.debug(`Uploaded ${apkFile} with the version code ${apk.versionCode}`);
if (shouldPickObb) {
const obbFile: string | null = fileHelper.getObbFile(apkFile, packageName, apk.versionCode);
if (obbFile !== null) {
const obb: pub3.Schema$ExpansionFilesUploadResponse | null = await googleutil.addObb(
edits,
packageName,
obbFile,
apk.versionCode,
'main'
);
if (obb.expansionFile.fileSize !== null && Number(obb.expansionFile.fileSize) !== 0) {
console.log(`Uploaded Obb file with version code ${apk.versionCode} and size ${obb.expansionFile.fileSize}`);
}
}
}
versionCodes.push(apk.versionCode);
}
if (uploadMappingFile) {
tl.debug(`Mapping file pattern: ${mappingFilePattern}`);
const mappingFilePath = fileHelper.resolveGlobPath(mappingFilePattern);
tl.checkPath(mappingFilePath, 'Mapping file path');
console.log(tl.loc('FoundDeobfuscationFile', mappingFilePath));
tl.debug(`Uploading ${mappingFilePath} for version code ${versionCodes[0]}`);
await googleutil.uploadDeobfuscation(edits, mappingFilePath, packageName, versionCodes[0]);
}
}
let releaseNotes: googleapis.androidpublisher_v3.Schema$LocalizedText[];
if (shouldAttachMetadata) {
console.log(tl.loc('AttachingMetadataToRelease'));
tl.debug(`Uploading metadata from ${metadataRootPath}`);
releaseNotes = await metadataHelper.addMetadata(edits, versionCodes.map((versionCode) => Number(versionCode)), metadataRootPath);
if (action === 'OnlyStoreListing') {
tl.debug('Selected store listing update -> skip update track');
}
requireTrackUpdate = action !== 'OnlyStoreListing';
} else if (changelogFile) {
tl.debug(`Uploading the common change log ${changelogFile} to all versions`);
const commonNotes = await metadataHelper.getCommonReleaseNotes(languageCode, changelogFile);
releaseNotes = commonNotes && [commonNotes];
requireTrackUpdate = true;
}
if (requireTrackUpdate) {
console.log(tl.loc('UpdateTrack'));
tl.debug(`Updating the track ${track}.`);
const parameters: TrackUpdateParameters = {
edits,
packageName,
track,
versionCodes,
versionCodeFilterType,
versionCodeFilter,
userFraction,
updatePriority,
releaseNotes,
releaseName
};
const updatedTrack: pub3.Schema$Track = await prepareTrackUpdate(parameters);
tl.debug('Updated track info: ' + JSON.stringify(updatedTrack));
}
tl.debug('Committing the edit transaction in Google Play.');
await edits.commit({ changesNotSentForReview });
console.log(tl.loc('TrackInfo', track));
tl.setResult(tl.TaskResult.Succeeded, tl.loc('PublishSucceed'));
} catch (e) {
tl.setResult(tl.TaskResult.Failed, e);
}
}