Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: warn about diffs when patching macos releases #2679

Merged
merged 82 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
fde077e
feat: add macos release type to shorebird_code_push_protocol
bryanoltman Nov 26, 2024
3aee1a1
feat: add support for releasing and patching macOS apps
bryanoltman Nov 26, 2024
f614b30
Merge branch 'main' into bo/macos
bryanoltman Dec 2, 2024
81870f7
wip
bryanoltman Dec 2, 2024
dfb50a6
merge main
bryanoltman Dec 5, 2024
56bb42c
merge
bryanoltman Dec 5, 2024
0f510fc
update artifact proxy
bryanoltman Dec 5, 2024
3fd6c22
clean
bryanoltman Dec 5, 2024
7694fa5
add support for supplementary release data
bryanoltman Dec 5, 2024
0b30046
Merge branch 'main' into bo/macos
bryanoltman Dec 5, 2024
9f692fb
fix merge
bryanoltman Dec 5, 2024
15830d1
wip
bryanoltman Dec 5, 2024
21ebe63
fix macos patch logic
bryanoltman Dec 6, 2024
3a369d0
remove unused import
bryanoltman Dec 6, 2024
8200548
add separate gen_snapshot for mac
bryanoltman Dec 9, 2024
1922b5e
merge main
bryanoltman Dec 9, 2024
80f4308
chore: add test files for macos releaser/patcher
bryanoltman Dec 9, 2024
88a4954
tests, more wip
bryanoltman Dec 9, 2024
3e9e458
coverage
bryanoltman Dec 9, 2024
cfbd3d5
coverage, cleanup
bryanoltman Dec 9, 2024
274d284
Merge branch 'main' into bo/macos
felangel Dec 10, 2024
fddaced
use correct gen_snapshot when buildElfAotSnapshot
bryanoltman Dec 10, 2024
788badf
fix macos preview
felangel Dec 10, 2024
e1f43f7
fix: use ditto in macos_patcher
felangel Dec 10, 2024
ac4f357
Split macos/ios analyze_snapshot
bryanoltman Dec 10, 2024
ed1adb4
chore: bump flutter rev
bryanoltman Dec 10, 2024
ddfd5e3
wip
bryanoltman Dec 10, 2024
2008b60
fix macos_releaser test
felangel Dec 10, 2024
e1d4141
more test fixes
felangel Dec 10, 2024
b0029aa
fix snapshot paths
bryanoltman Dec 10, 2024
1ef87b1
create `Ditto` wrapper
felangel Dec 10, 2024
6589301
use ditto in code_push_client_wrapper
felangel Dec 11, 2024
9b83494
refactor: use ditto.archive in mac_patcher
felangel Dec 11, 2024
082147d
test: add `ditto` tests
felangel Dec 11, 2024
189176e
passing unit tests
felangel Dec 11, 2024
f3b4ffa
tests: code_push_client_wrapper_test
felangel Dec 11, 2024
0d3cfbb
tests: shorebird_artifacts_test
felangel Dec 11, 2024
8cfcab6
tests: artifact_manager_test
felangel Dec 11, 2024
88b2a61
tests: artifact_manager_test
felangel Dec 11, 2024
3742f45
format
felangel Dec 11, 2024
db17846
fix MacosPatcher tests
bryanoltman Dec 11, 2024
470dd3c
Merge branch 'bo/macos' of github.com:shorebirdtech/shorebird into bo…
bryanoltman Dec 11, 2024
cfc7d4b
cspell
bryanoltman Dec 11, 2024
e80b1d0
cspell
bryanoltman Dec 11, 2024
fc9d430
CSPELL
bryanoltman Dec 11, 2024
0335474
coverage
bryanoltman Dec 11, 2024
38aea73
preview coverage
felangel Dec 11, 2024
fffaa13
coverage
bryanoltman Dec 11, 2024
7d17f5d
artifact build tests/coverage
bryanoltman Dec 11, 2024
9aa731b
format
bryanoltman Dec 11, 2024
02cca6e
formatting
bryanoltman Dec 11, 2024
0e01803
dart pub upgrade with dart 3.6.0
bryanoltman Dec 11, 2024
2d67829
coverage
bryanoltman Dec 11, 2024
07f9ff3
cleanup
bryanoltman Dec 11, 2024
b64b774
coverage
bryanoltman Dec 11, 2024
ed71434
patcher coverage, completeness
bryanoltman Dec 11, 2024
3489664
coverage
bryanoltman Dec 11, 2024
1f4f02a
fix linux tests
bryanoltman Dec 11, 2024
8050350
coverage
bryanoltman Dec 11, 2024
8c8eff7
cleanup, pr feedback
bryanoltman Dec 11, 2024
b9f9bd1
cleanup
bryanoltman Dec 11, 2024
3851d97
lints
bryanoltman Dec 11, 2024
e0d81d6
polish
bryanoltman Dec 11, 2024
1f3cf0e
coverage
bryanoltman Dec 11, 2024
7f5b77f
fix tests
bryanoltman Dec 11, 2024
a39e7f5
print beta warning when releasing or patching macos
bryanoltman Dec 11, 2024
ffe9044
coverage
bryanoltman Dec 11, 2024
9396c17
feat: add validator to check for macOS app network entitlement
bryanoltman Dec 12, 2024
56e9c34
Merge branch 'main' into bo/macos-entitlement-validator
bryanoltman Dec 12, 2024
6c35229
coverage
bryanoltman Dec 12, 2024
731d26c
Use macos podfile.lock for macos builds
bryanoltman Dec 12, 2024
f798345
Merge branch 'bo/macos' into bo/macos-entitlement-validator
bryanoltman Dec 12, 2024
81673c0
Don't pass sequesterRsrc flag to ditto
bryanoltman Dec 12, 2024
b90c7d0
Merge branch 'bo/macos' into bo/macos-entitlement-validator
bryanoltman Dec 12, 2024
59e04de
feat: warn about diffs when patching macos releases
bryanoltman Dec 12, 2024
e1e4ddf
Merge branch 'main' into bo/macos
felangel Dec 12, 2024
e556a25
rename mock
bryanoltman Dec 12, 2024
3bbf32e
remove unused mocks
bryanoltman Dec 12, 2024
f03cc46
coverage
bryanoltman Dec 13, 2024
1d80e45
Merge branch 'bo/macos' into bo/macos-entitlement-validator
bryanoltman Dec 13, 2024
ea7de77
Merge branch 'bo/macos-entitlement-validator' into bo/macos-patch-differ
bryanoltman Dec 13, 2024
4cc6eb1
Merge branch 'main' into bo/macos-patch-differ
bryanoltman Dec 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@
import 'package:shorebird_cli/src/archive_analysis/file_set_diff.dart';
import 'package:shorebird_cli/src/archive_analysis/macho.dart';

