Skip to content

Commit

Permalink
[eas-cli] Add rollbackPercentage flag to update command
Browse files Browse the repository at this point in the history
  • Loading branch information
wschurman committed Aug 20, 2024
1 parent 2332815 commit 85ec3a8
Show file tree
Hide file tree
Showing 11 changed files with 1,194 additions and 166 deletions.
793 changes: 741 additions & 52 deletions packages/eas-cli/graphql.schema.json

Large diffs are not rendered by default.

83 changes: 69 additions & 14 deletions packages/eas-cli/src/commands/update/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Platform as PublishPlatform } from '@expo/config';
import { Workflow } from '@expo/eas-build-job';
import { Errors, Flags } from '@oclif/core';
import chalk from 'chalk';
Expand All @@ -16,24 +15,25 @@ import {
StatuspageServiceName,
UpdateInfoGroup,
UpdatePublishMutation,
UpdateRolloutInfoGroup,
} from '../../graphql/generated';
import { PublishMutation } from '../../graphql/mutations/PublishMutation';
import Log, { learnMore, link } from '../../log';
import { ora } from '../../ora';
import { RequestedPlatform } from '../../platform';
import { getOwnerAccountForProjectIdAsync } from '../../project/projectUtils';
import {
ExpoCLIExportPlatformFlag,
RawAsset,
UpdatePublishPlatform,
buildBundlesAsync,
buildUnsortedUpdateInfoGroupAsync,
collectAssetsAsync,
defaultPublishPlatforms,
filterExportedPlatformsByFlag,
filterCollectedAssetsByRequestedPlatforms,
generateEasMetadataAsync,
getBranchNameForCommandAsync,
getRequestedPlatform,
getRuntimeToPlatformMappingFromRuntimeVersions,
getRuntimeToUpdateRolloutInfoGroupMappingAsync,
getRuntimeVersionObjectAsync,
getUpdateMessageForCommandAsync,
isUploadedAssetCountAboveWarningThreshold,
Expand Down Expand Up @@ -66,24 +66,26 @@ type RawUpdateFlags = {
'skip-bundler': boolean;
'clear-cache': boolean;
'private-key-path'?: string;
'non-interactive': boolean;
'emit-metadata': boolean;
'rollout-percentage'?: number;
'non-interactive': boolean;
json: boolean;
};

type UpdateFlags = {
auto: boolean;
platform: ExpoCLIExportPlatformFlag;
platform: RequestedPlatform;
branchName?: string;
channelName?: string;
updateMessage?: string;
inputDir: string;
skipBundler: boolean;
clearCache: boolean;
privateKeyPath?: string;
emitMetadata: boolean;
rolloutPercentage?: number;
json: boolean;
nonInteractive: boolean;
emitMetadata: boolean;
};

export default class UpdatePublish extends EasCommand {
Expand Down Expand Up @@ -120,6 +122,12 @@ export default class UpdatePublish extends EasCommand {
description: `Emit "eas-update-metadata.json" in the bundle folder with detailed information about the generated updates`,
default: false,
}),
'rollout-percentage': Flags.integer({
description: `Percentage of users this update should be immediately available to. Users not in the rollout will be served the previous latest update on the branch, even if that update is itself being rolled out. The specified number must be an integer between 1 and 100. When not specified, this defaults to 100.`,
required: false,
min: 0,
max: 100,
}),
platform: Flags.enum({
char: 'p',
options: [
Expand Down Expand Up @@ -153,7 +161,7 @@ export default class UpdatePublish extends EasCommand {
const paginatedQueryOptions = getPaginatedQueryOptions(rawFlags);
const {
auto: autoFlag,
platform: platformFlag,
platform: requestedPlatform,
channelName: channelNameArg,
updateMessage: updateMessageArg,
inputDir,
Expand All @@ -164,6 +172,7 @@ export default class UpdatePublish extends EasCommand {
nonInteractive,
branchName: branchNameArg,
emitMetadata,
rolloutPercentage,
} = this.sanitizeFlags(rawFlags);

const {
Expand Down Expand Up @@ -192,7 +201,7 @@ export default class UpdatePublish extends EasCommand {

await ensureEASUpdateIsConfiguredAsync({
exp: expPossiblyWithoutEasUpdateConfigured,
platform: getRequestedPlatform(platformFlag),
platform: requestedPlatform,
projectDir,
projectId,
vcsClient,
Expand Down Expand Up @@ -225,7 +234,13 @@ export default class UpdatePublish extends EasCommand {
if (!skipBundler) {
const bundleSpinner = ora().start('Exporting...');
try {
await buildBundlesAsync({ projectDir, inputDir, exp, platformFlag, clearCache });
await buildBundlesAsync({
projectDir,
inputDir,
exp,
platformFlag: requestedPlatform,
clearCache,
});
bundleSpinner.succeed('Exported bundle(s)');
} catch (e) {
bundleSpinner.fail('Export failed');
Expand All @@ -240,12 +255,12 @@ export default class UpdatePublish extends EasCommand {
let unsortedUpdateInfoGroups: UpdateInfoGroup = {};
let uploadedAssetCount = 0;
let assetLimitPerUpdateGroup = 0;
let realizedPlatforms: PublishPlatform[] = [];
let realizedPlatforms: UpdatePublishPlatform[] = [];

try {
const collectedAssets = await collectAssetsAsync(distRoot);
const assets = filterExportedPlatformsByFlag(collectedAssets, platformFlag);
realizedPlatforms = Object.keys(assets) as PublishPlatform[];
const assets = filterCollectedAssetsByRequestedPlatforms(collectedAssets, requestedPlatform);
realizedPlatforms = Object.keys(assets) as UpdatePublishPlatform[];

// Timeout mechanism:
// - Start with NO_ACTIVITY_TIMEOUT. 180 seconds is chosen because the cloud function that processes
Expand Down Expand Up @@ -338,7 +353,7 @@ export default class UpdatePublish extends EasCommand {
Log.debug(chalk.dim(`- ${uploadedAssetPath}`));
}

const platformString = (Object.keys(assets) as PublishPlatform[])
const platformString = realizedPlatforms
.map(platform => {
const collectedAssetForPlatform = nullthrows(assets[platform]);
const totalAssetsForPlatform = collectedAssetForPlatform.assets.length + 1; // launch asset
Expand Down Expand Up @@ -376,6 +391,16 @@ export default class UpdatePublish extends EasCommand {
branchName,
});

const runtimeVersionToRolloutInfoGroup =
rolloutPercentage !== undefined
? await getRuntimeToUpdateRolloutInfoGroupMappingAsync(graphqlClient, {
appId: projectId,
branchName,
rolloutPercentage,
runtimeToPlatformMapping,
})
: undefined;

const gitCommitHash = await vcsClient.getCommitHashAsync();
const isGitWorkingTreeDirty = await vcsClient.hasUncommittedChangesAsync();

Expand All @@ -389,9 +414,22 @@ export default class UpdatePublish extends EasCommand {
])
);

const rolloutInfoGroupForRuntimeVersion = runtimeVersionToRolloutInfoGroup
? runtimeVersionToRolloutInfoGroup.get(runtimeVersion)
: null;
const localRolloutInfoGroup = rolloutInfoGroupForRuntimeVersion
? Object.fromEntries(
platforms.map(platform => [
platform,
rolloutInfoGroupForRuntimeVersion[platform as keyof UpdateRolloutInfoGroup],
])
)
: null;

return {
branchId,
updateInfoGroup: localUpdateInfoGroup,
rolloutInfoGroup: localRolloutInfoGroup,
runtimeVersion,
message: updateMessage,
gitCommitHash,
Expand Down Expand Up @@ -505,6 +543,22 @@ export default class UpdatePublish extends EasCommand {
? [{ label: 'Android update ID', value: newAndroidUpdate.id }]
: []),
...(newIosUpdate ? [{ label: 'iOS update ID', value: newIosUpdate.id }] : []),
...(newAndroidUpdate && newAndroidUpdate.rolloutControlUpdate
? [
{
label: 'Android Rollout',
value: `${newAndroidUpdate.rolloutPercentage}% (Base update ID: ${newAndroidUpdate.rolloutControlUpdate.id})`,
},
]
: []),
...(newIosUpdate && newIosUpdate.rolloutControlUpdate
? [
{
label: 'iOS Rollout',
value: `${newIosUpdate.rolloutPercentage}% (Base update ID: ${newIosUpdate.rolloutControlUpdate.id})`,
},
]
: []),
{ label: 'Message', value: updateMessage ?? '' },
...(gitCommitHash
? [
Expand Down Expand Up @@ -565,6 +619,7 @@ export default class UpdatePublish extends EasCommand {
clearCache: flags['clear-cache'],
platform: flags.platform as RequestedPlatform,
privateKeyPath: flags['private-key-path'],
rolloutPercentage: flags['rollout-percentage'],
nonInteractive,
emitMetadata,
json: flags.json ?? false,
Expand Down
10 changes: 7 additions & 3 deletions packages/eas-cli/src/commands/update/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,13 @@ export default class UpdateList extends EasCommand {
}

if (all) {
listAndRenderUpdateGroupsOnAppAsync(graphqlClient, { projectId, paginatedQueryOptions });
await listAndRenderUpdateGroupsOnAppAsync(graphqlClient, {
projectId,
paginatedQueryOptions,
});
} else {
if (branchFlag) {
listAndRenderUpdateGroupsOnBranchAsync(graphqlClient, {
await listAndRenderUpdateGroupsOnBranchAsync(graphqlClient, {
projectId,
branchName: branchFlag,
paginatedQueryOptions,
Expand All @@ -81,7 +84,8 @@ export default class UpdateList extends EasCommand {
offset: 0,
},
});
listAndRenderUpdateGroupsOnBranchAsync(graphqlClient, {

await listAndRenderUpdateGroupsOnBranchAsync(graphqlClient, {
projectId,
branchName: selectedBranch.name,
paginatedQueryOptions,
Expand Down
11 changes: 5 additions & 6 deletions packages/eas-cli/src/commands/update/roll-back-to-embedded.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@ import {
getOwnerAccountForProjectIdAsync,
} from '../../project/projectUtils';
import {
ExpoCLIExportPlatformFlag,
UpdatePublishPlatform,
defaultPublishPlatforms,
getBranchNameForCommandAsync,
getRequestedPlatform,
getRuntimeToPlatformMappingFromRuntimeVersions,
getRuntimeVersionObjectAsync,
getUpdateMessageForCommandAsync,
Expand Down Expand Up @@ -60,7 +59,7 @@ type RawUpdateFlags = {

type UpdateFlags = {
auto: boolean;
platform: ExpoCLIExportPlatformFlag;
platform: RequestedPlatform;
branchName?: string;
channelName?: string;
updateMessage?: string;
Expand Down Expand Up @@ -150,7 +149,7 @@ export default class UpdateRollBackToEmbedded extends EasCommand {

await ensureEASUpdateIsConfiguredAsync({
exp: expPossiblyWithoutEasUpdateConfigured,
platform: getRequestedPlatform(platformFlag),
platform: platformFlag,
projectDir,
projectId,
vcsClient,
Expand Down Expand Up @@ -182,7 +181,7 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
jsonFlag,
});

const realizedPlatforms: PublishPlatform[] =
const realizedPlatforms: UpdatePublishPlatform[] =
platformFlag === 'all' ? defaultPublishPlatforms : [platformFlag];

const { branchId } = await ensureBranchExistsAsync(graphqlClient, {
Expand Down Expand Up @@ -300,7 +299,7 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
updateMessage: string | undefined;
branchId: string;
codeSigningInfo: CodeSigningInfo | undefined;
runtimeVersions: { platform: string; runtimeVersion: string }[];
runtimeVersions: { platform: UpdatePublishPlatform; runtimeVersion: string }[];
realizedPlatforms: PublishPlatform[];
}): Promise<UpdatePublishMutation['updateBranch']['publishUpdateGroups']> {
const runtimeToPlatformMapping =
Expand Down
Loading

0 comments on commit 85ec3a8

Please sign in to comment.