Fix upgrade --start-from-workspace-id (#20116)

# Introduction
Prevent using both `--start-from-workspace-id` and `--workspace`

When any of the two are being passed we prevent passing to the next
instance segment, it would require an upgrade re run even if legit

When `--start-from-workspace-id` is passed we filter from all the
fetched active or suspended workspace ids and apply equivalent filter as
before
This commit is contained in:
Paul Rastoin
2026-04-28 18:46:15 +02:00
committed by GitHub
parent 6aec449a56
commit d2dda67596
3 changed files with 235 additions and 9 deletions
@@ -69,12 +69,14 @@ export class UpgradeSequenceRunnerService {
if (step.kind === 'fast-instance' || step.kind === 'slow-instance') {
if (
isDefined(options.workspaceIds) &&
options.workspaceIds.length > 0
(isDefined(options.workspaceIds) &&
options.workspaceIds.length > 0) ||
isDefined(options.startFromWorkspaceId) ||
isDefined(options.workspaceCountLimit)
) {
this.logger.log(
`Stopping before instance step "${step.name}": ` +
'upgrade was run with workspace filter (-w). ' +
'upgrade was run with a workspace filter (-w, --start-from-workspace-id, or --workspace-count-limit). ' +
'Instance commands require all workspaces to be aligned.',
);
@@ -303,15 +305,13 @@ export class UpgradeSequenceRunnerService {
allActiveOrSuspendedWorkspaceIds: string[];
options: ParsedUpgradeCommandOptions;
}): Promise<WorkspaceIteratorReport> {
const workspaceIds =
isDefined(options.workspaceIds) && options.workspaceIds.length > 0
? options.workspaceIds
: allActiveOrSuspendedWorkspaceIds;
const workspaceIds = this.deriveWorkspaceIdsToProcess({
allActiveOrSuspendedWorkspaceIds,
options,
});
return this.workspaceIteratorService.iterate({
workspaceIds,
startFromWorkspaceId: options.startFromWorkspaceId,
workspaceCountLimit: options.workspaceCountLimit,
dryRun: options.dryRun,
callback: async (context) => {
const workspaceCursor = workspaceCursors.get(context.workspaceId);
@@ -337,6 +337,32 @@ export class UpgradeSequenceRunnerService {
});
}
private deriveWorkspaceIdsToProcess({
allActiveOrSuspendedWorkspaceIds,
options,
}: {
allActiveOrSuspendedWorkspaceIds: string[];
options: ParsedUpgradeCommandOptions;
}): string[] {
if (isDefined(options.workspaceIds) && options.workspaceIds.length > 0) {
return options.workspaceIds;
}
let workspaceIds = allActiveOrSuspendedWorkspaceIds;
if (isDefined(options.startFromWorkspaceId)) {
workspaceIds = workspaceIds.filter(
(id) => id >= options.startFromWorkspaceId!,
);
}
if (isDefined(options.workspaceCountLimit)) {
workspaceIds = workspaceIds.slice(0, options.workspaceCountLimit);
}
return workspaceIds;
}
private enforceWorkspacesCompletedPreviousWorkspaceSegment({
sequence,
previousWorkspaceStep,