feat(shorebird_cli): export patch-debug.zip in codemagic (#2853)

This commit is contained in:
Felix Angelov
2025-02-05 13:10:10 -06:00
committed by GitHub
parent 6b19423055
commit c928a1da49
3 changed files with 85 additions and 2 deletions
+1
View File
@@ -24,6 +24,7 @@ words:
- canvaskit - canvaskit
- carryforward - carryforward
- cipd - cipd
- codemagic
- codesign - codesign
- codesigned - codesigned
- codesigning - codesigning
@@ -9,6 +9,7 @@ import 'package:shorebird_cli/src/archive/directory_archive.dart';
import 'package:shorebird_cli/src/commands/patch/patcher.dart'; import 'package:shorebird_cli/src/commands/patch/patcher.dart';
import 'package:shorebird_cli/src/executables/aot_tools.dart'; import 'package:shorebird_cli/src/executables/aot_tools.dart';
import 'package:shorebird_cli/src/logging/shorebird_logger.dart'; import 'package:shorebird_cli/src/logging/shorebird_logger.dart';
import 'package:shorebird_cli/src/platform.dart';
import 'package:shorebird_cli/src/shorebird_artifacts.dart'; import 'package:shorebird_cli/src/shorebird_artifacts.dart';
import 'package:shorebird_cli/src/shorebird_env.dart'; import 'package:shorebird_cli/src/shorebird_env.dart';
import 'package:xml/xml.dart'; import 'package:xml/xml.dart';
@@ -226,6 +227,26 @@ class Apple {
final debugInfoZip = await dumpDebugInfoDir.zipToTempFile(); final debugInfoZip = await dumpDebugInfoDir.zipToTempFile();
debugInfoZip.copySync(p.join('build', Patcher.debugInfoFile.path)); debugInfoZip.copySync(p.join('build', Patcher.debugInfoFile.path));
logger.detail('Link debug info saved to ${Patcher.debugInfoFile.path}'); logger.detail('Link debug info saved to ${Patcher.debugInfoFile.path}');
// If we're running on codemagic, export the patch-debug.zip artifact.
// https://docs.codemagic.io/knowledge-others/upload-custom-artifacts
final codemagicExportDir = platform.environment['CM_EXPORT_DIR'];
if (codemagicExportDir != null) {
logger.detail(
'''Codemagic environment detected. Exporting ${Patcher.debugInfoFile.path} to $codemagicExportDir''',
);
try {
debugInfoZip.copySync(
p.join(codemagicExportDir, p.basename(Patcher.debugInfoFile.path)),
);
} on Exception catch (error) {
logger.detail(
'''
Failed to export ${Patcher.debugInfoFile.path} to $codemagicExportDir.
$error''',
);
}
}
} }
try { try {
@@ -1,12 +1,13 @@
import 'dart:io'; import 'dart:io' hide Platform;
import 'package:io/io.dart';
import 'package:mason_logger/mason_logger.dart'; import 'package:mason_logger/mason_logger.dart';
import 'package:mocktail/mocktail.dart'; import 'package:mocktail/mocktail.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:platform/platform.dart';
import 'package:scoped_deps/scoped_deps.dart'; import 'package:scoped_deps/scoped_deps.dart';
import 'package:shorebird_cli/src/executables/executables.dart'; import 'package:shorebird_cli/src/executables/executables.dart';
import 'package:shorebird_cli/src/logging/logging.dart'; import 'package:shorebird_cli/src/logging/logging.dart';
import 'package:shorebird_cli/src/platform.dart';
import 'package:shorebird_cli/src/platform/platform.dart'; import 'package:shorebird_cli/src/platform/platform.dart';
import 'package:shorebird_cli/src/shorebird_artifacts.dart'; import 'package:shorebird_cli/src/shorebird_artifacts.dart';
import 'package:shorebird_cli/src/shorebird_env.dart'; import 'package:shorebird_cli/src/shorebird_env.dart';
@@ -26,6 +27,7 @@ void main() {
late AotTools aotTools; late AotTools aotTools;
late Apple apple; late Apple apple;
late Progress progress; late Progress progress;
late Platform platform;
late ShorebirdArtifacts shorebirdArtifacts; late ShorebirdArtifacts shorebirdArtifacts;
late ShorebirdLogger logger; late ShorebirdLogger logger;
late ShorebirdEnv shorebirdEnv; late ShorebirdEnv shorebirdEnv;
@@ -36,6 +38,7 @@ void main() {
values: { values: {
aotToolsRef.overrideWith(() => aotTools), aotToolsRef.overrideWith(() => aotTools),
loggerRef.overrideWith(() => logger), loggerRef.overrideWith(() => logger),
platformRef.overrideWith(() => platform),
shorebirdArtifactsRef.overrideWith(() => shorebirdArtifacts), shorebirdArtifactsRef.overrideWith(() => shorebirdArtifacts),
shorebirdEnvRef.overrideWith(() => shorebirdEnv), shorebirdEnvRef.overrideWith(() => shorebirdEnv),
}, },
@@ -45,12 +48,14 @@ void main() {
setUp(() { setUp(() {
aotTools = MockAotTools(); aotTools = MockAotTools();
apple = Apple(); apple = Apple();
platform = MockPlatform();
progress = MockProgress(); progress = MockProgress();
logger = MockShorebirdLogger(); logger = MockShorebirdLogger();
shorebirdArtifacts = MockShorebirdArtifacts(); shorebirdArtifacts = MockShorebirdArtifacts();
shorebirdEnv = MockShorebirdEnv(); shorebirdEnv = MockShorebirdEnv();
when(() => logger.progress(any())).thenReturn(progress); when(() => logger.progress(any())).thenReturn(progress);
when(() => platform.environment).thenReturn({});
}); });
group(MissingXcodeProjectException, () { group(MissingXcodeProjectException, () {
@@ -479,6 +484,62 @@ To add macOS, run "flutter create . --platforms macos"''',
), ),
).called(1); ).called(1);
}); });
group('when running in codemagic', () {
late Directory codemagicExportDir;
setUp(() {
codemagicExportDir = Directory.systemTemp.createTempSync();
when(() => platform.environment).thenReturn(
{'CM_EXPORT_DIR': codemagicExportDir.path},
);
});
test('copies debug info to codemagic exports', () async {
final copiedPatchDebugInfo = File(
p.join(codemagicExportDir.path, 'patch-debug.zip'),
);
expect(copiedPatchDebugInfo.existsSync(), isFalse);
await runWithOverrides(
() => apple.runLinker(
aotOutputFile: aotOutputFile,
kernelFile: File('missing'),
releaseArtifact: File('missing'),
vmCodeFile: File('missing'),
splitDebugInfoArgs: [],
),
);
expect(copiedPatchDebugInfo.existsSync(), isTrue);
verify(
() => logger.detail(
any(that: startsWith('Codemagic environment detected.')),
),
).called(1);
});
test('gracefully handles errors', () async {
when(() => platform.environment).thenReturn(
{'CM_EXPORT_DIR': 'invalid path'},
);
await runWithOverrides(
() => apple.runLinker(
aotOutputFile: aotOutputFile,
kernelFile: File('missing'),
releaseArtifact: File('missing'),
vmCodeFile: File('missing'),
splitDebugInfoArgs: [],
),
);
verify(
() => logger.detail(
any(
that: contains('PathNotFoundException: Cannot copy file to'),
),
),
).called(1);
});
});
}); });
group('when call to aotTools.link fails', () { group('when call to aotTools.link fails', () {