From 0780ea4a4f611b9370f40f36c5134a227017b55b Mon Sep 17 00:00:00 2001 From: Fredia Huya-Kouadio Date: Sun, 5 Mar 2023 21:33:51 -0800 Subject: [PATCH] Add logic to upload the Godot Android library to MavenCentral MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add environment variables to sign the release build for the Godot Android editor and to publish the library to MavenCentral. If the environment vars are not defined, we do a simple unsigned `release_debug` build for the Android editor. Change `config.sh.in` template to use single quotes by default, to prevent expanding special characters in environment variables. To publish to MavenCentral, a new `build-android/upload-mavencentral.sh` script is added. It needs to run after the build using gradle, but we still want it to be optional and used only when making an official release, so we copy the compiled sources in the first step. Co-authored-by: Rémi Verschelde --- .gitignore | 3 +- build-android/build.sh | 40 ++++++++++++++--- build-android/upload-mavencentral.sh | 18 ++++++++ build-release.sh | 2 + build.sh | 28 ++++++------ config.sh.in | 64 +++++++++++++++++++++------- 6 files changed, 121 insertions(+), 34 deletions(-) create mode 100644 build-android/upload-mavencentral.sh diff --git a/.gitignore b/.gitignore index 7968ad8..bf30644 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ -# User-specific configuration and signing key +# User-specific configuration and signing keys config.sh +*.jks *.pfx *.pkcs12 diff --git a/build-android/build.sh b/build-android/build.sh index 2db0110..5c8e181 100755 --- a/build-android/build.sh +++ b/build-android/build.sh @@ -14,6 +14,16 @@ mkdir godot cd godot tar xf /root/godot.tar.gz --strip-components=1 +# Environment variables and keystore needed for signing store editor build, +# as well as signing and publishing to MavenCentral. +source /root/keystore/config.sh + +store_release="yes" +if [ -z "${GODOT_ANDROID_SIGN_KEYSTORE}" ]; then + echo "No keystore provided to sign the Android release editor build, using debug build instead." + store_release="no" +fi + # Classical dnf -y install gettext @@ -21,17 +31,29 @@ dnf -y install gettext if [ "${CLASSICAL}" == "1" ]; then echo "Starting classical build for Android..." - $SCONS platform=android arch=arm32 $OPTIONS target=editor - $SCONS platform=android arch=arm64 $OPTIONS target=editor - $SCONS platform=android arch=x86_32 $OPTIONS target=editor - $SCONS platform=android arch=x86_64 $OPTIONS target=editor + $SCONS platform=android arch=arm32 $OPTIONS target=editor store_release=${store_release} + $SCONS platform=android arch=arm64 $OPTIONS target=editor store_release=${store_release} + $SCONS platform=android arch=x86_32 $OPTIONS target=editor store_release=${store_release} + $SCONS platform=android arch=x86_64 $OPTIONS target=editor store_release=${store_release} pushd platform/android/java ./gradlew generateGodotEditor popd mkdir -p /root/out/tools - cp bin/android_editor.apk /root/out/tools/ + # Copy the generated Android editor binaries (apk & aab). + if [ "$store_release" == "yes" ]; then + cp bin/android_editor_builds/android_editor-release.apk /root/out/tools/android_editor.apk + cp bin/android_editor_builds/android_editor-release.aab /root/out/tools/android_editor.aab + else + cp bin/android_editor_builds/android_editor-debug.apk /root/out/tools/android_editor.apk + cp bin/android_editor_builds/android_editor-debug.aab /root/out/tools/android_editor.aab + fi + + # Restart from a clean tarball, as we'll copy all the contents + # outside the container for the MavenCentral upload. + rm -rf /root/godot/* + tar xf /root/godot.tar.gz --strip-components=1 $SCONS platform=android arch=arm32 $OPTIONS target=template_debug $SCONS platform=android arch=arm32 $OPTIONS target=template_release @@ -47,6 +69,14 @@ if [ "${CLASSICAL}" == "1" ]; then pushd platform/android/java ./gradlew generateGodotTemplates + + if [ "$store_release" == "yes" ]; then + # Copy source folder with compiled libs so we can optionally use it + # in a separate script to upload the templates to MavenCentral. + cp -r /root/godot /root/out/source/ + # Backup ~/.gradle too so we can reuse all the downloaded stuff. + cp -r /root/.gradle /root/out/source/.gradle + fi popd mkdir -p /root/out/templates diff --git a/build-android/upload-mavencentral.sh b/build-android/upload-mavencentral.sh new file mode 100644 index 0000000..9b43e6a --- /dev/null +++ b/build-android/upload-mavencentral.sh @@ -0,0 +1,18 @@ +#/bin/bash + +basedir="$(pwd)" + +if [ ! -d "${basedir}/deps/keystore" ]; then + echo "Couldn't find ${basedir}/deps/keystore. Make sure to run this from the root folder of the Git repository." +fi + +source ${basedir}/deps/keystore/config.sh + +# Release the Godot Android library to MavenCentral +${PODMAN} run -it --rm \ + -v ${basedir}/out/android/source:/root/godot -v ${basedir}/deps/keystore:/root/keystore \ + localhost/godot-android:${IMAGE_VERSION} bash -c \ + "source /root/keystore/config.sh && \ + cp -r /root/godot/.gradle /root && \ + cd /root/godot/platform/android/java && \ + ./gradlew publishTemplateReleasePublicationToSonatypeRepository --max-workers 1 closeAndReleaseSonatypeStagingRepository" diff --git a/build-release.sh b/build-release.sh index 4f400e0..94d6054 100755 --- a/build-release.sh +++ b/build-release.sh @@ -319,6 +319,8 @@ if [ "${build_classical}" == "1" ]; then # Editor binname="${godot_basename}_android_editor.apk" cp out/android/tools/android_editor.apk ${reldir}/${binname} + binname="${godot_basename}_android_editor.aab" + cp out/android/tools/android_editor.aab ${reldir}/${binname} # Templates cp out/android/templates/*.apk ${templatesdir}/ diff --git a/build.sh b/build.sh index 068330c..9e726b2 100755 --- a/build.sh +++ b/build.sh @@ -83,17 +83,7 @@ while getopts "h?r:u:p:v:g:b:fsc" opt; do esac done -export podman=none -if which podman > /dev/null; then - export podman=podman -elif which docker > /dev/null; then - export podman=docker -fi - -if [ "${podman}" == "none" ]; then - echo "Either podman or docker needs to be installed" - exit 1 -fi +export podman=${PODMAN} if [ $UID != 0 ]; then echo "WARNING: Running as non-root may cause problems for the uwp build" @@ -150,6 +140,18 @@ if [ ! -d "deps/vulkansdk-macos" ]; then echo "Missing Vulkan SDK for macOS, we're going to run into issues!" fi +# Keystore for Android editor signing +# Optional - the config.sh will be copied but if it's not filled in, +# it will do an unsigned build. +if [ ! -d "deps/keystore" ]; then + mkdir -p deps/keystore + cp config.sh deps/keystore/ + if [ ! -z "$GODOT_ANDROID_SIGN_KEYSTORE" ]; then + cp "$GODOT_ANDROID_SIGN_KEYSTORE" deps/keystore/ + sed -i deps/keystore/config.sh -e "s@$GODOT_ANDROID_SIGN_KEYSTORE@/root/keystore/$GODOT_ANDROID_SIGN_KEYSTORE@" + fi +fi + if [ "${skip_git_checkout}" == 0 ]; then git clone https://github.com/godotengine/godot git || /bin/true pushd git @@ -183,7 +185,7 @@ mkdir -p ${basedir}/out/logs mkdir -p ${basedir}/mono-glue export podman_run="${podman} run -it --rm --env BUILD_NAME --env GODOT_VERSION_STATUS --env NUM_CORES --env CLASSICAL=${build_classical} --env MONO=${build_mono} -v ${basedir}/godot-${godot_version}.tar.gz:/root/godot.tar.gz -v ${basedir}/mono-glue:/root/mono-glue -w /root/" -export img_version=4.x-f36 +export img_version=$IMAGE_VERSION mkdir -p ${basedir}/mono-glue ${podman_run} -v ${basedir}/build-mono-glue:/root/build localhost/godot-linux:${img_version} bash build/build.sh 2>&1 | tee ${basedir}/out/logs/mono-glue @@ -201,7 +203,7 @@ mkdir -p ${basedir}/out/macos ${podman_run} -v ${basedir}/build-macos:/root/build -v ${basedir}/out/macos:/root/out -v ${basedir}/deps/vulkansdk-macos:/root/vulkansdk localhost/godot-osx:${img_version} bash build/build.sh 2>&1 | tee ${basedir}/out/logs/macos mkdir -p ${basedir}/out/android -${podman_run} -v ${basedir}/build-android:/root/build -v ${basedir}/out/android:/root/out localhost/godot-android:${img_version} bash build/build.sh 2>&1 | tee ${basedir}/out/logs/android +${podman_run} -v ${basedir}/build-android:/root/build -v ${basedir}/out/android:/root/out -v ${basedir}/deps/keystore:/root/keystore localhost/godot-android:${img_version} bash build/build.sh 2>&1 | tee ${basedir}/out/logs/android mkdir -p ${basedir}/out/ios ${podman_run} -v ${basedir}/build-ios:/root/build -v ${basedir}/out/ios:/root/out localhost/godot-ios:${img_version} bash build/build.sh 2>&1 | tee ${basedir}/out/logs/ios diff --git a/config.sh.in b/config.sh.in index 9fe9ccc..3694af5 100644 --- a/config.sh.in +++ b/config.sh.in @@ -3,16 +3,28 @@ # Configuration file for user-specific details. # This file is gitignore'd and will be sourced by build scripts. +# Note: For passwords or GPG keys, make sure that special characters such +# as $ won't be expanded, by using single quotes to enclose the string, +# or escaping with \$. + +# These scripts are designed and tested against podman. They may also work +# with docker, but it's not guaranteed. You can set this variable to the +# relevant tool in your PATH or an absolute path to run it from. +export PODMAN='podman' + # Registry for build containers. # The default registry is the one used for official Godot builds. # Note that some of its images are private and only accessible to selected # contributors. # You can build your own registry with scripts at # https://github.com/godotengine/build-containers -export REGISTRY="registry.prehensile-tales.com" +export REGISTRY='registry.prehensile-tales.com' + +# Version string of the images to use in build.sh. +export IMAGE_VERSION='4.x-f36' # Default build name used to distinguish between official and custom builds. -export BUILD_NAME="custom_build" +export BUILD_NAME='custom_build' # Default number of parallel cores for each build. export NUM_CORES=16 @@ -21,28 +33,50 @@ export NUM_CORES=16 # If you do not fill all SIGN_* fields, signing will be skipped. # Path to pkcs12 archive. -export SIGN_KEYSTORE="" +export SIGN_KEYSTORE='' # Password for the private key. -export SIGN_PASSWORD="" +export SIGN_PASSWORD='' # Name and URL of the signed application. # Use your own when making a thirdparty build. -export SIGN_NAME="" -export SIGN_URL="" +export SIGN_NAME='' +export SIGN_URL='' -# Hostname or IP address of an macOS host (Needed for signing) -# eg "user@10.1.0.10" -export OSX_HOST="" +# Hostname or IP address of an OSX host (Needed for signing) +# eg 'user@10.1.0.10' +export OSX_HOST='' # ID of the Apple certificate used to sign -export OSX_KEY_ID="" +export OSX_KEY_ID='' # Bundle id for the signed app -export OSX_BUNDLE_ID="" +export OSX_BUNDLE_ID='' # Username/password for Apple's signing APIs (used for atltool) -export APPLE_ID="" -export APPLE_ID_PASSWORD="" +export APPLE_ID='' +export APPLE_ID_PASSWORD='' # NuGet source for publishing .NET packages -export NUGET_SOURCE="nuget.org" +export NUGET_SOURCE='nuget.org' # API key for publishing NuGet packages to nuget.org -export NUGET_API_KEY="" +export NUGET_API_KEY='' + +# MavenCentral (sonatype) credentials +export OSSRH_GROUP_ID='' +export OSSRH_USERNAME='' +export OSSRH_PASSWORD='' +# Sonatype assigned ID used to upload the generated artifacts +export SONATYPE_STAGING_PROFILE_ID='' +# Used to sign the artifacts after they're built +# ID of the GPG key pair, the last eight characters of its fingerprint +export SIGNING_KEY_ID='' +# Passphrase of the key pair +export SIGNING_PASSWORD='' +# Base64 encoded private GPG key +export SIGNING_KEY='' + +# Android signing configs +# Path to the Android keystore file used to sign the release build +export GODOT_ANDROID_SIGN_KEYSTORE='' +# Key alias used for signing the release build +export GODOT_ANDROID_KEYSTORE_ALIAS='' +# Password for the key used for signing the release build +export GODOT_ANDROID_SIGN_PASSWORD=''