Unverified Commit 2b0255f0 authored by Elsabe Ros's avatar Elsabe Ros Committed by GitHub

Use the maven-publish plugin to publish AAR files. (#101276)

parent 58fe0983
This diff is collapsed.
...@@ -93,3 +93,4 @@ Alberto Miola <betoman96@gmail.com> ...@@ -93,3 +93,4 @@ Alberto Miola <betoman96@gmail.com>
Twin Sun, LLC <google-contrib@twinsunsolutions.com> Twin Sun, LLC <google-contrib@twinsunsolutions.com>
Taskulu LDA <contributions@taskulu.com> Taskulu LDA <contributions@taskulu.com>
Jonathan Joelson <jon@joelson.co> Jonathan Joelson <jon@joelson.co>
Elsabe Ros <hello@elsabe.dev>
...@@ -67,21 +67,45 @@ Future<void> main() async { ...@@ -67,21 +67,45 @@ Future<void> main() async {
]); ]);
}); });
final String outputAarDirectory = path.join( final String outputAarDirectoryOld = path.join(
flutterProject.rootPath, flutterProject.rootPath,
'build/host/outputs/repo/com/example/${flutterProject.name}/flutter_release/1.0/flutter_release-1.0.aar', 'build/host/outputs/repo/com/example/${flutterProject.name}/flutter_release/1.0/flutter_release-1.0.aar',
); );
final Iterable<String> aarFiles = await getFilesInAar(outputAarDirectory); final Iterable<String> oldAarFiles = await getFilesInAar(outputAarDirectoryOld);
checkCollectionContains<String>(<String>[ checkCollectionContains<String>(<String>[
...flutterAssets, ...flutterAssets,
'jni/armeabi-v7a/libapp.so', 'jni/armeabi-v7a/libapp.so',
], aarFiles); ], oldAarFiles);
final String outputAarDirectoryNew = path.join(
flutterProject.rootPath,
'build/host/outputs/repo/com/example/${flutterProject.name}/flutter/1.0/flutter-1.0-release.aar',
);
final Iterable<String> newAarFiles = await getFilesInAar(outputAarDirectoryNew);
checkCollectionContains<String>(<String>[
...flutterAssets,
'jni/armeabi-v7a/libapp.so',
], newAarFiles);
// Verify that an identifier from the Dart project code is not present // Verify that an identifier from the Dart project code is not present
// in the compiled binary. // in the compiled binary.
await inDirectory(flutterProject.rootPath, () async { await inDirectory(flutterProject.rootPath, () async {
await exec('unzip', <String>[outputAarDirectory]); await exec('unzip', <String>[outputAarDirectoryOld]);
checkFileExists(path.join(flutterProject.rootPath, 'jni/armeabi-v7a/libapp.so'));
final String response = await eval(
'grep',
<String>[flutterProject.name, 'jni/armeabi-v7a/libapp.so'],
canFail: true,
);
if (response.trim().contains('matches')) {
foundAarProjectName = true;
}
});
await inDirectory(flutterProject.rootPath, () async {
await exec('unzip', <String>[outputAarDirectoryNew]);
checkFileExists(path.join(flutterProject.rootPath, 'jni/armeabi-v7a/libapp.so')); checkFileExists(path.join(flutterProject.rootPath, 'jni/armeabi-v7a/libapp.so'));
final String response = await eval( final String response = await eval(
'grep', 'grep',
......
...@@ -98,7 +98,7 @@ Future<void> main() async { ...@@ -98,7 +98,7 @@ Future<void> main() async {
'repo', 'repo',
); );
section('Check release Maven artifacts'); section('Check release Maven artifacts (old format)');
checkFileExists(path.join( checkFileExists(path.join(
repoPath, repoPath,
...@@ -111,7 +111,7 @@ Future<void> main() async { ...@@ -111,7 +111,7 @@ Future<void> main() async {
'flutter_release-1.0.aar', 'flutter_release-1.0.aar',
)); ));
final String releasePom = path.join( final String releasePomOld = path.join(
repoPath, repoPath,
'io', 'io',
'flutter', 'flutter',
...@@ -122,7 +122,7 @@ Future<void> main() async { ...@@ -122,7 +122,7 @@ Future<void> main() async {
'flutter_release-1.0.pom', 'flutter_release-1.0.pom',
); );
checkFileExists(releasePom); checkFileExists(releasePomOld);
checkFileExists(path.join( checkFileExists(path.join(
repoPath, repoPath,
...@@ -146,6 +146,54 @@ Future<void> main() async { ...@@ -146,6 +146,54 @@ Future<void> main() async {
'plugin_with_android_release-1.0.pom', 'plugin_with_android_release-1.0.pom',
)); ));
section('Check release Maven artifacts (new format)');
checkFileExists(path.join(
repoPath,
'io',
'flutter',
'devicelab',
'hello',
'flutter',
'1.0',
'flutter-1.0-release.aar',
));
final String releasePomNew = path.join(
repoPath,
'io',
'flutter',
'devicelab',
'hello',
'flutter',
'1.0',
'flutter-1.0.pom',
);
checkFileExists(releasePomNew);
checkFileExists(path.join(
repoPath,
'io',
'flutter',
'devicelab',
'plugin_with_android',
'plugin_with_android',
'1.0',
'plugin_with_android-1.0-release.aar',
));
checkFileExists(path.join(
repoPath,
'io',
'flutter',
'devicelab',
'plugin_with_android',
'plugin_with_android',
'1.0',
'plugin_with_android-1.0.pom',
));
section('Check AOT blobs in release POM'); section('Check AOT blobs in release POM');
checkFileContains(<String>[ checkFileContains(<String>[
...@@ -153,8 +201,17 @@ Future<void> main() async { ...@@ -153,8 +201,17 @@ Future<void> main() async {
'armeabi_v7a_release', 'armeabi_v7a_release',
'arm64_v8a_release', 'arm64_v8a_release',
'x86_64_release', 'x86_64_release',
'plugin_with_android_release', 'plugin_with_android',
], releasePom); '<relocation>', //make sure the old pom contains the <relocation> tag
], releasePomOld);
checkFileContains(<String>[
'flutter_embedding_release',
'armeabi_v7a_release',
'arm64_v8a_release',
'x86_64_release',
'plugin_with_android',
], releasePomNew);
section('Check assets in release AAR'); section('Check assets in release AAR');
...@@ -180,7 +237,29 @@ Future<void> main() async { ...@@ -180,7 +237,29 @@ Future<void> main() async {
) )
); );
section('Check debug Maven artifacts'); checkCollectionContains<String>(
<String>[
...flutterAssets,
// AOT snapshots
'jni/arm64-v8a/libapp.so',
'jni/armeabi-v7a/libapp.so',
'jni/x86_64/libapp.so',
],
await getFilesInAar(
path.join(
repoPath,
'io',
'flutter',
'devicelab',
'hello',
'flutter',
'1.0',
'flutter-1.0-release.aar',
)
)
);
section('Check debug Maven artifacts (old format)');
checkFileExists(path.join( checkFileExists(path.join(
repoPath, repoPath,
...@@ -193,7 +272,7 @@ Future<void> main() async { ...@@ -193,7 +272,7 @@ Future<void> main() async {
'flutter_debug-1.0.aar', 'flutter_debug-1.0.aar',
)); ));
final String debugPom = path.join( final String debugPomOld = path.join(
repoPath, repoPath,
'io', 'io',
'flutter', 'flutter',
...@@ -204,7 +283,7 @@ Future<void> main() async { ...@@ -204,7 +283,7 @@ Future<void> main() async {
'flutter_debug-1.0.pom', 'flutter_debug-1.0.pom',
); );
checkFileExists(debugPom); checkFileExists(debugPomOld);
checkFileExists(path.join( checkFileExists(path.join(
repoPath, repoPath,
...@@ -228,6 +307,54 @@ Future<void> main() async { ...@@ -228,6 +307,54 @@ Future<void> main() async {
'plugin_with_android_debug-1.0.pom', 'plugin_with_android_debug-1.0.pom',
)); ));
section('Check debug Maven artifacts (new format)');
checkFileExists(path.join(
repoPath,
'io',
'flutter',
'devicelab',
'hello',
'flutter',
'1.0',
'flutter-1.0-debug.aar',
));
final String debugPomNew = path.join(
repoPath,
'io',
'flutter',
'devicelab',
'hello',
'flutter',
'1.0',
'flutter-1.0.pom',
);
checkFileExists(debugPomNew);
checkFileExists(path.join(
repoPath,
'io',
'flutter',
'devicelab',
'plugin_with_android',
'plugin_with_android',
'1.0',
'plugin_with_android-1.0-debug.aar',
));
checkFileExists(path.join(
repoPath,
'io',
'flutter',
'devicelab',
'plugin_with_android',
'plugin_with_android',
'1.0',
'plugin_with_android-1.0.pom',
));
section('Check AOT blobs in debug POM'); section('Check AOT blobs in debug POM');
checkFileContains(<String>[ checkFileContains(<String>[
...@@ -236,8 +363,18 @@ Future<void> main() async { ...@@ -236,8 +363,18 @@ Future<void> main() async {
'x86_64_debug', 'x86_64_debug',
'armeabi_v7a_debug', 'armeabi_v7a_debug',
'arm64_v8a_debug', 'arm64_v8a_debug',
'plugin_with_android_debug', 'plugin_with_android',
], debugPom); '<relocation>', //make sure the old pom contains the <relocation> tag
], debugPomOld);
checkFileContains(<String>[
'flutter_embedding_debug',
'x86_debug',
'x86_64_debug',
'armeabi_v7a_debug',
'arm64_v8a_debug',
'plugin_with_android',
], debugPomNew);
section('Check assets in debug AAR'); section('Check assets in debug AAR');
...@@ -252,11 +389,27 @@ Future<void> main() async { ...@@ -252,11 +389,27 @@ Future<void> main() async {
'flutter_debug-1.0.aar', 'flutter_debug-1.0.aar',
)); ));
final Iterable<String> debugAarNew = await getFilesInAar(path.join(
repoPath,
'io',
'flutter',
'devicelab',
'hello',
'flutter',
'1.0',
'flutter-1.0-debug.aar',
));
checkCollectionContains<String>(<String>[ checkCollectionContains<String>(<String>[
...flutterAssets, ...flutterAssets,
...debugAssets, ...debugAssets,
], debugAar); ], debugAar);
checkCollectionContains<String>(<String>[
...flutterAssets,
...debugAssets,
], debugAarNew);
return TaskResult.success(null); return TaskResult.success(null);
} on TaskResult catch (taskResult) { } on TaskResult catch (taskResult) {
return taskResult; return taskResult;
......
...@@ -6,9 +6,7 @@ ...@@ -6,9 +6,7 @@
import java.nio.file.Paths import java.nio.file.Paths
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.maven.MavenDeployer import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.plugins.MavenPlugin
import org.gradle.api.tasks.Upload
void configureProject(Project project, String outputDir) { void configureProject(Project project, String outputDir) {
if (!project.hasProperty("android")) { if (!project.hasProperty("android")) {
...@@ -18,8 +16,6 @@ void configureProject(Project project, String outputDir) { ...@@ -18,8 +16,6 @@ void configureProject(Project project, String outputDir) {
throw new GradleException("Can't generate AAR on a non Android library project."); throw new GradleException("Can't generate AAR on a non Android library project.");
} }
project.apply plugin: "maven"
// Snapshot versions include the timestamp in the artifact name. // Snapshot versions include the timestamp in the artifact name.
// Therefore, remove the snapshot part, so new runs of `flutter build aar` overrides existing artifacts. // Therefore, remove the snapshot part, so new runs of `flutter build aar` overrides existing artifacts.
// This version isn't relevant in Flutter since the pub version is used // This version isn't relevant in Flutter since the pub version is used
...@@ -34,13 +30,51 @@ void configureProject(Project project, String outputDir) { ...@@ -34,13 +30,51 @@ void configureProject(Project project, String outputDir) {
addAarTask(project, variant) addAarTask(project, variant)
} }
project.uploadArchives { project.publishing {
repositories { repositories {
mavenDeployer { maven {
repository(url: "file://${outputDir}/outputs/repo") url = uri("file://${outputDir}/outputs/repo")
}
}
}
// Some extra work to have alternative publications with the same format as the old maven plugin.
// Instead of using classifiers for the variants, the old maven plugin appended `_{variant}` to the artifactId
// First, create a default MavenPublication for each variant (except "all" since that is used to publish artifacts in the new way)
project.components.forEach { component ->
if (component.name != "all") {
project.publishing.publications.create(component.name, MavenPublication) {
from component
} }
} }
} }
// then, rename the artifactId to include the variant and make sure to remove any classifier
// data tha gradle has set, as well as adding a <relocation> tag pointing to the new coordinates
project.publishing.publications.forEach { pub ->
def relocationArtifactId = pub.artifactId
pub.artifactId = "${relocationArtifactId}_${pub.name}"
pub.alias = true
pub.pom.distributionManagement {
relocation {
// New artifact coordinates
groupId = "${pub.groupId}"
artifactId = "${relocationArtifactId}"
version = "${pub.version}"
message = "Use classifiers rather than _variant for new publish plugin"
}
}
}
// also publish the artifacts in the new way, using one set of coordinates with classifiers
project.publishing.publications.create("all", MavenPublication) {
from project.components.all
alias false
}
if (!project.property("is-plugin").toBoolean()) { if (!project.property("is-plugin").toBoolean()) {
return return
} }
...@@ -84,55 +118,21 @@ void addAarTask(Project project, variant) { ...@@ -84,55 +118,21 @@ void addAarTask(Project project, variant) {
String variantName = variant.name.capitalize() String variantName = variant.name.capitalize()
String taskName = "assembleAar$variantName" String taskName = "assembleAar$variantName"
project.tasks.create(name: taskName) { project.tasks.create(name: taskName) {
// This check is required to be able to configure the archives before `uploadArchives` runs. // This check is required to be able to configure the archives before `publish` runs.
if (!project.gradle.startParameter.taskNames.contains(taskName)) { if (!project.gradle.startParameter.taskNames.contains(taskName)) {
return return
} }
project.uploadArchives.repositories.mavenDeployer {
pom {
artifactId = "${project.name}_${variant.name.toLowerCase()}"
}
}
overrideDefaultPublishConfig(project, variant)
// Generate the Maven artifacts. // Generate the Maven artifacts.
finalizedBy "uploadArchives" finalizedBy "publish"
} }
} }
// This method mimics the logic in AGP when `android.defaultPublishConfig` is set in `build.gradle`: // maven-publish has to be applied _before_ the project gets evaluated, but some of the code in
// https://android.googlesource.com/platform/tools/base/+/studio-master-dev/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/variant/VariantHelper.java // `configureProject` requires the project to be evaluated. Apply the maven plugin to all projects, but
// // only configure it if it matches the conditions in `projectsEvaluated`
// Unfortunately, `android.defaultPublishConfig` cannot be overridden at this point since
// AGP already run this code.
void overrideDefaultPublishConfig(Project project, variant) {
String variantName = variant.name.capitalize()
Task bundle = project.tasks.findByName("bundle${variantName}Aar") // gradle:3.2.0
if (bundle == null) {
bundle = project.tasks.findByName("bundle${variantName}") // gradle:3.1.0
}
if (bundle == null) {
throw new GradleException("Can't generate AAR for variant ${variantName}.");
}
// Clear the current archive artifacts since the artifacts are based on `android.defaultPublishConfig`.
project.configurations["archives"].artifacts.clear()
// Add the artifact that will be published.
project.artifacts.add("archives", bundle)
def scopeMappings = project.uploadArchives.repositories.mavenDeployer.pom.scopeMappings allprojects {
// Clear the scope mappings added by AGP since they are based on the current `android.defaultPublishConfig`. apply plugin: "maven-publish"
scopeMappings.mappings.clear()
// Add the new mappings.
for (Configuration configuration : flattenConfiguration(variant.runtimeConfiguration)) {
scopeMappings.addMapping(/* priority = */ 300, configuration, "compile")
}
}
Set<Configuration> flattenConfiguration(Configuration configuration) {
Set<Configuration> configs = [configuration]
for (Configuration extend : configuration.extendsFrom) {
configs.addAll(flattenConfiguration(extend))
}
return configs
} }
projectsEvaluated { projectsEvaluated {
......
...@@ -726,7 +726,7 @@ void printHowToConsumeAar({ ...@@ -726,7 +726,7 @@ void printHowToConsumeAar({
for (final String buildMode in buildModes) { for (final String buildMode in buildModes) {
logger.printStatus(""" logger.printStatus("""
${buildMode}Implementation '$androidPackage:flutter_$buildMode:$buildNumber'"""); ${buildMode}Implementation '$androidPackage:flutter:$buildNumber:$buildMode'""");
} }
logger.printStatus(''' logger.printStatus('''
......
...@@ -29,8 +29,7 @@ import 'android_sdk.dart'; ...@@ -29,8 +29,7 @@ import 'android_sdk.dart';
// https://kotlinlang.org/docs/gradle.html#plugin-and-versions // https://kotlinlang.org/docs/gradle.html#plugin-and-versions
const String templateDefaultGradleVersion = '7.4'; const String templateDefaultGradleVersion = '7.4';
const String templateAndroidGradlePluginVersion = '7.1.2'; const String templateAndroidGradlePluginVersion = '7.1.2';
// TODO(egarciad): Gradle 7 breaks AARs builds: https://github.com/flutter/flutter/issues/101083 const String templateDefaultGradleVersionForModule = '7.1.2';
const String templateDefaultGradleVersionForModule = '4.1.0';
const String templateKotlinGradlePluginVersion = '1.6.10'; const String templateKotlinGradlePluginVersion = '1.6.10';
// These versions should match the values in flutter.gradle (FlutterExtension). // These versions should match the values in flutter.gradle (FlutterExtension).
......
...@@ -543,9 +543,9 @@ flutter: ...@@ -543,9 +543,9 @@ flutter:
' 3. Make the host app depend on the Flutter module:\n' ' 3. Make the host app depend on the Flutter module:\n'
'\n' '\n'
' dependencies {\n' ' dependencies {\n'
" releaseImplementation 'com.mycompany:flutter_release:2.2'\n" " releaseImplementation 'com.mycompany:flutter:2.2:release'\n"
" debugImplementation 'com.mycompany:flutter_debug:2.2'\n" " debugImplementation 'com.mycompany:flutter:2.2:debug'\n"
" profileImplementation 'com.mycompany:flutter_profile:2.2'\n" " profileImplementation 'com.mycompany:flutter:2.2:profile'\n"
' }\n' ' }\n'
'\n' '\n'
'\n' '\n'
...@@ -594,7 +594,7 @@ flutter: ...@@ -594,7 +594,7 @@ flutter:
' 3. Make the host app depend on the Flutter module:\n' ' 3. Make the host app depend on the Flutter module:\n'
'\n' '\n'
' dependencies {\n' ' dependencies {\n'
" releaseImplementation 'com.mycompany:flutter_release:1.0'\n" " releaseImplementation 'com.mycompany:flutter:1.0:release'\n"
' }\n' ' }\n'
'\n' '\n'
'To learn more, visit https://flutter.dev/go/build-aar\n' 'To learn more, visit https://flutter.dev/go/build-aar\n'
...@@ -632,7 +632,7 @@ flutter: ...@@ -632,7 +632,7 @@ flutter:
' 3. Make the host app depend on the Flutter module:\n' ' 3. Make the host app depend on the Flutter module:\n'
'\n' '\n'
' dependencies {\n' ' dependencies {\n'
" debugImplementation 'com.mycompany:flutter_debug:1.0'\n" " debugImplementation 'com.mycompany:flutter:1.0:debug'\n"
' }\n' ' }\n'
'\n' '\n'
'To learn more, visit https://flutter.dev/go/build-aar\n' 'To learn more, visit https://flutter.dev/go/build-aar\n'
...@@ -671,7 +671,7 @@ flutter: ...@@ -671,7 +671,7 @@ flutter:
' 3. Make the host app depend on the Flutter module:\n' ' 3. Make the host app depend on the Flutter module:\n'
'\n' '\n'
' dependencies {\n' ' dependencies {\n'
" profileImplementation 'com.mycompany:flutter_profile:1.0'\n" " profileImplementation 'com.mycompany:flutter:1.0:profile'\n"
' }\n' ' }\n'
'\n' '\n'
'\n' '\n'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment