feat: record whether patches were forced, or contain asset/native code changes (#1775)

This commit is contained in:
Bryan Oltman
2024-03-05 12:54:39 -05:00
committed by GitHub
parent 7b8ad1491f
commit 2218d4aa12
15 changed files with 429 additions and 26 deletions
@@ -625,12 +625,18 @@ aar artifact already exists, continuing...''',
Future<Patch> createPatch({
required String appId,
required int releaseId,
required bool wasForced,
required bool hasAssetChanges,
required bool hasNativeChanges,
}) async {
final createPatchProgress = logger.progress('Creating patch');
try {
final patch = await codePushClient.createPatch(
appId: appId,
releaseId: releaseId,
wasForced: wasForced,
hasAssetChanges: hasAssetChanges,
hasNativeChanges: hasNativeChanges,
);
createPatchProgress.complete();
return patch;
@@ -688,6 +694,9 @@ aar artifact already exists, continuing...''',
Future<void> publishPatch({
required String appId,
required int releaseId,
required bool wasForced,
required bool hasAssetChanges,
required bool hasNativeChanges,
required ReleasePlatform platform,
required DeploymentTrack track,
required Map<Arch, PatchArtifactBundle> patchArtifactBundles,
@@ -695,6 +704,9 @@ aar artifact already exists, continuing...''',
final patch = await createPatch(
appId: appId,
releaseId: releaseId,
wasForced: wasForced,
hasAssetChanges: hasAssetChanges,
hasNativeChanges: hasNativeChanges,
);
await createPatchArtifacts(
@@ -201,8 +201,9 @@ Please re-run the release command for this version or create a new release.''');
unzipFn: _unzipFn,
);
final DiffStatus diffStatus;
try {
await patchDiffChecker.confirmUnpatchableDiffsIfNecessary(
diffStatus = await patchDiffChecker.confirmUnpatchableDiffsIfNecessary(
localArtifact: File(
aarArtifactPath(
packageName: shorebirdEnv.androidPackageName!,
@@ -271,6 +272,9 @@ ${summary.join('\n')}
await codePushClientWrapper.publishPatch(
appId: appId,
releaseId: release.id,
wasForced: force,
hasAssetChanges: diffStatus.hasAssetChanges,
hasNativeChanges: diffStatus.hasNativeChanges,
platform: platform,
track: DeploymentTrack.production,
patchArtifactBundles: patchArtifactBundles,
@@ -238,9 +238,9 @@ Current Flutter Revision: $originalFlutterRevision
downloadReleaseArtifactProgress.complete();
final DiffStatus diffStatus;
try {
final diffChecker = patchDiffChecker;
await diffChecker.confirmUnpatchableDiffsIfNecessary(
diffStatus = await patchDiffChecker.confirmUnpatchableDiffsIfNecessary(
localArtifact: File(bundlePath),
releaseArtifact: releaseAabArtifactFile,
archiveDiffer: _archiveDiffer,
@@ -337,6 +337,9 @@ ${summary.join('\n')}
await codePushClientWrapper.publishPatch(
appId: appId,
releaseId: release.id,
wasForced: force,
hasAssetChanges: diffStatus.hasAssetChanges,
hasNativeChanges: diffStatus.hasNativeChanges,
platform: platform,
track: isStaging ? DeploymentTrack.staging : DeploymentTrack.production,
patchArtifactBundles: patchArtifactBundles,
@@ -231,8 +231,10 @@ Current Flutter Revision: $currentFlutterRevision
}
downloadProgress.complete();
final DiffStatus diffStatus;
try {
await patchDiffChecker.zipAndConfirmUnpatchableDiffsIfNecessary(
diffStatus =
await patchDiffChecker.zipAndConfirmUnpatchableDiffsIfNecessary(
localArtifactDirectory: Directory(archivePath),
releaseArtifact: releaseArtifactZipFile,
archiveDiffer: _archiveDiffer,
@@ -369,6 +371,9 @@ ${summary.join('\n')}
await codePushClientWrapper.publishPatch(
appId: appId,
releaseId: release.id,
wasForced: force,
hasAssetChanges: diffStatus.hasAssetChanges,
hasNativeChanges: diffStatus.hasNativeChanges,
platform: releasePlatform,
track: isStaging ? DeploymentTrack.staging : DeploymentTrack.production,
patchArtifactBundles: {
@@ -211,8 +211,10 @@ Please re-run the release command for this version or create a new release.''');
}
downloadProgress.complete();
final DiffStatus diffStatus;
try {
await patchDiffChecker.zipAndConfirmUnpatchableDiffsIfNecessary(
diffStatus =
await patchDiffChecker.zipAndConfirmUnpatchableDiffsIfNecessary(
localArtifactDirectory: Directory(getAppXcframeworkPath()),
releaseArtifact: releaseArtifactZipFile,
archiveDiffer: _archiveDiffer,
@@ -342,6 +344,9 @@ ${summary.join('\n')}
await codePushClientWrapper.publishPatch(
appId: appId,
releaseId: release.id,
wasForced: force,
hasAssetChanges: diffStatus.hasAssetChanges,
hasNativeChanges: diffStatus.hasNativeChanges,
platform: releasePlatform,
track: DeploymentTrack.production,
patchArtifactBundles: {
@@ -7,6 +7,24 @@ import 'package:shorebird_cli/src/archive_analysis/archive_differ.dart';
import 'package:shorebird_cli/src/logger.dart';
import 'package:shorebird_cli/src/shorebird_env.dart';
/// {@template diff_status}
/// Describes the types of changes that have been detected between a patch
/// and its release.
/// {@endtemplate}
class DiffStatus {
/// {@macro diff_status}
DiffStatus({
required this.hasAssetChanges,
required this.hasNativeChanges,
});
/// Whether the patch contains asset changes.
final bool hasAssetChanges;
/// Whether the patch contains native code changes.
final bool hasNativeChanges;
}
/// Thrown when an unpatchable change is detected in an environment where the
/// user cannot be prompted to continue.
class UnpatchableChangeException implements Exception {}
@@ -26,7 +44,7 @@ PatchDiffChecker get patchDiffChecker => read(patchDiffCheckerRef);
class PatchDiffChecker {
/// Zips the contents of [localArtifactDirectory] to a temporary file and
/// forwards to [confirmUnpatchableDiffsIfNecessary].
Future<void> zipAndConfirmUnpatchableDiffsIfNecessary({
Future<DiffStatus> zipAndConfirmUnpatchableDiffsIfNecessary({
required Directory localArtifactDirectory,
required File releaseArtifact,
required ArchiveDiffer archiveDiffer,
@@ -46,7 +64,7 @@ class PatchDiffChecker {
/// Checks for differences that could cause issues when applying the
/// [localArtifact] patch to the [releaseArtifact].
Future<void> confirmUnpatchableDiffsIfNecessary({
Future<DiffStatus> confirmUnpatchableDiffsIfNecessary({
required File localArtifact,
required File releaseArtifact,
required ArchiveDiffer archiveDiffer,
@@ -61,7 +79,14 @@ class PatchDiffChecker {
);
progress.complete();
if (archiveDiffer.containsPotentiallyBreakingNativeDiffs(contentDiffs)) {
final status = DiffStatus(
hasAssetChanges:
archiveDiffer.containsPotentiallyBreakingAssetDiffs(contentDiffs),
hasNativeChanges:
archiveDiffer.containsPotentiallyBreakingNativeDiffs(contentDiffs),
);
if (status.hasNativeChanges) {
logger
..warn(
'''Your app contains native changes, which cannot be applied with a patch.''',
@@ -88,7 +113,7 @@ If you don't know why you're seeing this error, visit our troublshooting page at
}
}
if (archiveDiffer.containsPotentiallyBreakingAssetDiffs(contentDiffs)) {
if (status.hasAssetChanges) {
logger
..warn(
'''Your app contains asset changes, which will not be included in the patch.''',
@@ -109,5 +134,7 @@ If you don't know why you're seeing this error, visit our troublshooting page at
}
}
}
return status;
}
}
@@ -1782,6 +1782,9 @@ Please bump your version number and try again.''',
() => codePushClient.createPatch(
appId: appId,
releaseId: releaseId,
wasForced: any(named: 'wasForced'),
hasAssetChanges: any(named: 'hasAssetChanges'),
hasNativeChanges: any(named: 'hasNativeChanges'),
),
).thenThrow(error);
@@ -1790,6 +1793,9 @@ Please bump your version number and try again.''',
() => codePushClientWrapper.createPatch(
appId: appId,
releaseId: releaseId,
wasForced: false,
hasAssetChanges: false,
hasNativeChanges: false,
),
),
exitsWithCode(ExitCode.software),
@@ -1802,6 +1808,9 @@ Please bump your version number and try again.''',
() => codePushClient.createPatch(
appId: appId,
releaseId: releaseId,
wasForced: any(named: 'wasForced'),
hasAssetChanges: any(named: 'hasAssetChanges'),
hasNativeChanges: any(named: 'hasNativeChanges'),
),
).thenAnswer((_) async => patch);
@@ -1809,6 +1818,9 @@ Please bump your version number and try again.''',
() => codePushClientWrapper.createPatch(
appId: appId,
releaseId: releaseId,
wasForced: false,
hasAssetChanges: false,
hasNativeChanges: false,
),
);
@@ -1935,6 +1947,9 @@ Please bump your version number and try again.''',
() => codePushClient.createPatch(
appId: any(named: 'appId'),
releaseId: any(named: 'releaseId'),
wasForced: any(named: 'wasForced'),
hasAssetChanges: any(named: 'hasAssetChanges'),
hasNativeChanges: any(named: 'hasNativeChanges'),
),
).thenAnswer((_) async => patch);
when(
@@ -1964,6 +1979,9 @@ Please bump your version number and try again.''',
() => codePushClientWrapper.publishPatch(
appId: appId,
releaseId: releaseId,
wasForced: false,
hasAssetChanges: true,
hasNativeChanges: false,
platform: releasePlatform,
track: track,
patchArtifactBundles: patchArtifactBundles,
@@ -1974,6 +1992,9 @@ Please bump your version number and try again.''',
() => codePushClient.createPatch(
appId: appId,
releaseId: releaseId,
wasForced: false,
hasAssetChanges: true,
hasNativeChanges: false,
),
).called(1);
verify(
@@ -2018,6 +2039,9 @@ Please bump your version number and try again.''',
() => codePushClientWrapper.publishPatch(
appId: appId,
releaseId: releaseId,
wasForced: true,
hasAssetChanges: false,
hasNativeChanges: true,
platform: releasePlatform,
track: track,
patchArtifactBundles: patchArtifactBundles,
@@ -2028,6 +2052,9 @@ Please bump your version number and try again.''',
() => codePushClient.createPatch(
appId: appId,
releaseId: releaseId,
wasForced: true,
hasAssetChanges: false,
hasNativeChanges: true,
),
).called(1);
verify(
@@ -2061,6 +2088,9 @@ Please bump your version number and try again.''',
() => codePushClientWrapper.publishPatch(
appId: appId,
releaseId: releaseId,
wasForced: false,
hasAssetChanges: false,
hasNativeChanges: false,
platform: releasePlatform,
track: track,
patchArtifactBundles: patchArtifactBundles,
@@ -137,7 +137,7 @@ void main() {
).called(1);
verify(
() => logger.info(
"Run ${lightCyan.wrap('shorebird logout')} to log out and try again.",
'''Run ${lightCyan.wrap('shorebird logout')} to log out and try again.''',
),
).called(1);
verifyNever(() => auth.login(any(), prompt: any(named: 'prompt')));
@@ -295,6 +295,9 @@ void main() {
() => codePushClientWrapper.publishPatch(
appId: any(named: 'appId'),
releaseId: any(named: 'releaseId'),
wasForced: any(named: 'wasForced'),
hasAssetChanges: any(named: 'hasAssetChanges'),
hasNativeChanges: any(named: 'hasNativeChanges'),
platform: any(named: 'platform'),
track: any(named: 'track'),
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -322,7 +325,12 @@ void main() {
archiveDiffer: archiveDiffer,
force: any(named: 'force'),
),
).thenAnswer((_) async => {});
).thenAnswer(
(_) async => DiffStatus(
hasAssetChanges: false,
hasNativeChanges: false,
),
);
command = runWithOverrides(
() => PatchAarCommand(
@@ -642,6 +650,9 @@ Please re-run the release command for this version or create a new release.'''),
verifyNever(
() => codePushClientWrapper.publishPatch(
appId: any(named: 'appId'),
wasForced: any(named: 'wasForced'),
hasAssetChanges: any(named: 'hasAssetChanges'),
hasNativeChanges: any(named: 'hasNativeChanges'),
releaseId: any(named: 'releaseId'),
platform: any(named: 'platform'),
track: any(named: 'track'),
@@ -680,6 +691,9 @@ Please re-run the release command for this version or create a new release.'''),
() => codePushClientWrapper.publishPatch(
appId: any(named: 'appId'),
releaseId: any(named: 'releaseId'),
wasForced: any(named: 'wasForced'),
hasAssetChanges: any(named: 'hasAssetChanges'),
hasNativeChanges: any(named: 'hasNativeChanges'),
platform: any(named: 'platform'),
track: any(named: 'track'),
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -711,6 +725,9 @@ Please re-run the release command for this version or create a new release.'''),
() => codePushClientWrapper.publishPatch(
appId: any(named: 'appId'),
releaseId: any(named: 'releaseId'),
wasForced: any(named: 'wasForced'),
hasAssetChanges: any(named: 'hasAssetChanges'),
hasNativeChanges: any(named: 'hasNativeChanges'),
platform: any(named: 'platform'),
track: any(named: 'track'),
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -739,6 +756,51 @@ Please re-run the release command for this version or create a new release.'''),
() => codePushClientWrapper.publishPatch(
appId: appId,
releaseId: release.id,
wasForced: true,
hasAssetChanges: any(named: 'hasAssetChanges'),
hasNativeChanges: any(named: 'hasNativeChanges'),
platform: releasePlatform,
track: track,
patchArtifactBundles: any(named: 'patchArtifactBundles'),
),
).called(1);
});
test('reports when patch has asset and native changes', () async {
when(() => argResults['force']).thenReturn(true);
when(() => archiveDiffer.containsPotentiallyBreakingAssetDiffs(any()))
.thenReturn(true);
when(() => archiveDiffer.containsPotentiallyBreakingNativeDiffs(any()))
.thenReturn(true);
when(() => archiveDiffer.changedFiles(any(), any()))
.thenAnswer((_) async => FileSetDiff.empty());
when(
() => patchDiffChecker.confirmUnpatchableDiffsIfNecessary(
localArtifact: any(named: 'localArtifact'),
releaseArtifact: any(named: 'releaseArtifact'),
archiveDiffer: archiveDiffer,
force: any(named: 'force'),
),
).thenAnswer(
(_) async => DiffStatus(
hasAssetChanges: true,
hasNativeChanges: true,
),
);
setUpProjectRootArtifacts();
final exitCode = await runWithOverrides(command.run);
expect(exitCode, equals(ExitCode.success.code));
verifyNever(() => logger.confirm(any()));
verify(
() => codePushClientWrapper.publishPatch(
appId: appId,
releaseId: release.id,
wasForced: true,
hasAssetChanges: true,
hasNativeChanges: true,
platform: releasePlatform,
track: track,
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -786,6 +848,9 @@ Please re-run the release command for this version or create a new release.'''),
() => codePushClientWrapper.publishPatch(
appId: appId,
releaseId: release.id,
wasForced: false,
hasAssetChanges: false,
hasNativeChanges: false,
platform: releasePlatform,
track: track,
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -329,6 +329,9 @@ flutter:
() => codePushClientWrapper.publishPatch(
appId: any(named: 'appId'),
releaseId: any(named: 'releaseId'),
wasForced: any(named: 'wasForced'),
hasAssetChanges: any(named: 'hasAssetChanges'),
hasNativeChanges: any(named: 'hasNativeChanges'),
platform: any(named: 'platform'),
track: any(named: 'track'),
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -361,7 +364,12 @@ flutter:
archiveDiffer: archiveDiffer,
force: any(named: 'force'),
),
).thenAnswer((_) async => {});
).thenAnswer(
(_) async => DiffStatus(
hasAssetChanges: false,
hasNativeChanges: false,
),
);
when(() => shorebirdEnv.isRunningOnCI).thenReturn(false);
});
@@ -669,6 +677,9 @@ Please re-run the release command for this version or create a new release.'''),
() => codePushClientWrapper.publishPatch(
appId: any(named: 'appId'),
releaseId: any(named: 'releaseId'),
wasForced: any(named: 'wasForced'),
hasAssetChanges: any(named: 'hasAssetChanges'),
hasNativeChanges: any(named: 'hasNativeChanges'),
platform: any(named: 'platform'),
track: any(named: 'track'),
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -707,6 +718,9 @@ Please re-run the release command for this version or create a new release.'''),
() => codePushClientWrapper.publishPatch(
appId: any(named: 'appId'),
releaseId: any(named: 'releaseId'),
wasForced: any(named: 'wasForced'),
hasAssetChanges: any(named: 'hasAssetChanges'),
hasNativeChanges: any(named: 'hasNativeChanges'),
platform: any(named: 'platform'),
track: any(named: 'track'),
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -740,6 +754,9 @@ Please re-run the release command for this version or create a new release.'''),
() => codePushClientWrapper.publishPatch(
appId: any(named: 'appId'),
releaseId: any(named: 'releaseId'),
wasForced: any(named: 'wasForced'),
hasAssetChanges: any(named: 'hasAssetChanges'),
hasNativeChanges: any(named: 'hasNativeChanges'),
platform: any(named: 'platform'),
track: any(named: 'track'),
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -763,6 +780,51 @@ Please re-run the release command for this version or create a new release.'''),
() => codePushClientWrapper.publishPatch(
appId: appId,
releaseId: release.id,
wasForced: any(named: 'wasForced'),
hasAssetChanges: any(named: 'hasAssetChanges'),
hasNativeChanges: any(named: 'hasNativeChanges'),
platform: releasePlatform,
track: track,
patchArtifactBundles: any(named: 'patchArtifactBundles'),
),
).called(1);
});
test('reports when patch has asset and native changes', () async {
when(() => argResults['force']).thenReturn(true);
when(() => archiveDiffer.containsPotentiallyBreakingAssetDiffs(any()))
.thenReturn(true);
when(() => archiveDiffer.containsPotentiallyBreakingNativeDiffs(any()))
.thenReturn(true);
when(() => archiveDiffer.changedFiles(any(), any()))
.thenAnswer((_) async => FileSetDiff.empty());
when(
() => patchDiffChecker.confirmUnpatchableDiffsIfNecessary(
localArtifact: any(named: 'localArtifact'),
releaseArtifact: any(named: 'releaseArtifact'),
archiveDiffer: archiveDiffer,
force: any(named: 'force'),
),
).thenAnswer(
(_) async => DiffStatus(
hasAssetChanges: true,
hasNativeChanges: true,
),
);
setUpProjectRootArtifacts();
final exitCode = await runWithOverrides(command.run);
expect(exitCode, equals(ExitCode.success.code));
verifyNever(() => logger.confirm(any()));
verify(
() => codePushClientWrapper.publishPatch(
appId: appId,
releaseId: release.id,
wasForced: true,
hasAssetChanges: true,
hasNativeChanges: true,
platform: releasePlatform,
track: track,
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -789,6 +851,9 @@ Please re-run the release command for this version or create a new release.'''),
() => codePushClientWrapper.publishPatch(
appId: appId,
releaseId: release.id,
wasForced: false,
hasAssetChanges: false,
hasNativeChanges: false,
platform: releasePlatform,
track: track,
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -817,6 +882,9 @@ Please re-run the release command for this version or create a new release.'''),
() => codePushClientWrapper.publishPatch(
appId: appId,
releaseId: release.id,
wasForced: false,
hasAssetChanges: false,
hasNativeChanges: false,
platform: releasePlatform,
track: DeploymentTrack.staging,
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -841,9 +909,7 @@ Please re-run the release command for this version or create a new release.'''),
).called(1);
});
test(
'succeeds when patch is successful '
'with flavors and target', () async {
test('succeeds when patch is successful with flavors and target', () async {
const flavor = 'development';
const target = './lib/main_development.dart';
when(() => argResults['flavor']).thenReturn(flavor);
@@ -861,6 +927,9 @@ flavors:
() => codePushClientWrapper.publishPatch(
appId: appId,
releaseId: release.id,
wasForced: false,
hasAssetChanges: false,
hasNativeChanges: false,
platform: releasePlatform,
track: track,
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -394,6 +394,9 @@ flutter:
() => codePushClientWrapper.publishPatch(
appId: any(named: 'appId'),
releaseId: any(named: 'releaseId'),
wasForced: any(named: 'wasForced'),
hasAssetChanges: any(named: 'hasAssetChanges'),
hasNativeChanges: any(named: 'hasNativeChanges'),
platform: any(named: 'platform'),
track: any(named: 'track'),
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -476,7 +479,12 @@ flutter:
archiveDiffer: archiveDiffer,
force: any(named: 'force'),
),
).thenAnswer((_) async => {});
).thenAnswer(
(_) async => DiffStatus(
hasAssetChanges: false,
hasNativeChanges: false,
),
);
command = runWithOverrides(
() => PatchIosCommand(archiveDiffer: archiveDiffer),
@@ -904,6 +912,9 @@ Please re-run the release command for this version or create a new release.'''),
() => codePushClientWrapper.publishPatch(
appId: any(named: 'appId'),
releaseId: any(named: 'releaseId'),
wasForced: any(named: 'wasForced'),
hasAssetChanges: any(named: 'hasAssetChanges'),
hasNativeChanges: any(named: 'hasNativeChanges'),
platform: any(named: 'platform'),
track: any(named: 'track'),
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -978,6 +989,9 @@ Please re-run the release command for this version or create a new release.'''),
() => codePushClientWrapper.publishPatch(
appId: any(named: 'appId'),
releaseId: any(named: 'releaseId'),
wasForced: any(named: 'wasForced'),
hasAssetChanges: any(named: 'hasAssetChanges'),
hasNativeChanges: any(named: 'hasNativeChanges'),
platform: any(named: 'platform'),
track: any(named: 'track'),
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -1156,6 +1170,9 @@ Please re-run the release command for this version or create a new release.'''),
() => codePushClientWrapper.publishPatch(
appId: appId,
releaseId: postLinkerRelease.id,
wasForced: false,
hasAssetChanges: false,
hasNativeChanges: false,
platform: releasePlatform,
track: track,
patchArtifactBundles: any(
@@ -1178,6 +1195,9 @@ Please re-run the release command for this version or create a new release.'''),
() => codePushClientWrapper.createPatch(
appId: any(named: 'appId'),
releaseId: any(named: 'releaseId'),
wasForced: any(named: 'wasForced'),
hasAssetChanges: any(named: 'hasAssetChanges'),
hasNativeChanges: any(named: 'hasNativeChanges'),
),
);
verify(() => logger.info('No issues detected.')).called(1);
@@ -1194,6 +1214,52 @@ Please re-run the release command for this version or create a new release.'''),
() => codePushClientWrapper.publishPatch(
appId: appId,
releaseId: preLinkerRelease.id,
wasForced: true,
hasAssetChanges: false,
hasNativeChanges: false,
platform: releasePlatform,
track: track,
patchArtifactBundles: any(named: 'patchArtifactBundles'),
),
).called(1);
});
test('reports when patch has asset and native changes', () async {
when(() => argResults['force']).thenReturn(true);
when(() => archiveDiffer.containsPotentiallyBreakingAssetDiffs(any()))
.thenReturn(true);
when(() => archiveDiffer.containsPotentiallyBreakingNativeDiffs(any()))
.thenReturn(true);
when(() => archiveDiffer.changedFiles(any(), any()))
.thenAnswer((_) async => FileSetDiff.empty());
when(
() => patchDiffChecker.zipAndConfirmUnpatchableDiffsIfNecessary(
localArtifactDirectory: any(named: 'localArtifactDirectory'),
releaseArtifact: any(named: 'releaseArtifact'),
archiveDiffer: archiveDiffer,
force: any(named: 'force'),
),
).thenAnswer(
(_) async => DiffStatus(
hasAssetChanges: true,
hasNativeChanges: true,
),
);
setUpProjectRoot();
setUpProjectRootArtifacts();
final exitCode = await runWithOverrides(command.run);
expect(exitCode, equals(ExitCode.success.code));
verifyNever(() => logger.confirm(any()));
verify(
() => codePushClientWrapper.publishPatch(
appId: appId,
releaseId: preLinkerRelease.id,
wasForced: true,
hasAssetChanges: true,
hasNativeChanges: true,
platform: releasePlatform,
track: track,
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -1220,6 +1286,9 @@ Please re-run the release command for this version or create a new release.'''),
() => codePushClientWrapper.publishPatch(
appId: appId,
releaseId: preLinkerRelease.id,
wasForced: false,
hasAssetChanges: false,
hasNativeChanges: false,
platform: releasePlatform,
track: track,
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -1264,6 +1333,9 @@ Please re-run the release command for this version or create a new release.'''),
() => codePushClientWrapper.publishPatch(
appId: appId,
releaseId: preLinkerRelease.id,
wasForced: false,
hasAssetChanges: false,
hasNativeChanges: false,
platform: releasePlatform,
track: DeploymentTrack.staging,
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -1335,9 +1407,7 @@ Please re-run the release command for this version or create a new release.'''),
);
});
test(
'succeeds when patch is successful '
'with flavors and target', () async {
test('succeeds when patch is successful with flavors and target', () async {
const flavor = 'development';
const target = './lib/main_development.dart';
when(() => argResults['flavor']).thenReturn(flavor);
@@ -1356,6 +1426,9 @@ flavors:
() => codePushClientWrapper.publishPatch(
appId: appId,
releaseId: preLinkerRelease.id,
wasForced: false,
hasAssetChanges: false,
hasNativeChanges: false,
platform: releasePlatform,
track: track,
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -193,6 +193,7 @@ flutter:
setUpAll(() {
registerFallbackValue(Directory(''));
registerFallbackValue(File(''));
registerFallbackValue(FileSetDiff.empty());
registerFallbackValue(ReleasePlatform.ios);
registerFallbackValue(Uri.parse('https://example.com'));
registerFallbackValue(DeploymentTrack.production);
@@ -359,6 +360,9 @@ flutter:
() => codePushClientWrapper.publishPatch(
appId: any(named: 'appId'),
releaseId: any(named: 'releaseId'),
wasForced: any(named: 'wasForced'),
hasAssetChanges: any(named: 'hasAssetChanges'),
hasNativeChanges: any(named: 'hasNativeChanges'),
platform: any(named: 'platform'),
track: any(named: 'track'),
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -386,7 +390,12 @@ flutter:
archiveDiffer: archiveDiffer,
force: any(named: 'force'),
),
).thenAnswer((_) async => {});
).thenAnswer(
(_) async => DiffStatus(
hasAssetChanges: false,
hasNativeChanges: false,
),
);
command = runWithOverrides(
() => PatchIosFrameworkCommand(archiveDiffer: archiveDiffer),
@@ -723,6 +732,9 @@ Please re-run the release command for this version or create a new release.'''),
() => codePushClientWrapper.publishPatch(
appId: any(named: 'appId'),
releaseId: any(named: 'releaseId'),
wasForced: any(named: 'wasForced'),
hasAssetChanges: any(named: 'hasAssetChanges'),
hasNativeChanges: any(named: 'hasNativeChanges'),
platform: any(named: 'platform'),
track: any(named: 'track'),
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -760,6 +772,9 @@ Please re-run the release command for this version or create a new release.'''),
() => codePushClientWrapper.publishPatch(
appId: any(named: 'appId'),
releaseId: any(named: 'releaseId'),
wasForced: any(named: 'wasForced'),
hasAssetChanges: any(named: 'hasAssetChanges'),
hasNativeChanges: any(named: 'hasNativeChanges'),
platform: any(named: 'platform'),
track: any(named: 'track'),
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -777,6 +792,9 @@ Please re-run the release command for this version or create a new release.'''),
() => codePushClientWrapper.createPatch(
appId: any(named: 'appId'),
releaseId: any(named: 'releaseId'),
wasForced: any(named: 'wasForced'),
hasAssetChanges: any(named: 'hasAssetChanges'),
hasNativeChanges: any(named: 'hasNativeChanges'),
),
);
verify(() => logger.info('No issues detected.')).called(1);
@@ -793,6 +811,51 @@ Please re-run the release command for this version or create a new release.'''),
() => codePushClientWrapper.publishPatch(
appId: appId,
releaseId: preLinkerRelease.id,
wasForced: true,
hasAssetChanges: false,
hasNativeChanges: false,
platform: ReleasePlatform.ios,
track: track,
patchArtifactBundles: any(named: 'patchArtifactBundles'),
),
).called(1);
});
test('reports when patch has asset and native changes', () async {
when(() => argResults['force']).thenReturn(true);
when(() => archiveDiffer.containsPotentiallyBreakingAssetDiffs(any()))
.thenReturn(true);
when(() => archiveDiffer.containsPotentiallyBreakingNativeDiffs(any()))
.thenReturn(true);
when(() => archiveDiffer.changedFiles(any(), any()))
.thenAnswer((_) async => FileSetDiff.empty());
when(
() => patchDiffChecker.zipAndConfirmUnpatchableDiffsIfNecessary(
localArtifactDirectory: any(named: 'localArtifactDirectory'),
releaseArtifact: any(named: 'releaseArtifact'),
archiveDiffer: archiveDiffer,
force: any(named: 'force'),
),
).thenAnswer(
(_) async => DiffStatus(
hasAssetChanges: true,
hasNativeChanges: true,
),
);
setUpProjectRootArtifacts();
final exitCode = await runWithOverrides(command.run);
expect(exitCode, equals(ExitCode.success.code));
verifyNever(() => logger.confirm(any()));
verify(
() => codePushClientWrapper.publishPatch(
appId: appId,
releaseId: postLinkerRelease.id,
wasForced: true,
hasAssetChanges: true,
hasNativeChanges: true,
platform: ReleasePlatform.ios,
track: track,
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -819,6 +882,9 @@ Please re-run the release command for this version or create a new release.'''),
() => codePushClientWrapper.publishPatch(
appId: appId,
releaseId: preLinkerRelease.id,
wasForced: false,
hasAssetChanges: false,
hasNativeChanges: false,
platform: ReleasePlatform.ios,
track: track,
patchArtifactBundles: any(named: 'patchArtifactBundles'),
@@ -1021,6 +1087,9 @@ Please re-run the release command for this version or create a new release.'''),
() => codePushClientWrapper.publishPatch(
appId: appId,
releaseId: preLinkerRelease.id,
wasForced: false,
hasAssetChanges: false,
hasNativeChanges: false,
platform: ReleasePlatform.ios,
track: track,
patchArtifactBundles: any(
@@ -40,7 +40,13 @@ Future<void> main() async {
);
// Create a new patch.
final patch = await client.createPatch(appId: app.id, releaseId: release.id);
final patch = await client.createPatch(
appId: app.id,
releaseId: release.id,
wasForced: false,
hasAssetChanges: false,
hasNativeChanges: false,
);
// Create a patch artifact.
await client.createPatchArtifact(
@@ -245,10 +245,19 @@ class CodePushClient {
Future<Patch> createPatch({
required String appId,
required int releaseId,
required bool wasForced,
required bool hasAssetChanges,
required bool hasNativeChanges,
}) async {
final request = CreatePatchRequest(
releaseId: releaseId,
wasForced: wasForced,
hasAssetChanges: hasAssetChanges,
hasNativeChanges: hasNativeChanges,
);
final response = await _httpClient.post(
Uri.parse('$_v1/apps/$appId/patches'),
body: json.encode({'release_id': releaseId}),
body: json.encode(request.toJson()),
);
if (response.statusCode != HttpStatus.ok) {
@@ -820,7 +820,15 @@ void main() {
const releaseId = 0;
test('makes the correct request', () async {
codePushClient.createPatch(appId: appId, releaseId: releaseId).ignore();
codePushClient
.createPatch(
appId: appId,
releaseId: releaseId,
wasForced: true,
hasAssetChanges: false,
hasNativeChanges: true,
)
.ignore();
final request = verify(() => httpClient.send(captureAny()))
.captured
.single as http.BaseRequest;
@@ -838,7 +846,13 @@ void main() {
);
expect(
codePushClient.createPatch(appId: appId, releaseId: releaseId),
codePushClient.createPatch(
appId: appId,
releaseId: releaseId,
wasForced: true,
hasAssetChanges: false,
hasNativeChanges: true,
),
throwsA(
isA<CodePushException>().having(
(e) => e.message,
@@ -858,7 +872,13 @@ void main() {
);
expect(
codePushClient.createPatch(appId: appId, releaseId: releaseId),
codePushClient.createPatch(
appId: appId,
releaseId: releaseId,
wasForced: true,
hasAssetChanges: false,
hasNativeChanges: true,
),
throwsA(
isA<CodePushException>().having(
(e) => e.message,
@@ -884,7 +904,13 @@ void main() {
);
await expectLater(
codePushClient.createPatch(appId: appId, releaseId: releaseId),
codePushClient.createPatch(
appId: appId,
releaseId: releaseId,
wasForced: true,
hasAssetChanges: false,
hasNativeChanges: true,
),
completion(
equals(
isA<Patch>()