/// {@template ios_archive_differ}
/// Finds differences between two IPAs or zipped Xcframeworks.
/// {@template apple_archive_differ}
/// Finds differences between two IPAs, zipped Xcframeworks, or zipped macOS
/// .apps. Note that, due to a quirk in how macOS .app zips are handled by
/// package:archive, they must *not* include the top-level .app directory (i.e.,
/// they should unzip to a Contents directory).
///
/// Asset changes will be in the `Assets.car` file (which is a combination of
/// the `.xcasset` catalogs in the Xcode project) and the `flutter_assets`
Expand All @@ -23,9 +26,9 @@
///
/// Dart changes will appear in the App.framework/App executable.
/// {@endtemplate}
class IosArchiveDiffer extends ArchiveDiffer {
/// {@macro ios_archive_differ}
const IosArchiveDiffer();
class AppleArchiveDiffer extends ArchiveDiffer {
/// {@macro apple_archive_differ}
const AppleArchiveDiffer();

String _hash(List<int> bytes) => sha256.convert(bytes).toString();

Expand All @@ -34,11 +37,16 @@
RegExp(r'Flutter.framework/Flutter$'),
};

/// The regex pattern for identifying app files within an archive.
static final RegExp appRegex = RegExp(
/// The regex pattern for identifying app files within an xcarchive.
static final RegExp xcFrameworkAppRegex = RegExp(

Check warning on line 41 in packages/shorebird_cli/lib/src/archive_analysis/apple_archive_differ.dart

View check run for this annotation

Codecov / codecov/patch

packages/shorebird_cli/lib/src/archive_analysis/apple_archive_differ.dart#L41

Added line #L41 was not covered by tests
r'^Products/Applications/[\w\-. ]+.app/[\w\- ]+$',
);

/// The regex pattern for identifying executable files within a macOS .app.
static final RegExp macosAppRegex = RegExp(

Check warning on line 46 in packages/shorebird_cli/lib/src/archive_analysis/apple_archive_differ.dart

View check run for this annotation

Codecov / codecov/patch

packages/shorebird_cli/lib/src/archive_analysis/apple_archive_differ.dart#L46

Added line #L46 was not covered by tests
r'^Contents/MacOS/.+$',
);

/// Files that have been added, removed, or that have changed between the
/// archives at the two provided paths. This method will also unsign mach-o
/// binaries in the archives before computing the diff.
Expand Down Expand Up @@ -95,7 +103,7 @@
(file) =>
_binaryFilePatterns
.any((pattern) => pattern.hasMatch(file.name)) ||
appRegex.hasMatch(file.name),
xcFrameworkAppRegex.hasMatch(file.name),

Check warning on line 106 in packages/shorebird_cli/lib/src/archive_analysis/apple_archive_differ.dart

View check run for this annotation

Codecov / codecov/patch

packages/shorebird_cli/lib/src/archive_analysis/apple_archive_differ.dart#L106

Added line #L106 was not covered by tests
)
.toList();
}
Expand Down Expand Up @@ -170,5 +178,7 @@
filePath.endsWith('App.framework/App');

