diff --git a/.github/workflows/android_builds.yml b/.github/workflows/android_builds.yml index 2d74ccde9..f92becf49 100644 --- a/.github/workflows/android_builds.yml +++ b/.github/workflows/android_builds.yml @@ -26,11 +26,11 @@ jobs: sudo cp -f misc/ci/sources.list /etc/apt/sources.list sudo apt-get update - - name: Set up Java 11 + - name: Set up Java 17 uses: actions/setup-java@v3 with: distribution: temurin - java-version: 11 + java-version: 17 - name: Setup Pandemonium build cache uses: ./.github/actions/pandemonium-cache diff --git a/.github/workflows/android_editor_builds.yml b/.github/workflows/android_editor_builds.yml index 2fd79d093..6685fff66 100644 --- a/.github/workflows/android_editor_builds.yml +++ b/.github/workflows/android_editor_builds.yml @@ -26,11 +26,11 @@ jobs: sudo cp -f misc/ci/sources.list /etc/apt/sources.list sudo apt-get update - - name: Set up Java 11 + - name: Set up Java 17 uses: actions/setup-java@v3 with: distribution: temurin - java-version: 11 + java-version: 17 - name: Setup Pandemonium build cache uses: ./.github/actions/pandemonium-cache diff --git a/TODO.md b/TODO.md index 108c9c852..29ba633a4 100644 --- a/TODO.md +++ b/TODO.md @@ -261,14 +261,6 @@ This PR mainly is to aid in faster development as outlined in godotengine/godot- https://github.com/godotengine/godot/pull/52566 -## [3.x] Update Android dependencies for the project - -Updates Java version from 11 to 17. Will need more testing, also likely an udpate to my build containers.\ -Do after the next release. - -https://github.com/godotengine/godot/commit/d1b6b6f725af4fadb8108c3769d3e7a36f6f8e5a -https://github.com/godotengine/godot/pull/87588 - ## Cleanup TODOs Cleanup this file, lots of things are already done. diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 70018ca12..312b88572 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -38,11 +38,8 @@ void register_android_exporter() { #ifndef ANDROID_ENABLED - String exe_ext; - if (OS::get_singleton()->get_name() == "Windows") { - exe_ext = "*.exe"; - } - + EDITOR_DEF("export/android/java_sdk_path", OS::get_singleton()->get_environment("JAVA_HOME")); + EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/java_sdk_path", PROPERTY_HINT_GLOBAL_DIR)); EDITOR_DEF("export/android/android_sdk_path", OS::get_singleton()->get_environment("ANDROID_SDK_ROOT")); EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/android_sdk_path", PROPERTY_HINT_GLOBAL_DIR)); EDITOR_DEF("export/android/debug_keystore", ""); diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index 281bb5e3a..75f034b51 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -227,7 +227,7 @@ static const char *APK_ASSETS_DIRECTORY = "res://android/build/assets"; static const char *AAB_ASSETS_DIRECTORY = "res://android/build/assetPacks/installTime/src/main/assets"; static const int DEFAULT_MIN_SDK_VERSION = 19; // Should match the value in 'platform/android/java/app/config.gradle#minSdk' -static const int DEFAULT_TARGET_SDK_VERSION = 33; // Should match the value in 'platform/android/java/app/config.gradle#targetSdk' +static const int DEFAULT_TARGET_SDK_VERSION = 34; // Should match the value in 'platform/android/java/app/config.gradle#targetSdk' const String SDK_VERSION_RANGE = vformat("%s,%s,1", DEFAULT_MIN_SDK_VERSION, DEFAULT_TARGET_SDK_VERSION); #ifndef ANDROID_ENABLED @@ -1939,6 +1939,15 @@ Ref EditorExportPlatformAndroid::get_run_icon() const { return run_icon; } +String EditorExportPlatformAndroid::get_java_path() { + String exe_ext = ""; + if (OS::get_singleton()->get_name() == "Windows") { + exe_ext = ".exe"; + } + String java_sdk_path = EditorSettings::get_singleton()->get("export/android/java_sdk_path"); + return java_sdk_path.plus_file("bin/java" + exe_ext); +} + String EditorExportPlatformAndroid::get_adb_path() { String exe_ext = ""; if (OS::get_singleton()->get_name() == "Windows") { @@ -2069,6 +2078,32 @@ bool EditorExportPlatformAndroid::has_valid_export_configuration(const Refget("export/android/java_sdk_path"); + if (java_sdk_path == "") { + err += TTR("A valid Java SDK path is required in Editor Settings.") + "\n"; + valid = false; + } else { + // Validate the given path by checking that `java` is present under the `bin` directory. + Error errn; + // Check for the bin directory. + DirAccessRef da = DirAccess::open(java_sdk_path.plus_file("bin"), &errn); + if (errn != OK) { + err += TTR("Invalid Java SDK path in Editor Settings."); + err += TTR("Missing 'bin' directory!"); + err += "\n"; + valid = false; + } else { + // Check for the `java` command. + String java_path = get_java_path(); + if (!FileAccess::exists(java_path)) { + err += TTR("Unable to find 'java' command using the Java SDK path."); + err += TTR("Please check the Java SDK directory specified in Editor Settings."); + err += "\n"; + valid = false; + } + } + } + String sdk_path = EditorSettings::get_singleton()->get("export/android/android_sdk_path"); if (sdk_path == "") { err += TTR("A valid Android SDK path is required in Editor Settings.") + "\n"; @@ -2804,6 +2839,11 @@ Error EditorExportPlatformAndroid::export_project_helper(const Refset_environment("JAVA_HOME", java_sdk_path); + print_verbose("Updating ANDROID_HOME environment to " + sdk_path); - OS::get_singleton()->set_environment("ANDROID_HOME", sdk_path); //set and overwrite if required + OS::get_singleton()->set_environment("ANDROID_HOME", sdk_path); String build_command; #ifdef WINDOWS_ENABLED @@ -2877,6 +2920,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref cmdline; + cmdline.push_back("validateJavaVersion"); if (clean_build_required) { cmdline.push_back("clean"); } diff --git a/platform/android/export/export_plugin.h b/platform/android/export/export_plugin.h index eef300b4a..90b68e2ac 100644 --- a/platform/android/export/export_plugin.h +++ b/platform/android/export/export_plugin.h @@ -205,6 +205,8 @@ public: static String get_apksigner_path(); + static String get_java_path(); + virtual bool has_valid_export_configuration(const Ref &p_preset, String &r_error, bool &r_missing_templates) const; virtual bool has_valid_project_configuration(const Ref &p_preset, String &r_error) const; diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml index 8ce6e11f0..6fd94d562 100644 --- a/platform/android/java/app/AndroidManifest.xml +++ b/platform/android/java/app/AndroidManifest.xml @@ -1,7 +1,6 @@ diff --git a/platform/android/java/app/assetPacks/installTime/build.gradle b/platform/android/java/app/assetPacks/installTime/build.gradle index b06faac37..46fa046ed 100644 --- a/platform/android/java/app/assetPacks/installTime/build.gradle +++ b/platform/android/java/app/assetPacks/installTime/build.gradle @@ -1,4 +1,6 @@ -apply plugin: 'com.android.asset-pack' +plugins { + id 'com.android.asset-pack' +} assetPack { packName = "installTime" // Directory name for the asset pack diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle index b95d7c9c2..82ff9b835 100644 --- a/platform/android/java/app/build.gradle +++ b/platform/android/java/app/build.gradle @@ -8,12 +8,14 @@ buildscript { repositories { google() mavenCentral() + gradlePluginPortal() + maven { url "https://plugins.gradle.org/m2/" } //CHUNK_BUILDSCRIPT_REPOSITORIES_BEGIN //CHUNK_BUILDSCRIPT_REPOSITORIES_END } dependencies { - classpath libraries.androidGradlePlugin - classpath libraries.kotlinGradlePlugin + classpath "com.android.tools.build:gradle:$versions.androidGradlePlugin" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlinVersion" //CHUNK_BUILDSCRIPT_DEPENDENCIES_BEGIN //CHUNK_BUILDSCRIPT_DEPENDENCIES_END } @@ -30,6 +32,8 @@ allprojects { repositories { google() mavenCentral() + gradlePluginPortal() + maven { url "https://plugins.gradle.org/m2/" } //CHUNK_ALLPROJECTS_REPOSITORIES_BEGIN //CHUNK_ALLPROJECTS_REPOSITORIES_END @@ -51,8 +55,7 @@ configurations { } dependencies { - implementation libraries.kotlinStdLib - implementation libraries.androidxFragment + implementation "androidx.fragment:fragment:$versions.fragmentVersion" if (rootProject.findProject(":lib")) { implementation project(":lib") @@ -100,6 +103,8 @@ android { assetPacks = [":assetPacks:installTime"] + namespace = 'com.pandemonium.game' + defaultConfig { // The default ignore pattern for the 'assets' directory includes hidden files and directories which are used by Pandemonium projects. aaptOptions { @@ -284,5 +289,28 @@ task copyAndRenameReleaseAab(type: Copy) { rename "build-release.aab", getExportFilename() } +/** + * Used to validate the version of the Java SDK used for the Godot gradle builds. + */ +task validateJavaVersion { + if (JavaVersion.current() != versions.javaVersion) { + throw new GradleException("Invalid Java version ${JavaVersion.current()}. Version ${versions.javaVersion} is the required Java version for Godot gradle builds.") + } +} + +/* +When they're scheduled to run, the copy*AARToAppModule tasks generate dependencies for the 'app' +module, so we're ensuring the ':app:preBuild' task is set to run after those tasks. + */ +if (rootProject.tasks.findByPath("copyDebugAARToAppModule") != null) { + preBuild.mustRunAfter(rootProject.tasks.named("copyDebugAARToAppModule")) +} +if (rootProject.tasks.findByPath("copyDevAARToAppModule") != null) { + preBuild.mustRunAfter(rootProject.tasks.named("copyDevAARToAppModule")) +} +if (rootProject.tasks.findByPath("copyReleaseAARToAppModule") != null) { + preBuild.mustRunAfter(rootProject.tasks.named("copyReleaseAARToAppModule")) +} + //CHUNK_GLOBAL_BEGIN //CHUNK_GLOBAL_END diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle index 0fc1fa283..0ad12e6a7 100644 --- a/platform/android/java/app/config.gradle +++ b/platform/android/java/app/config.gradle @@ -1,22 +1,14 @@ ext.versions = [ - androidGradlePlugin: '7.2.1', - compileSdk : 33, + androidGradlePlugin: '8.2.0', + compileSdk : 34, minSdk : 19, // Also update 'platform/android/export/export_plugin.cpp#DEFAULT_MIN_SDK_VERSION' - targetSdk : 33, // Also update 'platform/android/export/export_plugin.cpp#DEFAULT_TARGET_SDK_VERSION' - buildTools : '33.0.2', - kotlinVersion : '1.7.0', - fragmentVersion : '1.3.6', - nexusPublishVersion: '1.1.0', - javaVersion : 11, + targetSdk : 34, // Also update 'platform/android/export/export_plugin.cpp#DEFAULT_TARGET_SDK_VERSION' + buildTools : '34.0.0', + kotlinVersion : '1.9.20', + fragmentVersion : '1.6.2', + nexusPublishVersion: '1.3.0', + javaVersion : JavaVersion.VERSION_17, ndkVersion : '23.2.8568313' // Also update 'platform/android/detect.py#get_ndk_version' when this is updated. - -] - -ext.libraries = [ - androidGradlePlugin: "com.android.tools.build:gradle:$versions.androidGradlePlugin", - kotlinGradlePlugin : "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlinVersion", - kotlinStdLib : "org.jetbrains.kotlin:kotlin-stdlib:$versions.kotlinVersion", - androidxFragment : "androidx.fragment:fragment:$versions.fragmentVersion", ] ext.getExportPackageName = { -> diff --git a/platform/android/java/app/settings.gradle b/platform/android/java/app/settings.gradle index 237d44a2d..0e09e24b4 100644 --- a/platform/android/java/app/settings.gradle +++ b/platform/android/java/app/settings.gradle @@ -7,8 +7,10 @@ pluginManagement { id 'org.jetbrains.kotlin.android' version versions.kotlinVersion } repositories { - gradlePluginPortal() google() + mavenCentral() + gradlePluginPortal() + maven { url "https://plugins.gradle.org/m2/" } } } diff --git a/platform/android/java/build.gradle b/platform/android/java/build.gradle index 8b5e2b86c..842c589ac 100644 --- a/platform/android/java/build.gradle +++ b/platform/android/java/build.gradle @@ -1,17 +1,4 @@ -buildscript { - apply from: 'app/config.gradle' - - repositories { - google() - mavenCentral() - } - dependencies { - classpath libraries.androidGradlePlugin - classpath libraries.kotlinGradlePlugin - } -} - plugins { id 'io.github.gradle-nexus.publish-plugin' } @@ -23,6 +10,8 @@ allprojects { repositories { google() mavenCentral() + gradlePluginPortal() + maven { url "https://plugins.gradle.org/m2/" } } } @@ -30,6 +19,10 @@ ext { supportedAbis = ["armv7", "arm64v8", "x86", "x86_64"] supportedTargetsMap = [release: "release", dev: "debug", debug: "release_debug"] supportedFlavors = ["editor", "template"] + supportedTargetsMapByFlavors = [ + "editor": [release: "release_debug", dev: "debug", debug: "release_debug"], + "template": [release: "release", dev: "debug", debug: "release_debug"] + ] // Used by gradle to specify which architecture to build for by default when running // `./gradlew build` (this command is usually used by Android Studio). @@ -161,10 +154,21 @@ task zipCustomBuild(type: Zip) { destinationDirectory = file(binDir) } +/** + * Returns true if the scons build tasks responsible for generating the Godot native shared + * libraries should be excluded. + */ +def excludeSconsBuildTasks() { + return !isAndroidStudio() && !project.hasProperty("generateNativeLibs") +} + +/** + * Generates the list of build tasks that should be excluded from the build process.\ + */ def templateExcludedBuildTask() { // We exclude these gradle tasks so we can run the scons command manually. def excludedTasks = [] - if (!isAndroidStudio()) { + if (!excludeSconsBuildTasks()) { logger.lifecycle("Excluding Android studio build tasks") for (String flavor : supportedFlavors) { for (String buildType : supportedTargetsMap.keySet()) { @@ -183,23 +187,45 @@ def templateExcludedBuildTask() { return excludedTasks } -def templateBuildTasks() { +/** + * Generates the build tasks for the given flavor + * @param flavor Must be one of the supported flavors ('template' / 'editor') + */ +def generateBuildTasks(String flavor = "template") { + if (!supportedFlavors.contains(flavor)) { + throw new GradleException("Invalid build flavor: $flavor") + } + def tasks = [] - // Only build the apks and aar files for which we have native shared libraries. - for (String target : supportedTargetsMap.keySet()) { - File targetLibs = new File("lib/libs/" + target) - if (targetLibs != null + // Only build the apks and aar files for which we have native shared libraries unless we intend + // to run the scons build tasks. + boolean excludeSconsBuildTasks = excludeSconsBuildTasks() + boolean isTemplate = flavor == "template" + String libsDir = isTemplate ? "lib/libs/" : "lib/libs/tools/" + for (String target : supportedTargetsMapByFlavors[flavor].keySet()) { + File targetLibs = new File(libsDir + target) + if (!excludeSconsBuildTasks || (targetLibs != null && targetLibs.isDirectory() && targetLibs.listFiles() != null - && targetLibs.listFiles().length > 0) { + && targetLibs.listFiles().length > 0)) { + String capitalizedTarget = target.capitalize() - // Copy the generated aar library files to the custom build directory. - tasks += "copy" + capitalizedTarget + "AARToAppModule" - // Copy the generated aar library files to the bin directory. - tasks += "copy" + capitalizedTarget + "AARToBin" - // Copy the prebuilt binary templates to the bin directory. - tasks += "copy" + capitalizedTarget + "BinaryToBin" + + if (isTemplate) { + // Copy the generated aar library files to the build directory. + tasks += "copy${capitalizedTarget}AARToAppModule" + // Copy the generated aar library files to the bin directory. + tasks += "copy${capitalizedTarget}AARToBin" + // Copy the prebuilt binary templates to the bin directory. + tasks += "copy${capitalizedTarget}BinaryToBin" + } else { + // Copy the generated editor apk to the bin directory. + tasks += "copyEditor${capitalizedTarget}ApkToBin" + // Copy the generated editor aab to the bin directory. + tasks += "copyEditor${capitalizedTarget}AabToBin" + } + } else { logger.lifecycle("No native shared libs for target $target. Skipping build.") } @@ -230,31 +256,14 @@ task copyEditorDevBinaryToBin(type: Copy) { /** * Generate the Pandemonium Editor Android apk. * - * Note: The Pandemonium 'tools' shared libraries must have been generated (via scons) prior to running - * this gradle task. The task will only build the apk(s) for which the shared libraries is - * available. + * Note: Unless the 'generateNativeLibs` argument is specified, the Pandemonium 'tools' shared libraries + * must have been generated (via scons) prior to running this gradle task. + * The task will only build the apk(s) for which the shared libraries is available. */ task generatePandemoniumEditor { gradle.startParameter.excludedTaskNames += templateExcludedBuildTask() - def tasks = [] - - for (String target : supportedTargetsMap.keySet()) { - if (target == "release") { - // The editor can't be used with target=release as debugging tools are then not - // included, and it would crash on errors instead of reporting them. - continue - } - File targetLibs = new File("lib/libs/tools/" + target) - if (targetLibs != null - && targetLibs.isDirectory() - && targetLibs.listFiles() != null - && targetLibs.listFiles().length > 0) { - tasks += "copyEditor${target.capitalize()}BinaryToBin" - } - } - - dependsOn = tasks + dependsOn = generateBuildTasks("editor") } /** @@ -262,7 +271,7 @@ task generatePandemoniumEditor { */ task generatePandemoniumTemplates { gradle.startParameter.excludedTaskNames += templateExcludedBuildTask() - dependsOn = templateBuildTasks() + dependsOn = generateBuildTasks("template") finalizedBy 'zipCustomBuild' } @@ -277,10 +286,10 @@ task clean(type: Delete) { */ task generateDevTemplate { // add parameter to set symbols to true - gradle.startParameter.projectProperties += [doNotStrip: true] + gradle.startParameter.projectProperties += [doNotStrip: "true"] gradle.startParameter.excludedTaskNames += templateExcludedBuildTask() - dependsOn = templateBuildTasks() + dependsOn = generateBuildTasks("template") finalizedBy 'zipCustomBuild' } diff --git a/platform/android/java/editor/build.gradle b/platform/android/java/editor/build.gradle index adda4ead3..ccf072a8d 100644 --- a/platform/android/java/editor/build.gradle +++ b/platform/android/java/editor/build.gradle @@ -2,14 +2,14 @@ plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' + id 'base' } dependencies { - implementation libraries.kotlinStdLib - implementation libraries.androidxFragment + implementation "androidx.fragment:fragment:$versions.fragmentVersion" implementation project(":lib") - implementation "androidx.window:window:1.0.0" + implementation "androidx.window:window:1.2.0" } android { @@ -17,6 +17,8 @@ android { buildToolsVersion versions.buildTools ndkVersion versions.ndkVersion + namespace = "org.pandemoniumengine.editor" + defaultConfig { // The 'applicationId' suffix allows to install Pandemonium 3.x(v3) and 4.x(v4) on the same device applicationId "org.pandemoniumengine.editor.v3" @@ -27,6 +29,10 @@ android { missingDimensionStrategy 'products', 'editor' } + base { + archivesName = "android_editor" + } + compileOptions { sourceCompatibility versions.javaVersion targetCompatibility versions.javaVersion @@ -36,6 +42,10 @@ android { jvmTarget = versions.javaVersion } + buildFeatures { + buildConfig = true + } + buildTypes { dev { initWith debug diff --git a/platform/android/java/editor/src/main/AndroidManifest.xml b/platform/android/java/editor/src/main/AndroidManifest.xml index 4254ca5ec..4368690e3 100644 --- a/platform/android/java/editor/src/main/AndroidManifest.xml +++ b/platform/android/java/editor/src/main/AndroidManifest.xml @@ -1,7 +1,6 @@ diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle index 265eeb7e1..9f34e4fd0 100644 --- a/platform/android/java/lib/build.gradle +++ b/platform/android/java/lib/build.gradle @@ -4,8 +4,7 @@ plugins { } dependencies { - implementation libraries.kotlinStdLib - implementation libraries.androidxFragment + implementation "androidx.fragment:fragment:$versions.fragmentVersion" } def pathToRootDir = "../../../../" @@ -31,6 +30,11 @@ android { jvmTarget = versions.javaVersion } + buildFeatures { + aidl = true + buildConfig = true + } + buildTypes { dev { initWith debug diff --git a/platform/android/java/lib/src/org/pandemoniumengine/pandemonium/input/PandemoniumGestureHandler.kt b/platform/android/java/lib/src/org/pandemoniumengine/pandemonium/input/PandemoniumGestureHandler.kt index e5e182f2c..1cfe11cbc 100644 --- a/platform/android/java/lib/src/org/pandemoniumengine/pandemonium/input/PandemoniumGestureHandler.kt +++ b/platform/android/java/lib/src/org/pandemoniumengine/pandemonium/input/PandemoniumGestureHandler.kt @@ -212,7 +212,7 @@ internal class PandemoniumGestureHandler : SimpleOnGestureListener(), OnScaleGes } override fun onScroll( - originEvent: MotionEvent, + originEvent: MotionEvent?, terminusEvent: MotionEvent, distanceX: Float, distanceY: Float @@ -220,13 +220,15 @@ internal class PandemoniumGestureHandler : SimpleOnGestureListener(), OnScaleGes if (scaleInProgress) { if (dragInProgress) { // Cancel the drag - PandemoniumInputHandler.handleMotionEvent( - originEvent.source, - MotionEvent.ACTION_CANCEL, - originEvent.buttonState, - originEvent.x, - originEvent.y - ) + if (originEvent != null) { + PandemoniumInputHandler.handleMotionEvent( + originEvent.source, + MotionEvent.ACTION_CANCEL, + originEvent.buttonState, + originEvent.x, + originEvent.y + ) + } dragInProgress = false } } diff --git a/platform/android/java/nativeSrcsConfigs/AndroidManifest.xml b/platform/android/java/nativeSrcsConfigs/AndroidManifest.xml index ba35ea364..8072ee00d 100644 --- a/platform/android/java/nativeSrcsConfigs/AndroidManifest.xml +++ b/platform/android/java/nativeSrcsConfigs/AndroidManifest.xml @@ -1,2 +1,2 @@ - + diff --git a/platform/android/java/nativeSrcsConfigs/build.gradle b/platform/android/java/nativeSrcsConfigs/build.gradle index b920eaa07..b4add5766 100644 --- a/platform/android/java/nativeSrcsConfigs/build.gradle +++ b/platform/android/java/nativeSrcsConfigs/build.gradle @@ -9,6 +9,8 @@ android { buildToolsVersion versions.buildTools ndkVersion versions.ndkVersion + namespace = "org.pandemoniumengine.pandemonium" + defaultConfig { minSdkVersion versions.minSdk targetSdkVersion versions.targetSdk diff --git a/platform/android/java/settings.gradle b/platform/android/java/settings.gradle index b01783edc..fde8c07af 100644 --- a/platform/android/java/settings.gradle +++ b/platform/android/java/settings.gradle @@ -5,12 +5,15 @@ pluginManagement { plugins { id 'com.android.application' version versions.androidGradlePlugin id 'com.android.library' version versions.androidGradlePlugin + id 'com.android.asset-pack' version versions.androidGradlePlugin id 'org.jetbrains.kotlin.android' version versions.kotlinVersion id 'io.github.gradle-nexus.publish-plugin' version versions.nexusPublishVersion } repositories { - gradlePluginPortal() google() + mavenCentral() + gradlePluginPortal() + maven { url "https://plugins.gradle.org/m2/" } } }