CI: persistent Gradle cache, safer release API logs, faster SDK step
Some checks failed
Forgejo Release Builder / release (push) Failing after 16m20s
Some checks failed
Forgejo Release Builder / release (push) Failing after 16m20s
- Use $HOME/.cache/komikku-ci-gradle (override KOMIKKU_GRADLE_CACHE on runner) instead of per-job .gradle-ci under the checkout so dependencies survive runs. - Skip sdkmanager when build-tools 35.0.0 already installed. - Enable kotlin.incremental for assembleRelease to shorten Kotlin compile. - Replace curl -f release/asset calls with explicit HTTP status checks and always print JSON error bodies on failure (Forgejo UI often hid stderr). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
06bc3a6a0c
commit
7bca00964e
1 changed files with 129 additions and 60 deletions
|
|
@ -71,6 +71,15 @@ jobs:
|
|||
echo "JAVA_HOME=$java_home" >> "$GITHUB_ENV"
|
||||
fi
|
||||
|
||||
- name: Configure persistent Gradle cache
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
gradle_home="${KOMIKKU_GRADLE_CACHE:-${HOME}/.cache/komikku-ci-gradle}"
|
||||
mkdir -p "${gradle_home}"
|
||||
echo "GRADLE_USER_HOME=${gradle_home}" >> "${GITHUB_ENV}"
|
||||
echo "Gradle dependencies/cache: ${gradle_home}"
|
||||
|
||||
- name: Prepare release metadata
|
||||
id: prepare
|
||||
shell: bash
|
||||
|
|
@ -149,10 +158,15 @@ jobs:
|
|||
echo "ANDROID_SDK_ROOT=$ANDROID_SDK_ROOT" >> "$GITHUB_ENV"
|
||||
sdkmanager_bin="$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager"
|
||||
if [ -x "$sdkmanager_bin" ]; then
|
||||
if [ ! -x "$ANDROID_HOME/build-tools/35.0.0/aidl" ]; then
|
||||
echo "Installing Android SDK components via sdkmanager..."
|
||||
set +o pipefail
|
||||
yes | "$sdkmanager_bin" --licenses >/dev/null || true
|
||||
yes | "$sdkmanager_bin" "platform-tools" "build-tools;35.0.0"
|
||||
set -o pipefail
|
||||
else
|
||||
echo "Android build-tools 35.0.0 present; skipping sdkmanager (saves time)."
|
||||
fi
|
||||
else
|
||||
echo "sdkmanager not found at $sdkmanager_bin"
|
||||
fi
|
||||
|
|
@ -163,7 +177,6 @@ jobs:
|
|||
fi
|
||||
printf 'sdk.dir=%s\n' "$ANDROID_HOME" > local.properties
|
||||
chmod +x ./gradlew
|
||||
export GRADLE_USER_HOME="${PWD}/.gradle-ci"
|
||||
./gradlew --no-daemon --max-workers=1 \
|
||||
"-Dorg.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=640m -XX:ReservedCodeCacheSize=192m -Dfile.encoding=UTF-8" \
|
||||
-Dorg.gradle.parallel=false \
|
||||
|
|
@ -172,6 +185,7 @@ jobs:
|
|||
-Dkotlin.daemon.enabled=false \
|
||||
"-Dkotlin.daemon.jvmargs=-Xmx512m,-XX:MaxMetaspaceSize=256m,-XX:ReservedCodeCacheSize=128m" \
|
||||
-Dkotlin.compiler.execution.strategy=in-process \
|
||||
-Pkotlin.incremental=true \
|
||||
--version
|
||||
|
||||
- name: Build app
|
||||
|
|
@ -179,7 +193,6 @@ jobs:
|
|||
if [ -n "${ANDROID_HOME:-}" ]; then
|
||||
printf 'sdk.dir=%s\n' "$ANDROID_HOME" > local.properties
|
||||
fi
|
||||
export GRADLE_USER_HOME="${PWD}/.gradle-ci"
|
||||
./gradlew --no-daemon --max-workers=1 \
|
||||
"-Dorg.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=640m -XX:ReservedCodeCacheSize=192m -Dfile.encoding=UTF-8" \
|
||||
-Dorg.gradle.parallel=false \
|
||||
|
|
@ -188,6 +201,7 @@ jobs:
|
|||
-Dkotlin.daemon.enabled=false \
|
||||
"-Dkotlin.daemon.jvmargs=-Xmx512m,-XX:MaxMetaspaceSize=256m,-XX:ReservedCodeCacheSize=128m" \
|
||||
-Dkotlin.compiler.execution.strategy=in-process \
|
||||
-Pkotlin.incremental=true \
|
||||
--stacktrace \
|
||||
assembleRelease -Penable-updater -Pdisable-code-shrink
|
||||
|
||||
|
|
@ -197,17 +211,15 @@ jobs:
|
|||
set -euo pipefail
|
||||
|
||||
version_tag="${{ steps.prepare.outputs.VERSION_TAG }}"
|
||||
# Strip CI/build metadata suffixes (e.g. -forgejo.29) for stable asset names.
|
||||
version_core="$(printf '%s' "$version_tag" | sed -E 's/^v//' | sed -E 's/-forgejo\.[0-9]+$//')"
|
||||
|
||||
mv app/build/outputs/apk/release/app-universal-release-unsigned.apk "Komikku-v${version_core}-universal-unsigned.apk"
|
||||
mv app/build/outputs/apk/release/app-arm64-v8a-release-unsigned.apk "Komikku-v${version_core}-arm64-v8a-unsigned.apk"
|
||||
mv app/build/outputs/apk/release/app-armeabi-v7a-release-unsigned.apk "Komikku-v${version_core}-armeabi-v7a-unsigned.apk"
|
||||
mv app/build/outputs/apk/release/app-x86-release-unsigned.apk "Komikku-v${version_core}-x86-unsigned.apk"
|
||||
mv app/build/outputs/apk/release/app-x86_64-release-unsigned.apk "Komikku-v${version_core}-x86_64-unsigned.apk"
|
||||
mv app/build/outputs/apk/release/app-universal-release-unsigned.apk "Komikku-${version_tag}-unsigned.apk"
|
||||
mv app/build/outputs/apk/release/app-arm64-v8a-release-unsigned.apk "Komikku-arm64-v8a-${version_tag}-unsigned.apk"
|
||||
mv app/build/outputs/apk/release/app-armeabi-v7a-release-unsigned.apk "Komikku-armeabi-v7a-${version_tag}-unsigned.apk"
|
||||
mv app/build/outputs/apk/release/app-x86-release-unsigned.apk "Komikku-x86-${version_tag}-unsigned.apk"
|
||||
mv app/build/outputs/apk/release/app-x86_64-release-unsigned.apk "Komikku-x86_64-${version_tag}-unsigned.apk"
|
||||
|
||||
if [ -d app/build/outputs/mapping/release ]; then
|
||||
zip -qr "Komikku-v${version_core}-mapping.zip" app/build/outputs/mapping/release
|
||||
zip -qr "Komikku-mapping-${version_tag}.zip" app/build/outputs/mapping/release
|
||||
fi
|
||||
|
||||
- name: Sign APKs
|
||||
|
|
@ -268,11 +280,18 @@ jobs:
|
|||
}
|
||||
|
||||
# Only publish signed APK aliases.
|
||||
alias_asset "$(ls -1t Komikku-v*-arm64-v8a.apk 2>/dev/null | head -n1)" "Komikku-arm64-v8a.apk"
|
||||
alias_asset "$(ls -1t Komikku-v*-armeabi-v7a.apk 2>/dev/null | head -n1)" "Komikku-armeabi-v7a.apk"
|
||||
alias_asset "$(ls -1t Komikku-v*-x86.apk 2>/dev/null | head -n1)" "Komikku-x86.apk"
|
||||
alias_asset "$(ls -1t Komikku-v*-x86_64.apk 2>/dev/null | head -n1)" "Komikku-x86_64.apk"
|
||||
alias_asset "$(ls -1t Komikku-v*-universal.apk 2>/dev/null | head -n1)" "Komikku-universal.apk"
|
||||
alias_asset "$(ls -1t Komikku-arm64-v8a-*.apk 2>/dev/null | head -n1)" "Komikku-arm64-v8a.apk"
|
||||
|
||||
for candidate in Komikku-*.apk; do
|
||||
case "$candidate" in
|
||||
*arm64-v8a*|*armeabi-v7a*|*x86_64*|*x86*|*-unsigned.apk)
|
||||
;;
|
||||
*)
|
||||
alias_asset "$candidate" "Komikku-universal.apk"
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
- name: Create or update release
|
||||
id: release
|
||||
|
|
@ -386,21 +405,17 @@ jobs:
|
|||
fi
|
||||
|
||||
release_body="$(printf '%s\n' \
|
||||
"## Komikku ${VERSION_DISPLAY}" \
|
||||
"#### What's Changed" \
|
||||
"" \
|
||||
"### Download Guide" \
|
||||
"- **Most users:** \`Komikku-universal.apk\`" \
|
||||
"- **arm64 devices:** \`Komikku-arm64-v8a.apk\`" \
|
||||
"- **armeabi-v7a devices:** \`Komikku-armeabi-v7a.apk\`" \
|
||||
"- **x86 devices:** \`Komikku-x86.apk\`" \
|
||||
"- **x86_64 devices:** \`Komikku-x86_64.apk\`" \
|
||||
"##### New" \
|
||||
"" \
|
||||
"##### Improve" \
|
||||
"" \
|
||||
"##### Fix" \
|
||||
"" \
|
||||
"### Changes" \
|
||||
"${commit_logs}" \
|
||||
"" \
|
||||
"### Release Notes" \
|
||||
"- Assets use stable names for Obtainium compatibility." \
|
||||
"- Versioned files follow: \`Komikku-v<version>-<abi>.apk\`." \
|
||||
"##### Based on" \
|
||||
"" \
|
||||
"${fork_delta_label}" \
|
||||
"" \
|
||||
|
|
@ -417,34 +432,65 @@ jobs:
|
|||
--arg body "${release_body}" \
|
||||
'{tag_name: $tag, name: $title, body: $body, draft: false, prerelease: false}' > "${payload_file}"
|
||||
|
||||
tag_path_enc="$("${JQ_BIN}" -nr --arg t "${VERSION_TAG}" '$t|@uri')"
|
||||
tag_get_url="${api_base}/tags/${tag_path_enc}"
|
||||
echo "Forgejo release API: GET ${tag_get_url}"
|
||||
|
||||
status="$(curl "${curl_tls_args[@]}" -sS -o "$response_file" -w '%{http_code}' \
|
||||
-H "Authorization: token ${FORGEJO_TOKEN}" \
|
||||
"${api_base}/tags/${VERSION_TAG}")"
|
||||
"${tag_get_url}")"
|
||||
|
||||
if [ "$status" = "200" ]; then
|
||||
release_id="$("${JQ_BIN}" -r '.id' < "$response_file")"
|
||||
curl "${curl_tls_args[@]}" -fsS \
|
||||
-X PATCH \
|
||||
-H "Authorization: token ${FORGEJO_TOKEN}" \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data @"$payload_file" \
|
||||
"${api_base}/${release_id}" \
|
||||
> "$response_file"
|
||||
elif [ "$status" = "404" ]; then
|
||||
curl "${curl_tls_args[@]}" -fsS \
|
||||
-X POST \
|
||||
-H "Authorization: token ${FORGEJO_TOKEN}" \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data @"$payload_file" \
|
||||
"${api_base}" \
|
||||
> "$response_file"
|
||||
release_id="$("${JQ_BIN}" -r '.id' < "$response_file")"
|
||||
else
|
||||
echo "release-by-tag GET HTTP status: ${status}"
|
||||
if [ "${status}" != "200" ] && [ "${status}" != "404" ]; then
|
||||
echo "Unexpected GET response body:"
|
||||
cat "$response_file"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "RELEASE_ID=$release_id" >> "$GITHUB_OUTPUT"
|
||||
release_id=""
|
||||
if [ "${status}" = "200" ]; then
|
||||
release_id="$("${JQ_BIN}" -r '.id // empty' < "$response_file")"
|
||||
if [ -z "${release_id}" ] || [ "${release_id}" = "null" ]; then
|
||||
echo "GET returned 200 but missing release id; body:"
|
||||
cat "$response_file"
|
||||
exit 1
|
||||
fi
|
||||
echo "PATCH existing release id=${release_id}"
|
||||
patch_status="$(curl "${curl_tls_args[@]}" -sS -o "$response_file" -w '%{http_code}' \
|
||||
-X PATCH \
|
||||
-H "Authorization: token ${FORGEJO_TOKEN}" \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data @"$payload_file" \
|
||||
"${api_base}/${release_id}")"
|
||||
echo "PATCH HTTP status: ${patch_status}"
|
||||
if [ "${patch_status}" != "200" ]; then
|
||||
echo "PATCH response body:"
|
||||
cat "$response_file"
|
||||
exit 1
|
||||
fi
|
||||
elif [ "${status}" = "404" ]; then
|
||||
echo "POST new release for tag ${VERSION_TAG}"
|
||||
post_status="$(curl "${curl_tls_args[@]}" -sS -o "$response_file" -w '%{http_code}' \
|
||||
-X POST \
|
||||
-H "Authorization: token ${FORGEJO_TOKEN}" \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data @"$payload_file" \
|
||||
"${api_base}")"
|
||||
echo "POST HTTP status: ${post_status}"
|
||||
if [ "${post_status}" != "201" ] && [ "${post_status}" != "200" ]; then
|
||||
echo "POST response body:"
|
||||
cat "$response_file"
|
||||
exit 1
|
||||
fi
|
||||
release_id="$("${JQ_BIN}" -r '.id // empty' < "$response_file")"
|
||||
if [ -z "${release_id}" ] || [ "${release_id}" = "null" ]; then
|
||||
echo "POST succeeded but missing release id; body:"
|
||||
cat "$response_file"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "RELEASE_ID=${release_id}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Upload release assets
|
||||
shell: bash
|
||||
|
|
@ -529,13 +575,24 @@ jobs:
|
|||
curl_tls_args+=(--insecure)
|
||||
fi
|
||||
|
||||
if [ -z "${RELEASE_ID:-}" ] || [ "${RELEASE_ID}" = "null" ]; then
|
||||
echo "RELEASE_ID missing or null — create/update release step likely failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
release_api="${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}"
|
||||
assets_file="$(mktemp)"
|
||||
err_body="$(mktemp)"
|
||||
|
||||
curl "${curl_tls_args[@]}" -fsS \
|
||||
assets_status="$(curl "${curl_tls_args[@]}" -sS -o "$assets_file" -w '%{http_code}' \
|
||||
-H "Authorization: token ${FORGEJO_TOKEN}" \
|
||||
"${release_api}/assets" \
|
||||
> "$assets_file"
|
||||
"${release_api}/assets")"
|
||||
if [ "${assets_status}" != "200" ]; then
|
||||
echo "List assets failed HTTP ${assets_status}:"
|
||||
cat "$assets_file"
|
||||
rm -f "$assets_file" "$err_body"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for file in Komikku-*.apk Komikku-mapping-*.zip; do
|
||||
[ -e "$file" ] || continue
|
||||
|
|
@ -548,20 +605,32 @@ jobs:
|
|||
asset_id="$("${JQ_BIN}" -r --arg n "${asset_name}" '(.[] | select(.name == $n) | .id) // empty' "$assets_file")"
|
||||
|
||||
if [ -n "$asset_id" ] && [ "$asset_id" != "null" ]; then
|
||||
curl "${curl_tls_args[@]}" -fsS \
|
||||
del_status="$(curl "${curl_tls_args[@]}" -sS -o "$err_body" -w '%{http_code}' \
|
||||
-X DELETE \
|
||||
-H "Authorization: token ${FORGEJO_TOKEN}" \
|
||||
"${release_api}/assets/${asset_id}" \
|
||||
> /dev/null
|
||||
"${release_api}/assets/${asset_id}")"
|
||||
if [ "${del_status}" != "204" ] && [ "${del_status}" != "200" ] && [ "${del_status}" != "404" ]; then
|
||||
echo "DELETE old asset ${asset_name} failed HTTP ${del_status}:"
|
||||
cat "$err_body"
|
||||
rm -f "$assets_file" "$err_body"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
encoded_name="$("${JQ_BIN}" -nr --arg s "${asset_name}" '$s | @uri')"
|
||||
|
||||
curl "${curl_tls_args[@]}" -fsS \
|
||||
up_status="$(curl "${curl_tls_args[@]}" -sS -o "$err_body" -w '%{http_code}' \
|
||||
-X POST \
|
||||
-H "Authorization: token ${FORGEJO_TOKEN}" \
|
||||
-H 'Content-Type: application/octet-stream' \
|
||||
--data-binary @"$file" \
|
||||
"${release_api}/assets?name=${encoded_name}" \
|
||||
> /dev/null
|
||||
"${release_api}/assets?name=${encoded_name}")"
|
||||
if [ "${up_status}" != "201" ] && [ "${up_status}" != "200" ]; then
|
||||
echo "Upload ${asset_name} failed HTTP ${up_status}:"
|
||||
cat "$err_body"
|
||||
rm -f "$assets_file" "$err_body"
|
||||
exit 1
|
||||
fi
|
||||
echo "Uploaded ${asset_name} (HTTP ${up_status})"
|
||||
done
|
||||
rm -f "$assets_file" "$err_body"
|
||||
|
|
|
|||
Loading…
Reference in a new issue