async function run()

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);
    }
}