22
33set -e
44
5+ # Log output to a file automatically.
6+ exec > >( tee -a " out/logs/publish-release" ) 2>&1
7+
58# Config
69
7- # For signing keys, and path to godot-builds repo .
10+ # For upload tools and signing/release keys .
811source ./config.sh
912
1013godot_version=" "
11- web_editor_latest=0
14+ latest_stable=0
15+ skip_stable=0
1216
13- while getopts " h?v:l " opt; do
17+ while getopts " h?v:ls " opt; do
1418 case " $opt " in
1519 h|\? )
1620 echo " Usage: $0 [OPTIONS...]"
1721 echo
1822 echo " -v godot version (e.g: 3.2-stable) [mandatory]"
19- echo " -l mark web editor as latest"
23+ echo " -l latest stable release (web editor, itch.io, EGS)"
24+ echo " -s don't run stable specific steps"
2025 echo
2126 exit 1
2227 ;;
2328 v)
2429 godot_version=$OPTARG
2530 ;;
2631 l)
27- web_editor_latest=1
32+ latest_stable=1
33+ ;;
34+ s)
35+ skip_stable=1
2836 ;;
2937 esac
3038done
@@ -34,6 +42,9 @@ if [ -z "${godot_version}" ]; then
3442 exit 1
3543fi
3644
45+ basedir=$( pwd)
46+ reldir=${basedir} /releases/${godot_version}
47+
3748# Confirm
3849
3950IFS=- read version status <<< " ${godot_version}"
@@ -46,26 +57,109 @@ case "$choice" in
4657esac
4758template_version=${version} .${status}
4859
60+ # Config checks for stable releases.
61+
62+ if [ " ${status} " == " stable" -a " ${skip_stable} " == " 0" ]; then
63+ echo " Publishing a stable release. Checking that configuration is valid to perform stable release specific steps."
64+
65+ read -p " Enter personal access token (GH_TOKEN) for godotengine/godot: " personal_gh_token
66+ if [[ " ${personal_gh_token} " != " github_pat_" * ]]; then
67+ echo " Provided personal access token should start with 'github_pat', aborting."
68+ exit 1
69+ fi
70+
71+ if ! gh api repos/godotengine/godot/git/refs/tags | grep -q ${godot_version} ; then
72+ echo " The tag '${godot_version} ' does not exist in godotengine/godot, aborting."
73+ echo " Push commits and create it manually before running this script."
74+ exit 1
75+ fi
76+
77+ if [ ! -d " ${UPLOAD_STEAM_PATH} " ]; then
78+ echo " Invalid config.sh: UPLOAD_STEAM_PATH is not a directory, aborting."
79+ exit 1
80+ fi
81+
82+ if [ " ${latest_stable} " == " 1" ]; then
83+ if [ ! -d " ${UPLOAD_EGS_PATH} " ]; then
84+ echo " Invalid config.sh: UPLOAD_EGS_PATH is not a directory, aborting."
85+ exit 1
86+ fi
87+ if [ ! -x " ${UPLOAD_ITCH_BUTLER} " ]; then
88+ echo " Invalid config.sh: UPLOAD_ITCH_BUTLER does not point to an executable, aborting."
89+ exit 1
90+ fi
91+ fi
92+ fi
93+
4994# Upload to GitHub godot-builds
5095
96+ echo " Uploading release to to godotengine/godot-builds repository."
97+
5198if [ -z " ${GODOT_BUILDS_PATH} " ]; then
5299 echo " Missing path to godotengine/godot-builds clone in config.sh, necessary to upload releases. Aborting."
53100 exit 1
54101fi
55102
56103${GODOT_BUILDS_PATH} /tools/upload-github.sh -v ${version} -f ${status}
57104
58- # Web editor
105+ # Stable release only
59106
60- scp -P 22 -r web/${template_version} ${WEB_EDITOR_HOSTNAME} :/home/akien/web_editor/
61- sleep 2
62- command=" sudo mv /home/akien/web_editor/${template_version} /var/www/editor.godotengine.org/public/releases/"
63- command=" ${command} ; cd /var/www/editor.godotengine.org; sudo chown -R www-data:www-data public/releases/${template_version} "
64- command=" ${command} ; sudo ./create-symlinks.sh -v ${template_version} "
65- if [ $web_editor_latest == 1 ]; then
66- command=" ${command} -l"
107+ if [ " ${status} " == " stable" -a " ${skip_stable} " == " 0" ]; then
108+ namever=Godot_v${godot_version}
109+
110+ echo " Uploading stable release to main GitHub repository."
111+
112+ export GH_TOKEN=${personal_gh_token}
113+ pushd git
114+ # Get release details from existing godot-builds release.
115+ release_info=$( gh release view ${godot_version} --repo godotengine/godot-builds --json name,body)
116+ release_title=$( echo " $release_info " | jq -r ' .name' )
117+ release_desc=$( echo " $release_info " | jq -r ' .body' )
118+
119+ gh release create ${godot_version} --repo godotengine/godot --title " $release_title " --notes " $release_desc "
120+ gh release upload ${godot_version} ${reldir} /[Gg]* ${reldir} /mono/[Gg]*
121+ # Concatenate SHA sums.
122+ cp ${reldir} /SHA512-SUMS.txt .
123+ cat ${reldir} /mono/SHA512-SUMS.txt >> SHA512-SUMS.txt
124+ gh release upload ${godot_version} SHA512-SUMS.txt
125+ rm SHA512-SUMS.txt
126+ popd
127+
128+ echo " Uploading stable release to Steam."
129+
130+ pushd ${UPLOAD_STEAM_PATH}
131+ rm -rf content/bin/[Gg]*
132+ rm -rf content/editor_data/export_templates/*
133+ cp -f ${basedir} /git/* .{md,txt,png,svg} content/
134+ # Steam specific binaries prepared by build-release.sh
135+ cp -r ${basedir} /steam/[Gg]* content/bin/
136+ unzip ${reldir} /${namever} _export_templates.tpz -d content/editor_data/export_templates/
137+ mv content/editor_data/export_templates/{templates,${template_version} }
138+ steam_build/build.sh
139+ popd
140+
141+ if [ " ${latest_stable} " == " 1" ]; then
142+ echo " Uploading stable release to EGS (latest only)."
143+
144+ pushd ${UPLOAD_EGS_PATH}
145+ rm -rf buildroot-* /*
146+ unzip ${reldir} /${namever} _win64.exe.zip -d buildroot-win64/
147+ unzip ${reldir} /${namever} _win32.exe.zip -d buildroot-win32/
148+ unzip ${reldir} /${namever} _macos.universal.zip -d buildroot-macos/
149+ ./upload.sh -v ${godot_version}
150+ popd
151+
152+ echo " Uploading stable release to itch.io (latest only)."
153+
154+ ${UPLOAD_ITCH_BUTLER} push ${reldir} /${namever} _linux.x86_64.zip godotengine/godot:linux-64-stable --userversion ${godot_version}
155+ ${UPLOAD_ITCH_BUTLER} push ${reldir} /${namever} _linux.x86_32.zip godotengine/godot:linux-32-stable --userversion ${godot_version}
156+ ${UPLOAD_ITCH_BUTLER} push ${reldir} /${namever} _win64.exe.zip godotengine/godot:windows-64-stable --userversion ${godot_version}
157+ ${UPLOAD_ITCH_BUTLER} push ${reldir} /${namever} _win32.exe.zip godotengine/godot:windows-32-stable --userversion ${godot_version}
158+ ${UPLOAD_ITCH_BUTLER} push ${reldir} /${namever} _macos.universal.zip godotengine/godot:osx-64-stable --userversion ${godot_version}
159+ fi
160+
161+ echo " All stable release upload steps done."
67162fi
68- ssh -P 22 ${WEB_EDITOR_HOSTNAME} " ${command} "
69163
70164# NuGet packages
71165
91185 echo " Disabling Android library publishing as deps/keystore doesn't exist."
92186fi
93187
94- # Stable release only
188+ # Web editor
189+
190+ echo " Uploading web editor... (with retry logic as it can be flaky)"
95191
96- if [ " ${status} " == " stable" ]; then
97- echo " NOTE: This script doesn't handle yet uploading stable releases to the main GitHub repository, Steam, EGS, and itch.io."
192+ MAX_RETRIES=5
193+ delay=5
194+
195+ retry_command () {
196+ local attempt=1
197+ local cmd=$1
198+ while [ ${attempt} -le ${MAX_RETRIES} ]; do
199+ echo " Attempt ${attempt} : Running command..."
200+ eval " ${cmd} " && return 0 # Success
201+
202+ echo " Command failed. Retrying in ${delay} seconds..."
203+ sleep ${delay}
204+ (( attempt++ ))
205+ delay=$(( delay * 2 )) # Exponential backoff
206+ done
207+
208+ echo " ❌ Command failed after ${MAX_RETRIES} attempts."
209+ return 1
210+ }
211+
212+ command=" sudo mv /home/akien/web_editor/${template_version} /var/www/editor.godotengine.org/public/releases/"
213+ command=" ${command} ; cd /var/www/editor.godotengine.org; sudo chown -R www-data:www-data public/releases/${template_version} "
214+ command=" ${command} ; sudo ./create-symlinks.sh -v ${template_version} "
215+ if [ " ${latest_stable} " == " 1" ]; then
216+ echo " Marking web editor build as 'latest'."
217+ command=" ${command} -l"
98218fi
219+
220+ retry_command " scp -P 22 -r web/${template_version} ${WEB_EDITOR_HOSTNAME} :/home/akien/web_editor/"
221+ sleep 2
222+ retry_command " ssh -p 22 ${WEB_EDITOR_HOSTNAME} '${command} '"
223+
224+ echo " All publishing steps done. Check out/logs/publish-release to double check that all steps succeeded."
0 commit comments