@override
bool isNativeFilePath(String filePath) => appRegex.hasMatch(filePath);
bool isNativeFilePath(String filePath) =>
xcFrameworkAppRegex.hasMatch(filePath) ||
macosAppRegex.hasMatch(filePath);

Check warning on line 183 in packages/shorebird_cli/lib/src/archive_analysis/apple_archive_differ.dart

View check run for this annotation

Codecov / codecov/patch

packages/shorebird_cli/lib/src/archive_analysis/apple_archive_differ.dart#L182-L183

Added lines #L182 - L183 were not covered by tests
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export 'android_archive_differ.dart';
export 'apple_archive_differ.dart';
export 'file_set_diff.dart';
export 'ios_archive_differ.dart';
export 'plist.dart';
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import 'package:meta/meta.dart';
import 'package:path/path.dart' as p;
import 'package:platform/platform.dart';
import 'package:shorebird_cli/src/archive/directory_archive.dart';
import 'package:shorebird_cli/src/archive_analysis/ios_archive_differ.dart';
import 'package:shorebird_cli/src/archive_analysis/apple_archive_differ.dart';
import 'package:shorebird_cli/src/artifact_builder.dart';
import 'package:shorebird_cli/src/artifact_manager.dart';
import 'package:shorebird_cli/src/code_push_client_wrapper.dart';
Expand Down Expand Up @@ -96,7 +96,7 @@ class IosFrameworkPatcher extends Patcher {
patchDiffChecker.confirmUnpatchableDiffsIfNecessary(
localArchive: patchArchive,
releaseArchive: releaseArchive,
archiveDiffer: const IosArchiveDiffer(),
archiveDiffer: const AppleArchiveDiffer(),
allowAssetChanges: allowAssetDiffs,
allowNativeChanges: allowNativeDiffs,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ class IosPatcher extends Patcher {
await patchDiffChecker.confirmUnpatchableDiffsIfNecessary(
localArchive: patchArchive,
releaseArchive: releaseArchive,
archiveDiffer: const IosArchiveDiffer(),
archiveDiffer: const AppleArchiveDiffer(),
allowAssetChanges: allowAssetDiffs,
allowNativeChanges: allowNativeDiffs,
confirmNativeChanges: false,
Expand Down
57 changes: 54 additions & 3 deletions packages/shorebird_cli/lib/src/commands/patch/macos_patcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import 'package:path/path.dart' as p;
import 'package:platform/platform.dart';
import 'package:shorebird_cli/src/archive/directory_archive.dart';
import 'package:shorebird_cli/src/archive_analysis/apple_archive_differ.dart';
import 'package:shorebird_cli/src/archive_analysis/plist.dart';
import 'package:shorebird_cli/src/artifact_builder.dart';
import 'package:shorebird_cli/src/artifact_manager.dart';
Expand All @@ -24,6 +25,7 @@
import 'package:shorebird_cli/src/release_type.dart';
import 'package:shorebird_cli/src/shorebird_artifacts.dart';
import 'package:shorebird_cli/src/shorebird_documentation.dart';
import 'package:shorebird_cli/src/shorebird_env.dart';
import 'package:shorebird_cli/src/shorebird_flutter.dart';
import 'package:shorebird_cli/src/shorebird_validator.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
Expand Down Expand Up @@ -106,14 +108,61 @@
}
}

// FIXME: this is a direct copy of IosPatcher's implementation. We should
// consolidate this and other copied code.
@override
Future<DiffStatus> assertUnpatchableDiffs({
required ReleaseArtifact releaseArtifact,
required File releaseArchive,
required File patchArchive,
}) async {
// TODO(bryanoltman): implement assertUnpatchableDiffs
return const DiffStatus(hasAssetChanges: false, hasNativeChanges: false);
// Check for diffs without warning about native changes, as Xcode builds
// can be nondeterministic. So we still have some hope of alerting users of
// unpatchable native changes, we compare the Podfile.lock hash between the
// patch and the release.
final diffStatus =
await patchDiffChecker.confirmUnpatchableDiffsIfNecessary(

Check warning on line 124 in packages/shorebird_cli/lib/src/commands/patch/macos_patcher.dart

View check run for this annotation

Codecov / codecov/patch

packages/shorebird_cli/lib/src/commands/patch/macos_patcher.dart#L124

Added line #L124 was not covered by tests
localArchive: patchArchive,
releaseArchive: releaseArchive,
archiveDiffer: const AppleArchiveDiffer(),
allowAssetChanges: allowAssetDiffs,
allowNativeChanges: allowNativeDiffs,

Check warning on line 129 in packages/shorebird_cli/lib/src/commands/patch/macos_patcher.dart

View check run for this annotation

Codecov / codecov/patch

packages/shorebird_cli/lib/src/commands/patch/macos_patcher.dart#L128-L129

Added lines #L128 - L129 were not covered by tests
confirmNativeChanges: false,
);

if (!diffStatus.hasNativeChanges) {

Check warning on line 133 in packages/shorebird_cli/lib/src/commands/patch/macos_patcher.dart

View check run for this annotation

Codecov / codecov/patch

packages/shorebird_cli/lib/src/commands/patch/macos_patcher.dart#L133

Added line #L133 was not covered by tests
return diffStatus;
}

final String? podfileLockHash;
if (shorebirdEnv.macosPodfileLockFile.existsSync()) {

Check warning on line 138 in packages/shorebird_cli/lib/src/commands/patch/macos_patcher.dart

View check run for this annotation

Codecov / codecov/patch

packages/shorebird_cli/lib/src/commands/patch/macos_patcher.dart#L138

Added line #L138 was not covered by tests
podfileLockHash = sha256
.convert(shorebirdEnv.macosPodfileLockFile.readAsBytesSync())
.toString();

Check warning on line 141 in packages/shorebird_cli/lib/src/commands/patch/macos_patcher.dart

View check run for this annotation

Codecov / codecov/patch

packages/shorebird_cli/lib/src/commands/patch/macos_patcher.dart#L140-L141

Added lines #L140 - L141 were not covered by tests
} else {
podfileLockHash = null;
}

if (releaseArtifact.podfileLockHash != null &&
podfileLockHash != releaseArtifact.podfileLockHash) {
logger.warn(

Check warning on line 148 in packages/shorebird_cli/lib/src/commands/patch/macos_patcher.dart

View check run for this annotation

Codecov / codecov/patch

packages/shorebird_cli/lib/src/commands/patch/macos_patcher.dart#L146-L148

Added lines #L146 - L148 were not covered by tests
'''
Your macos/Podfile.lock is different from the one used to build the release.
This may indicate that the patch contains native changes, which cannot be applied with a patch. Proceeding may result in unexpected behavior or crashes.''',
);

if (!allowNativeDiffs) {
if (!shorebirdEnv.canAcceptUserInput) {
throw UnpatchableChangeException();

Check warning on line 156 in packages/shorebird_cli/lib/src/commands/patch/macos_patcher.dart

View check run for this annotation

Codecov / codecov/patch

packages/shorebird_cli/lib/src/commands/patch/macos_patcher.dart#L154-L156

Added lines #L154 - L156 were not covered by tests
}

if (!logger.confirm('Continue anyways?')) {
throw UserCancelledException();

Check warning on line 160 in packages/shorebird_cli/lib/src/commands/patch/macos_patcher.dart

View check run for this annotation

Codecov / codecov/patch

packages/shorebird_cli/lib/src/commands/patch/macos_patcher.dart#L159-L160

Added lines #L159 - L160 were not covered by tests
}
}
}

return diffStatus;
}

@override
Expand Down Expand Up @@ -189,7 +238,9 @@
await ditto.archive(
source: appPath,
destination: zippedApp.path,
keepParent: true,
// keepParent is false here in order to ensure the directory structure of
// this zip file matches what will be provided to the [AppleArchiveDiffer]
// (which uses package:archive to stream zip file contents).
);
return zippedApp;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,18 @@ void main() {
p.join(xcframeworkFixturesBasePath, 'changed_dart.xcframework.zip');

group(
IosArchiveDiffer,
AppleArchiveDiffer,
() {
late IosArchiveDiffer differ;
late AppleArchiveDiffer differ;

setUp(() {
differ = const IosArchiveDiffer();
differ = const AppleArchiveDiffer();
});

group('appRegex', () {
test('identifies Runner.app/Runner as an app file', () {
expect(
IosArchiveDiffer.appRegex.hasMatch(
AppleArchiveDiffer.xcFrameworkAppRegex.hasMatch(
'Products/Applications/Runner.app/Runner',
),
isTrue,
Expand All @@ -60,7 +60,7 @@ void main() {

test('does not identify Runner.app/Assets.car as an app file', () {
expect(
IosArchiveDiffer.appRegex.hasMatch(
AppleArchiveDiffer.xcFrameworkAppRegex.hasMatch(
'Products/Applications/Runner.app/Assets.car',
),
isFalse,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import 'package:mocktail/mocktail.dart';
import 'package:path/path.dart' as p;
import 'package:platform/platform.dart';
import 'package:scoped_deps/scoped_deps.dart';
import 'package:shorebird_cli/src/archive_analysis/ios_archive_differ.dart';
import 'package:shorebird_cli/src/archive_analysis/apple_archive_differ.dart';
import 'package:shorebird_cli/src/artifact_builder.dart';
import 'package:shorebird_cli/src/artifact_manager.dart';
import 'package:shorebird_cli/src/code_push_client_wrapper.dart';
Expand Down Expand Up @@ -90,7 +90,7 @@ void main() {
setUpAll(() {
registerFallbackValue(Directory(''));
registerFallbackValue(File(''));
registerFallbackValue(const IosArchiveDiffer());
registerFallbackValue(const AppleArchiveDiffer());
registerFallbackValue(ReleasePlatform.ios);
registerFallbackValue(ShorebirdArtifact.genSnapshotIos);
registerFallbackValue(Uri.parse('https://example.com'));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import 'package:path/path.dart' as p;
import 'package:platform/platform.dart';
import 'package:pub_semver/pub_semver.dart';
import 'package:scoped_deps/scoped_deps.dart';
import 'package:shorebird_cli/src/archive_analysis/ios_archive_differ.dart';
import 'package:shorebird_cli/src/archive_analysis/apple_archive_differ.dart';
import 'package:shorebird_cli/src/artifact_builder.dart';
import 'package:shorebird_cli/src/artifact_manager.dart';
import 'package:shorebird_cli/src/code_push_client_wrapper.dart';
Expand Down Expand Up @@ -101,7 +101,7 @@ void main() {
registerFallbackValue(FakeArgResults());
registerFallbackValue(Directory(''));
registerFallbackValue(File(''));
registerFallbackValue(const IosArchiveDiffer());
registerFallbackValue(const AppleArchiveDiffer());
registerFallbackValue(ReleasePlatform.ios);
registerFallbackValue(ShorebirdArtifact.genSnapshotIos);
registerFallbackValue(Uri.parse('https://example.com'));
Expand Down
Loading
Loading