komikku/.forgejo/workflows/build_release.yml
littlecodedragon 688b796e59
Some checks failed
Forgejo Release Builder / release (push) Failing after 17m39s
Make Forgejo release build work without Google secrets.
Remove secret JSON steps and build without telemetry so local fork release CI can run without cloud credentials.
2026-04-27 17:17:24 +02:00

273 lines
9.5 KiB
YAML
Executable file

name: Forgejo Release Builder
# NOTE: keep Forgejo action refs node20-compatible for runner v3.5.1.
on:
push:
tags:
- v*
permissions:
contents: write
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
release:
runs-on: forgejo-release
steps:
- name: Clone repository
shell: bash
env:
FORGEJO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
rm -rf .git
git init .
git remote add origin "http://copilot:${FORGEJO_TOKEN}@127.0.0.1:3030/${GITHUB_REPOSITORY}.git"
git fetch --tags --prune --depth=1 origin "${GITHUB_SHA}"
git checkout --force FETCH_HEAD
- name: Set up JDK
shell: bash
run: |
set -euo pipefail
pkg_install() {
if [ "$(id -u)" -eq 0 ]; then
"$@"
elif command -v sudo >/dev/null 2>&1; then
sudo "$@"
else
echo "Need root or sudo to install packages."
exit 1
fi
}
if command -v java >/dev/null 2>&1; then
java -version
else
echo "PATH=$PATH"
echo "pkg managers: dnf=$(command -v dnf || true) apt=$(command -v apt-get || true) apk=$(command -v apk || true) pacman=$(command -v pacman || true)"
if [ -x /usr/bin/dnf ] || command -v dnf >/dev/null 2>&1; then
pkg_install dnf install -y java-17-openjdk-devel
elif [ -x /usr/bin/apt-get ] || command -v apt-get >/dev/null 2>&1; then
pkg_install apt-get update
pkg_install apt-get install -y openjdk-17-jdk
elif [ -x /sbin/apk ] || [ -x /usr/sbin/apk ] || command -v apk >/dev/null 2>&1; then
pkg_install apk add --no-cache openjdk17
elif [ -x /usr/bin/pacman ] || command -v pacman >/dev/null 2>&1; then
pkg_install pacman -Sy --noconfirm jdk17-openjdk
else
echo "No supported package manager found for JDK installation."
exit 1
fi
java -version
fi
- name: Prepare release metadata
id: prepare
shell: bash
run: |
set -euo pipefail
version_tag="${GITHUB_REF_NAME:-${GITHUB_REF#refs/tags/}}"
previous_tag="$(git tag --list 'v*' --sort=-version:refname | grep -Fxv "$version_tag" | head -n 1 || true)"
echo "VERSION_TAG=$version_tag" >> "$GITHUB_OUTPUT"
echo "PREV_TAG_NAME=$previous_tag" >> "$GITHUB_OUTPUT"
if [ -n "$previous_tag" ]; then
commit_logs="$(git log --pretty=format:'- %s (@%an)' "${previous_tag}..HEAD")"
else
commit_logs='- Initial release'
fi
{
echo 'COMMIT_LOGS<<EOF'
printf '%s\n' "$commit_logs"
echo 'EOF'
} >> "$GITHUB_OUTPUT"
- name: Set up Gradle
shell: bash
run: |
set -euo pipefail
if [ -d /opt/android-sdk-linux ]; then
export ANDROID_HOME=/opt/android-sdk-linux
export ANDROID_SDK_ROOT=/opt/android-sdk-linux
echo "ANDROID_HOME=$ANDROID_HOME" >> "$GITHUB_ENV"
echo "ANDROID_SDK_ROOT=$ANDROID_SDK_ROOT" >> "$GITHUB_ENV"
printf 'sdk.dir=%s\n' "$ANDROID_HOME" > local.properties
fi
chmod +x ./gradlew
./gradlew --no-daemon --version
- name: Check code format
run: ./gradlew --no-daemon --max-workers=2 spotlessCheck
- name: Build app
run: ./gradlew --no-daemon --max-workers=2 assembleRelease -Penable-updater
- name: Run unit tests
run: ./gradlew --no-daemon --max-workers=2 testReleaseUnitTest
- name: Rename release artifacts
shell: bash
run: |
set -euo pipefail
version_tag="${{ steps.prepare.outputs.VERSION_TAG }}"
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"
zip -qr "Komikku-mapping-${version_tag}.zip" app/build/outputs/mapping/release
- name: Create or update release
id: release
shell: bash
env:
FORGEJO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION_TAG: ${{ steps.prepare.outputs.VERSION_TAG }}
PREV_TAG_NAME: ${{ steps.prepare.outputs.PREV_TAG_NAME }}
COMMIT_LOGS: ${{ steps.prepare.outputs.COMMIT_LOGS }}
REPO_URL: ${{ github.server_url }}/${{ github.repository }}
REPOSITORY_NAME: ${{ github.repository }}
run: |
set -euo pipefail
api_base="${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/releases"
payload_file="$(mktemp)"
response_file="$(mktemp)"
python3 - <<'PY' > "$payload_file"
import json
import os
import textwrap
version_tag = os.environ["VERSION_TAG"]
previous_tag = os.environ.get("PREV_TAG_NAME", "").strip()
commit_logs = os.environ.get("COMMIT_LOGS", "").strip() or "- Initial release"
repo_url = os.environ["REPO_URL"]
repository_name = os.environ["REPOSITORY_NAME"]
if previous_tag:
full_changelog = (
f"**Full Changelog**: "
f"[{repository_name}@{previous_tag}...{version_tag}]"
f"({repo_url}/compare/{previous_tag}...{version_tag})"
)
else:
full_changelog = ""
body = textwrap.dedent(
f"""\
#### What's Changed
##### New
##### Improve
##### Fix
{commit_logs}
##### Based on
{full_changelog}
<!-->
> [!TIP]
>
> ### If you are unsure which version to download then go with `Komikku-{version_tag}.apk`
""",
)
print(
json.dumps(
{
"tag_name": version_tag,
"name": f"Komikku {version_tag}",
"body": body,
"draft": True,
"prerelease": False,
},
),
)
PY
status="$(curl -sS -o "$response_file" -w '%{http_code}' \
-H "Authorization: token ${FORGEJO_TOKEN}" \
"${api_base}/tags/${VERSION_TAG}")"
if [ "$status" = "200" ]; then
release_id="$(python3 -c 'import json, sys; print(json.load(sys.stdin)["id"])' < "$response_file")"
curl -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 -fsS \
-X POST \
-H "Authorization: token ${FORGEJO_TOKEN}" \
-H 'Content-Type: application/json' \
--data @"$payload_file" \
"${api_base}" \
> "$response_file"
release_id="$(python3 -c 'import json, sys; print(json.load(sys.stdin)["id"])' < "$response_file")"
else
cat "$response_file"
exit 1
fi
echo "RELEASE_ID=$release_id" >> "$GITHUB_OUTPUT"
- name: Upload release assets
shell: bash
env:
FORGEJO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_ID: ${{ steps.release.outputs.RELEASE_ID }}
run: |
set -euo pipefail
release_api="${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}"
assets_file="$(mktemp)"
curl -fsS \
-H "Authorization: token ${FORGEJO_TOKEN}" \
"${release_api}/assets" \
> "$assets_file"
for file in Komikku-*.apk Komikku-mapping-*.zip; do
[ -e "$file" ] || continue
asset_name="$(basename "$file")"
asset_id="$(
python3 -c 'import json, sys; assets = json.load(open(sys.argv[1], encoding="utf-8")); name = sys.argv[2]; print(next((str(asset["id"]) for asset in assets if asset.get("name") == name), ""))' \
"$assets_file" \
"$asset_name"
)"
if [ -n "$asset_id" ]; then
curl -fsS \
-X DELETE \
-H "Authorization: token ${FORGEJO_TOKEN}" \
"${release_api}/assets/${asset_id}" \
> /dev/null
fi
encoded_name="$(python3 -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1]))' "$asset_name")"
curl -fsS \
-X POST \
-H "Authorization: token ${FORGEJO_TOKEN}" \
-H 'Content-Type: application/octet-stream' \
--data-binary @"$file" \
"${release_api}/assets?name=${encoded_name}" \
> /dev/null
done