Compare commits

..

No commits in common. "trunk" and "v0.1.41" have entirely different histories.

3 changed files with 26 additions and 85 deletions

View file

@ -16,17 +16,15 @@ jobs:
- name: Install dependencies
run: |
apt-get update
apt-get install -y -qq make git wget
apt-get update -qq
apt-get install -y -qq make git wget unzip
- name: Install Godot
run: |
wget -q https://github.com/godotengine/godot/releases/download/4.4.1-stable/Godot_v4.4.1-stable_linux.x86_64.zip
# python3 instead of unzip: the runner's apt index goes stale and the
# pinned unzip deb 404s in the security pool.
python3 -m zipfile -e Godot_v4.4.1-stable_linux.x86_64.zip godot-dir
unzip -q Godot_v4.4.1-stable_linux.x86_64.zip
mkdir -p "$HOME/.local/bin"
mv godot-dir/Godot_v4.4.1-stable_linux.x86_64 "$HOME/.local/bin/godot"
mv Godot_v4.4.1-stable_linux.x86_64 "$HOME/.local/bin/godot"
chmod +x "$HOME/.local/bin/godot"
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
@ -43,32 +41,21 @@ jobs:
TAG="${GITHUB_REF_NAME}"
API="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}"
# Create the release. `curl -sf` hid the reason a tag build could not
# publish, which left devices on the previous release with no clue,
# so report the status code and the API answer.
HTTP=$(curl -sS -o /tmp/release.json -w "%{http_code}" -X POST "${API}/releases" \
# Create the release
curl -sf -X POST "${API}/releases" \
-H "Authorization: token ${GITHUB_TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"tag_name\":\"${TAG}\",\"name\":\"${TAG}\"}")
if [ "${HTTP}" != "201" ] && [ "${HTTP}" != "200" ]; then
echo "Release creation for ${TAG} failed with HTTP ${HTTP}:"
cat /tmp/release.json
exit 1
fi
-d "{\"tag_name\":\"${TAG}\",\"name\":\"${TAG}\"}" \
-o /tmp/release.json
RELEASE_ID=$(python3 -c "import json; print(json.load(open('/tmp/release.json'))['id'])")
# Upload assets
for FILE in dist/itch.zip dist/itch.zip.sha256.txt; do
NAME=$(basename "$FILE")
HTTP=$(curl -sS -o /tmp/asset.json -w "%{http_code}" -X POST \
curl -sf -X POST \
"${API}/releases/${RELEASE_ID}/assets?name=${NAME}" \
-H "Authorization: token ${GITHUB_TOKEN}" \
-H "Content-Type: application/octet-stream" \
--data-binary "@${FILE}")
if [ "${HTTP}" != "201" ] && [ "${HTTP}" != "200" ]; then
echo "Asset upload of ${NAME} failed with HTTP ${HTTP}:"
cat /tmp/asset.json
exit 1
fi
--data-binary "@${FILE}"
done

View file

