komikku/.forgejo/workflows/build_release.yml
littlecodedragon 5396ebad7c
Some checks failed
Forgejo Release Builder / release (push) Failing after 3m15s
Fix Forgejo release workflow for Docker executor.
Use a container-reachable Forgejo checkout URL and support package installs via root or sudo in container jobs.
2026-04-27 06:05:44 +02:00

282 lines
9.3 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 config --global http.sslVerify false
git remote add origin "https://copilot:${FORGEJO_TOKEN}@192.168.1.155: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
if command -v dnf >/dev/null 2>&1; then
pkg_install dnf install -y java-17-openjdk-devel
elif command -v apt-get >/dev/null 2>&1; then
pkg_install apt-get update
pkg_install apt-get install -y openjdk-17-jdk
elif command -v apk >/dev/null 2>&1; then
pkg_install apk add --no-cache openjdk17
elif 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: Write google-services.json
shell: bash
run: |
set -euo pipefail
cat > app/google-services.json <<'EOF'
${{ secrets.GOOGLE_SERVICES_JSON }}
EOF
- name: Write client_secrets.json
shell: bash
run: |
set -euo pipefail
mkdir -p app/src/main/assets
cat > app/src/main/assets/client_secrets.json <<'EOF'
${{ secrets.GOOGLE_CLIENT_SECRETS_JSON }}
EOF
- 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
chmod +x ./gradlew
./gradlew --version
- name: Check code format
run: ./gradlew spotlessCheck
- name: Build app
run: ./gradlew assembleRelease -Pinclude-telemetry -Penable-updater
- name: Run unit tests
run: ./gradlew 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