eas-cli
Version:
EAS command line tool
145 lines (144 loc) • 8.42 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.republishAsync = void 0;
const tslib_1 = require("tslib");
const assert_1 = tslib_1.__importDefault(require("assert"));
const nullthrows_1 = tslib_1.__importDefault(require("nullthrows"));
const url_1 = require("../build/utils/url");
const fetch_1 = tslib_1.__importDefault(require("../fetch"));
const PublishMutation_1 = require("../graphql/mutations/PublishMutation");
const log_1 = tslib_1.__importStar(require("../log"));
const ora_1 = require("../ora");
const projectUtils_1 = require("../project/projectUtils");
const code_signing_1 = require("../utils/code-signing");
const formatFields_1 = tslib_1.__importDefault(require("../utils/formatFields"));
const json_1 = require("../utils/json");
/**
* @param updatesToPublish The update group to republish
* @param targetBranch The branch to repubish the update group on
*/
async function republishAsync({ graphqlClient, app, updatesToPublish, targetBranch, updateMessage, codeSigningInfo, json, }) {
const { branchName: targetBranchName, branchId: targetBranchId } = targetBranch;
// The update group properties are the same for all updates
(0, assert_1.default)(updatesToPublish.length > 0, 'Updates to republish must be provided');
const arbitraryUpdate = updatesToPublish[0];
const isSameGroup = (update) => update.groupId === arbitraryUpdate.groupId &&
update.branchId === arbitraryUpdate.branchId &&
update.branchName === arbitraryUpdate.branchName &&
update.runtimeVersion === arbitraryUpdate.runtimeVersion;
(0, assert_1.default)(updatesToPublish.every(isSameGroup), 'All updates being republished must belong to the same update group');
(0, assert_1.default)(updatesToPublish.every(u => u.isRollBackToEmbedded) ||
updatesToPublish.every(u => !u.isRollBackToEmbedded), 'All updates must either be roll back to embedded updates or not');
(0, assert_1.default)(!updatesToPublish.some(u => !!u.rolloutControlUpdate), 'Cannot republish an update that is being rolled-out. Either complete the update rollout and then republish or publish a new rollout update.');
const { runtimeVersion } = arbitraryUpdate;
// If codesigning was created for the original update, we need to add it to the republish.
// If one wishes to not sign the republish or sign with a different key, a normal publish should
// be performed.
const shouldRepublishWithCodesigning = updatesToPublish.some(update => update.codeSigningInfo);
if (shouldRepublishWithCodesigning) {
if (!codeSigningInfo) {
throw new Error('Must specify --private-key-path argument to sign republished update group for code signing');
}
for (const update of updatesToPublish) {
if ((0, nullthrows_1.default)(update.codeSigningInfo).alg !== codeSigningInfo.codeSigningMetadata.alg ||
(0, nullthrows_1.default)(update.codeSigningInfo).keyid !== codeSigningInfo.codeSigningMetadata.keyid) {
throw new Error('Republished updates must use the same code signing key and algorithm as original update');
}
}
log_1.default.withTick(`The republished update group will be signed with the same code signing key and algorithm as the original update`);
}
const publishIndicator = (0, ora_1.ora)('Republishing...').start();
let updatesRepublished;
try {
const arbitraryUpdate = updatesToPublish[0];
const objectToMergeIn = arbitraryUpdate.isRollBackToEmbedded
? {
rollBackToEmbeddedInfoGroup: Object.fromEntries(updatesToPublish.map(update => [update.platform, true])),
}
: {
updateInfoGroup: Object.fromEntries(updatesToPublish.map(update => [update.platform, JSON.parse(update.manifestFragment)])),
fingerprintInfoGroup: Object.fromEntries(updatesToPublish.map(update => {
const fingerprint = update.fingerprint;
if (!fingerprint) {
return [update.platform, undefined];
}
return [
update.platform,
{
fingerprintHash: fingerprint.hash,
fingerprintSource: fingerprint.source
? {
type: fingerprint.source.type,
bucketKey: fingerprint.source.bucketKey,
isDebugFingerprint: fingerprint.source.isDebugFingerprint,
}
: undefined,
},
];
})),
};
updatesRepublished = await PublishMutation_1.PublishMutation.publishUpdateGroupAsync(graphqlClient, [
{
branchId: targetBranchId,
runtimeVersion,
message: updateMessage,
...objectToMergeIn,
gitCommitHash: updatesToPublish[0].gitCommitHash,
awaitingCodeSigningInfo: !!codeSigningInfo,
},
]);
if (codeSigningInfo) {
log_1.default.log('🔒 Signing republished update group');
await Promise.all(updatesRepublished.map(async (newUpdate) => {
const response = await (0, fetch_1.default)(newUpdate.manifestPermalink, {
method: 'GET',
headers: { accept: 'multipart/mixed' },
});
let signature;
if (newUpdate.isRollBackToEmbedded) {
const directiveBody = (0, nullthrows_1.default)(await (0, code_signing_1.getDirectiveBodyAsync)(response));
(0, code_signing_1.checkDirectiveBodyAgainstUpdateInfoGroup)(directiveBody);
signature = (0, code_signing_1.signBody)(directiveBody, codeSigningInfo);
}
else {
const manifestBody = (0, nullthrows_1.default)(await (0, code_signing_1.getManifestBodyAsync)(response));
(0, code_signing_1.checkManifestBodyAgainstUpdateInfoGroup)(manifestBody, (0, nullthrows_1.default)((0, nullthrows_1.default)(objectToMergeIn.updateInfoGroup)[newUpdate.platform]));
signature = (0, code_signing_1.signBody)(manifestBody, codeSigningInfo);
}
await PublishMutation_1.PublishMutation.setCodeSigningInfoAsync(graphqlClient, newUpdate.id, {
alg: codeSigningInfo.codeSigningMetadata.alg,
keyid: codeSigningInfo.codeSigningMetadata.keyid,
sig: signature,
});
}));
}
publishIndicator.succeed('Republished update group');
}
catch (error) {
publishIndicator.fail('Failed to republish update group');
throw error;
}
if (json) {
(0, json_1.printJsonOnlyOutput)(updatesRepublished);
return;
}
const updatesRepublishedByPlatform = Object.fromEntries(updatesRepublished.map(update => [update.platform, update]));
const arbitraryRepublishedUpdate = updatesRepublished[0];
const updateGroupUrl = (0, url_1.getUpdateGroupUrl)((await (0, projectUtils_1.getOwnerAccountForProjectIdAsync)(graphqlClient, app.projectId)).name, app.exp.slug, arbitraryRepublishedUpdate.group);
log_1.default.addNewLineIfNone();
log_1.default.log((0, formatFields_1.default)([
{ label: 'Branch', value: targetBranchName },
{ label: 'Runtime version', value: arbitraryRepublishedUpdate.runtimeVersion },
{ label: 'Platform', value: updatesRepublished.map(update => update.platform).join(', ') },
{ label: 'Update group ID', value: arbitraryRepublishedUpdate.group },
...(updatesRepublishedByPlatform.android
? [{ label: 'Android update ID', value: updatesRepublishedByPlatform.android.id }]
: []),
...(updatesRepublishedByPlatform.ios
? [{ label: 'iOS update ID', value: updatesRepublishedByPlatform.ios.id }]
: []),
{ label: 'Message', value: updateMessage },
{ label: 'EAS Dashboard', value: (0, log_1.link)(updateGroupUrl, { dim: false }) },
]));
}
exports.republishAsync = republishAsync;