diff --git a/build-release.sh b/build-release.sh index f8e05a8..c1786b0 100755 --- a/build-release.sh +++ b/build-release.sh @@ -2,6 +2,9 @@ set -e +# Log output to a file automatically. +exec > >(tee -a "out/logs/build-release") 2>&1 + # Config # For signing keystore and password. diff --git a/build.sh b/build.sh index fd3e42e..f9bdd11 100755 --- a/build.sh +++ b/build.sh @@ -4,6 +4,13 @@ set -e OPTIND=1 +export basedir="$(pwd)" +mkdir -p ${basedir}/out +mkdir -p ${basedir}/out/logs + +# Log output to a file automatically. +exec > >(tee -a "out/logs/build") 2>&1 + # Config # For default registry and number of cores. @@ -174,10 +181,6 @@ EOF popd fi -export basedir="$(pwd)" -mkdir -p ${basedir}/out -mkdir -p ${basedir}/out/logs - export podman_run="${podman} run -it --rm --env BUILD_NAME=${BUILD_NAME} --env GODOT_VERSION_STATUS=${GODOT_VERSION_STATUS} --env NUM_CORES=${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=$IMAGE_VERSION diff --git a/config.sh.in b/config.sh.in index 52fdbb1..66ca223 100644 --- a/config.sh.in +++ b/config.sh.in @@ -12,10 +12,19 @@ # relevant tool in your PATH or an absolute path to run it from. export PODMAN='sudo podman' +# GitHub token for @GodotBuilder for releases on godotengine/godot-builds, +# can use a long expiry date. +# For stable releases to godotengine/godot, generate a personal token with +# write access to godotengine/godot for use in publish-release.sh. +export GH_TOKEN='' + # Path to a Git clone of https://github.com/godotengine/godot-builds. # Only used for uploading official releases. export GODOT_BUILDS_PATH='' +# Path to the directory with the Steam upload setup. +export UPLOAD_STEAM_PATH='' + # SSH hostname to upload Web editor builds to. # Only used for uploading official releases. export WEB_EDITOR_HOSTNAME='' diff --git a/publish-release.sh b/publish-release.sh index db43e94..54b7792 100755 --- a/publish-release.sh +++ b/publish-release.sh @@ -2,25 +2,33 @@ set -e +# Log output to a file automatically. +exec > >(tee -a "out/logs/publish-release") 2>&1 + # Config -# For signing keys, and path to godot-builds repo. +# For upload tools and signing/release keys. source ./config.sh godot_version="" +skip_stable=0 -while getopts "h?v:" opt; do +while getopts "h?v:s" opt; do case "$opt" in h|\?) echo "Usage: $0 [OPTIONS...]" echo echo " -v godot version (e.g: 3.2-stable) [mandatory]" + echo " -s don't run stable specific steps" echo exit 1 ;; v) godot_version=$OPTARG ;; + s) + skip_stable=1 + ;; esac done @@ -29,6 +37,9 @@ if [ -z "${godot_version}" ]; then exit 1 fi +basedir=$(pwd) +reldir=${basedir}/releases/${godot_version} + # Confirm IFS=- read version status <<< "${godot_version}" @@ -41,8 +52,33 @@ case "$choice" in esac template_version=${version}.${status} +# Config checks for stable releases. + +if [ "${status}" == "stable" -a "${skip_stable}" == "0" ]; then + echo "Publishing a stable release. Checking that configuration is valid to perform stable release specific steps." + + read -p "Enter personal access token (GH_TOKEN) for godotengine/godot: " personal_gh_token + if [[ "${personal_gh_token}" != "github_pat_"* ]]; then + echo "Provided personal access token should start with 'github_pat', aborting." + exit 1 + fi + + if ! gh api repos/godotengine/godot/git/refs/tags | grep -q ${godot_version}; then + echo "The tag '${godot_version}' does not exist in godotengine/godot, aborting." + echo "Push commits and create it manually before running this script." + exit 1 + fi + + if [ ! -d "${UPLOAD_STEAM_PATH}" ]; then + echo "Invalid config.sh: UPLOAD_STEAM_PATH is not a directory, aborting." + exit 1 + fi +fi + # Upload to GitHub godot-builds +echo "Uploading release to to godotengine/godot-builds repository." + if [ -z "${GODOT_BUILDS_PATH}" ]; then echo "Missing path to godotengine/godot-builds clone in config.sh, necessary to upload releases. Aborting." exit 1 @@ -50,17 +86,85 @@ fi ${GODOT_BUILDS_PATH}/tools/upload-github.sh -v ${version} -f ${status} +# Stable release only + +if [ "${status}" == "stable" -a "${skip_stable}" == "0" ]; then + namever=Godot_v${godot_version} + + echo "Uploading stable release to main GitHub repository." + + export GH_TOKEN=${personal_gh_token} + pushd git + # Get release details from existing godot-builds release. + release_info=$(gh release view ${godot_version} --repo godotengine/godot-builds --json name,body) + release_title=$(echo "$release_info" | jq -r '.name') + release_desc=$(echo "$release_info" | jq -r '.body') + + gh release create ${godot_version} --repo godotengine/godot --title "$release_title" --notes "$release_desc" + gh release upload ${godot_version} ${reldir}/[Gg]* ${reldir}/mono/[Gg]* + # Concatenate SHA sums. + cp ${reldir}/SHA512-SUMS.txt . + cat ${reldir}/mono/SHA512-SUMS.txt >> SHA512-SUMS.txt + gh release upload ${godot_version} SHA512-SUMS.txt + rm SHA512-SUMS.txt + popd + + echo "Uploading stable release to Steam." + + pushd ${UPLOAD_STEAM_PATH} + rm -rf content/bin/[Gg]* + rm -rf content/editor_data/templates/* + cp -f ${basedir}/git/*.{md,txt,png,svg} content/ + pushd content/bin/ + unzip ${reldir}/${namever}_x11.64.zip + unzip ${reldir}/${namever}_x11.32.zip + unzip ${reldir}/${namever}_win64.exe.zip + unzip ${reldir}/${namever}_win32.exe.zip + unzip ${reldir}/${namever}_osx.universal.zip + mv ${namever}_x11.64 godot.x11.opt.tools.64 + mv ${namever}_x11.32 godot.x11.opt.tools.32 + mv ${namever}_win64.exe godot.windows.opt.tools.64.exe + mv ${namever}_win32.exe godot.windows.opt.tools.32.exe + popd + unzip ${reldir}/${namever}_export_templates.tpz -d content/editor_data/templates/ + mv content/editor_data/templates/{templates,${template_version}} + steam_build/build.sh + popd + + echo "All stable release upload steps done." +fi + # Web editor -scp -P 22 -r web/${template_version} ${WEB_EDITOR_HOSTNAME}:/home/akien/web_editor/ -sleep 2 +echo "Uploading web editor... (with retry logic as it can be flaky)" + +MAX_RETRIES=5 +delay=5 + +retry_command() { + local attempt=1 + local cmd=$1 + while [ ${attempt} -le ${MAX_RETRIES} ]; do + echo "Attempt ${attempt}: Running command..." + eval "${cmd}" && return 0 # Success + + echo "Command failed. Retrying in ${delay} seconds..." + sleep ${delay} + ((attempt++)) + delay=$((delay * 2)) # Exponential backoff + done + + echo "❌ Command failed after ${MAX_RETRIES} attempts." + return 1 +} + command="sudo mv /home/akien/web_editor/${template_version} /var/www/editor.godotengine.org/public/releases/" command="${command}; cd /var/www/editor.godotengine.org; sudo chown -R www-data:www-data public/releases/${template_version}" command="${command}; sudo ./create-symlinks.sh -v ${template_version}" ssh -P 22 ${WEB_EDITOR_HOSTNAME} "${command}" -# Stable release only +retry_command "scp -P 22 -r web/${template_version} ${WEB_EDITOR_HOSTNAME}:/home/akien/web_editor/" +sleep 2 +retry_command "ssh -p 22 ${WEB_EDITOR_HOSTNAME} '${command}'" -if [ "${status}" == "stable" ]; then - echo "NOTE: This script doesn't handle yet uploading stable releases to the main GitHub repository, Steam, EGS, and itch.io." -fi +echo "All publishing steps done. Check out/logs/publish-release to double check that all steps succeeded."