@ -83,8 +83,7 @@ func _ready() -> void:
bootstrap()
## Bootstraps the butler binary (downloading it when missing or outdated), then
## spawns butlerd.
## Bootstraps the butler binary if it isn't present, then spawns butlerd.
func bootstrap() -> void:
var butler_dir_global := ProjectSettings.globalize_path(butler_dir)
_migrate_butler(butler_dir_global)
@ -97,12 +96,6 @@ func bootstrap() -> void:
bootstrap_finished.emit()
return
logger.info("Successfully installed butler")
elif await _butler_is_outdated(butler_bin):
logger.info("Updating the butler binary to " + str(await _fetch_latest_butler_version()) + ".")
var success := await _install_butler()
if not success:
# Not fatal: the installed butler still works, it is just behind.
logger.warn("Unable to update butler, keeping the installed one.")
var dbpath := "/".join([butler_dir_global, "butler.db"])
var args := [
@ -146,8 +139,9 @@ func _migrate_butler(dest_dir: String) -> void:
logger.info("Migrated butler from " + old_dir + " to " + dest_dir)
## broth's slug for the platform we are running on, e.g. "linux-amd64".
func _butler_platform_slug() -> String:
## Downloads a butler binary for this platform from itch's broth distribution
## channel (the same one the official itch.io app uses to self-update).
func _install_butler() -> bool:
var goos := "linux"
var goarch := "amd64"
if OS.get_name() == "Windows":
@ -161,13 +155,10 @@ func _butler_platform_slug() -> String:
var arch: String = Engine.get_architecture_name()
if "arm64" in arch or "aarch64" in arch:
goarch = "arm64"
return goos + "-" + goarch
var platform_slug := goos + "-" + goarch
var latest_url := "/".join([broth_base, platform_slug, "LATEST"])
## Asks itch's broth channel which butler version is current. Returns "" when
## the channel can't be reached, so callers can tell "unknown" from "current".
func _fetch_latest_butler_version() -> String:
var latest_url := "/".join([broth_base, _butler_platform_slug(), "LATEST"])
var http := HTTPRequest.new()
add_child.call_deferred(http)
await http.ready
@ -175,65 +166,28 @@ func _fetch_latest_butler_version() -> String:
logger.error("Error fetching latest butler version: " + latest_url)
remove_child(http)
http.queue_free()
return ""
return false
var args: Array = await http.request_completed
var result: int = args[0]
var response_code: int = args[1]
var body: PackedByteArray = args[3]
if result != HTTPRequest.RESULT_SUCCESS or response_code != 200:
logger.error("Unable to determine latest butler version for " + platform_slug)
remove_child(http)
http.queue_free()
if result != HTTPRequest.RESULT_SUCCESS or response_code != 200:
logger.error("Unable to determine the latest butler version")
return ""
return body.get_string_from_utf8().strip_edges()
## Reads the version of an installed butler binary, e.g. "15.30.0" out of
## "v15.30.0, built on Jul 27 2026". Returns "" when the binary can't be run.
func _butler_installed_version(butler_bin: String) -> String:
var out := []
if OS.execute(butler_bin, ["version"], out) != OK or out.is_empty():
return ""
var reported: String = (out[0] as String).strip_edges().get_slice(",", 0)
return reported.trim_prefix("v").strip_edges()
## True when the installed butler is behind broth's current version. The
## binary used to be downloaded only when missing, so it silently rotted for
## months and missed fixes. Unknown version (channel unreachable, binary not
## runnable) counts as up to date: never replace a working butler on a guess.
func _butler_is_outdated(butler_bin: String) -> bool:
var latest := await _fetch_latest_butler_version()
if latest == "":
return false
var installed := _butler_installed_version(butler_bin)
if installed == "" or installed == latest:
return false
logger.info("butler " + installed + " is behind " + latest + ". Updating it.")
return true
var version := body.get_string_from_utf8().strip_edges()
## Downloads a butler binary for this platform from itch's broth distribution
## channel (the same one the official itch.io app uses to self-update).
func _install_butler() -> bool:
var platform_slug := _butler_platform_slug()
var version := await _fetch_latest_butler_version()
if version == "":
return false
var http := HTTPRequest.new()
add_child.call_deferred(http)
await http.ready
var archive_url := "/".join([broth_base, platform_slug, version, "archive", "default"])
if http.request(archive_url) != OK:
logger.error("Error downloading butler: " + archive_url)
remove_child(http)
http.queue_free()
return false
var args: Array = await http.request_completed
var result: int = args[0]
var response_code: int = args[1]
var body: PackedByteArray = args[3]
args = await http.request_completed
result = args[0]
response_code = args[1]
body = args[3]
remove_child(http)
http.queue_free()
if result != HTTPRequest.RESULT_SUCCESS or response_code != 200:

View file

@ -1,7 +1,7 @@
{
"plugin.id": "itch",
"plugin.name": "itch.io",
"plugin.version": "0.1.43",
"plugin.version": "0.1.41",
"plugin.min-api-version": "1.1.0",
"plugin.link": "https://forge.thergic.ar/jose/itchio-opengamepadui-plugin",
"plugin.source": "https://forge.thergic.ar/jose/itchio-opengamepadui-plugin",