"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.command = void 0; const fs = require("fs-extra"); const command_1 = require("../command"); const utils = require("../utils"); const requireAuth_1 = require("../requireAuth"); const client_1 = require("../appdistribution/client"); const error_1 = require("../error"); const distribution_1 = require("../appdistribution/distribution"); const options_parser_util_1 = require("../appdistribution/options-parser-util"); function getReleaseNotes(releaseNotes, releaseNotesFile) { if (releaseNotes) { return releaseNotes.replace(/\\n/g, "\n"); } else if (releaseNotesFile) { (0, options_parser_util_1.ensureFileExists)(releaseNotesFile); return fs.readFileSync(releaseNotesFile, "utf8"); } return ""; } exports.command = new command_1.Command("appdistribution:distribute ") .description("upload a release binary") .option("--app ", "the app id of your Firebase app") .option("--release-notes ", "release notes to include") .option("--release-notes-file ", "path to file with release notes") .option("--testers ", "a comma separated list of tester emails to distribute to") .option("--testers-file ", "path to file with a comma separated list of tester emails to distribute to") .option("--groups ", "a comma separated list of group aliases to distribute to") .option("--groups-file ", "path to file with a comma separated list of group aliases to distribute to") .before(requireAuth_1.requireAuth) .action(async (file, options) => { const appName = (0, options_parser_util_1.getAppName)(options); const distribution = new distribution_1.Distribution(file); const releaseNotes = getReleaseNotes(options.releaseNotes, options.releaseNotesFile); const testers = (0, options_parser_util_1.getTestersOrGroups)(options.testers, options.testersFile); const groups = (0, options_parser_util_1.getTestersOrGroups)(options.groups, options.groupsFile); const requests = new client_1.AppDistributionClient(); let aabInfo; if (distribution.distributionFileType() === distribution_1.DistributionFileType.AAB) { try { aabInfo = await requests.getAabInfo(appName); } catch (err) { if (err.status === 404) { throw new error_1.FirebaseError(`App Distribution could not find your app ${options.app}. ` + `Make sure to onboard your app by pressing the "Get started" ` + "button on the App Distribution page in the Firebase console: " + "https://console.firebase.google.com/project/_/appdistribution", { exit: 1 }); } throw new error_1.FirebaseError(`failed to determine AAB info. ${err.message}`, { exit: 1 }); } if (aabInfo.integrationState !== client_1.IntegrationState.INTEGRATED && aabInfo.integrationState !== client_1.IntegrationState.AAB_STATE_UNAVAILABLE) { switch (aabInfo.integrationState) { case client_1.IntegrationState.PLAY_ACCOUNT_NOT_LINKED: { throw new error_1.FirebaseError("This project is not linked to a Google Play account."); } case client_1.IntegrationState.APP_NOT_PUBLISHED: { throw new error_1.FirebaseError('"This app is not published in the Google Play console.'); } case client_1.IntegrationState.NO_APP_WITH_GIVEN_BUNDLE_ID_IN_PLAY_ACCOUNT: { throw new error_1.FirebaseError("App with matching package name does not exist in Google Play."); } case client_1.IntegrationState.PLAY_IAS_TERMS_NOT_ACCEPTED: { throw new error_1.FirebaseError("You must accept the Play Internal App Sharing (IAS) terms to upload AABs."); } default: { throw new error_1.FirebaseError("App Distribution failed to process the AAB: " + aabInfo.integrationState); } } } } utils.logBullet("uploading binary..."); let releaseName; try { const operationName = await requests.uploadRelease(appName, distribution); const uploadResponse = await requests.pollUploadStatus(operationName); const release = uploadResponse.release; switch (uploadResponse.result) { case client_1.UploadReleaseResult.RELEASE_CREATED: utils.logSuccess(`uploaded new release ${release.displayVersion} (${release.buildVersion}) successfully!`); break; case client_1.UploadReleaseResult.RELEASE_UPDATED: utils.logSuccess(`uploaded update to existing release ${release.displayVersion} (${release.buildVersion}) successfully!`); break; case client_1.UploadReleaseResult.RELEASE_UNMODIFIED: utils.logSuccess(`re-uploaded already existing release ${release.displayVersion} (${release.buildVersion}) successfully!`); break; default: utils.logSuccess(`uploaded release ${release.displayVersion} (${release.buildVersion}) successfully!`); } utils.logSuccess(`View this release in the Firebase console: ${release.firebaseConsoleUri}`); utils.logSuccess(`Share this release with testers who have access: ${release.testingUri}`); utils.logSuccess(`Download the release binary (link expires in 1 hour): ${release.binaryDownloadUri}`); releaseName = uploadResponse.release.name; } catch (err) { if (err.status === 404) { throw new error_1.FirebaseError(`App Distribution could not find your app ${options.app}. ` + `Make sure to onboard your app by pressing the "Get started" ` + "button on the App Distribution page in the Firebase console: " + "https://console.firebase.google.com/project/_/appdistribution", { exit: 1 }); } throw new error_1.FirebaseError(`failed to upload release. ${err.message}`, { exit: 1 }); } if (aabInfo && !aabInfo.testCertificate) { aabInfo = await requests.getAabInfo(appName); if (aabInfo.testCertificate) { utils.logBullet("After you upload an AAB for the first time, App Distribution " + "generates a new test certificate. All AAB uploads are re-signed with this test " + "certificate. Use the certificate fingerprints below to register your app " + "signing key with API providers, such as Google Sign-In and Google Maps.\n" + `MD-1 certificate fingerprint: ${aabInfo.testCertificate.hashMd5}\n` + `SHA-1 certificate fingerprint: ${aabInfo.testCertificate.hashSha1}\n` + `SHA-256 certificate fingerprint: ${aabInfo.testCertificate.hashSha256}`); } } await requests.updateReleaseNotes(releaseName, releaseNotes); await requests.distribute(releaseName, testers, groups); });