diff --git a/release.bat b/release.bat new file mode 100644 index 0000000..58508fd --- /dev/null +++ b/release.bat @@ -0,0 +1,246 @@ +@echo off +setlocal EnableExtensions EnableDelayedExpansion +cd /d "%~dp0" + +REM ============================================================ +REM Item Despawn Timer - Gitea Release Script +REM Windows +REM ============================================================ + +if not defined GITEA_BASE_URL set "GITEA_BASE_URL=https://git.darto.id" +if not defined GITEA_OWNER set "GITEA_OWNER=dartokloning" +if not defined GITEA_REPO set "GITEA_REPO=item-despawn-timer" + +if not exist "gradle.properties" ( + echo [ERROR] gradle.properties tidak ditemukan. + exit /b 1 +) + +set "MOD_VERSION=" +set "MINECRAFT_VERSION=" +set "ARCHIVES_BASE_NAME=" +for /f "usebackq tokens=1,* delims==" %%A in ("gradle.properties") do ( + if "%%A"=="mod_version" set "MOD_VERSION=%%B" + if "%%A"=="minecraft_version" set "MINECRAFT_VERSION=%%B" + if "%%A"=="archives_base_name" set "ARCHIVES_BASE_NAME=%%B" +) + +if not defined MOD_VERSION ( + echo [ERROR] mod_version tidak ditemukan di gradle.properties. + exit /b 1 +) +if not defined MINECRAFT_VERSION ( + echo [ERROR] minecraft_version tidak ditemukan di gradle.properties. + exit /b 1 +) +if not defined ARCHIVES_BASE_NAME set "ARCHIVES_BASE_NAME=item-despawn-timer" + +set "PROJECT_VERSION=%MOD_VERSION%+mc%MINECRAFT_VERSION%" +set "TAG=v%MOD_VERSION%" +set "JAR_NAME=%ARCHIVES_BASE_NAME%-%PROJECT_VERSION%.jar" +set "JAR_PATH=%CD%\build\libs\%JAR_NAME%" + +echo ============================================ +echo Item Despawn Timer - Release %TAG% +echo Mod version: %MOD_VERSION% +echo Minecraft: %MINECRAFT_VERSION% +echo Asset: %JAR_NAME% +echo Gitea: %GITEA_BASE_URL%/%GITEA_OWNER%/%GITEA_REPO% +echo ============================================ +echo. +echo [INFO] Menjalankan build release terlebih dahulu... + +if not exist "%CD%\compiler.bat" ( + echo [ERROR] compiler.bat tidak ditemukan. + exit /b 1 +) +call "%CD%\compiler.bat" --build-only +if errorlevel 1 ( + echo [ERROR] Release dibatalkan karena build gagal. + exit /b 1 +) + +if not exist "%JAR_PATH%" ( + echo [ERROR] JAR release tidak ditemukan: + echo %JAR_PATH% + echo [INFO] Isi build\libs: + dir /b build\libs\*.jar 2>nul + exit /b 1 +) + +where git.exe >nul 2>&1 || ( + echo [ERROR] Git tidak ditemukan di PATH. + exit /b 1 +) +where curl.exe >nul 2>&1 || ( + echo [ERROR] curl.exe tidak ditemukan di PATH. + exit /b 1 +) + +git rev-parse --is-inside-work-tree >nul 2>&1 || ( + echo [ERROR] Folder ini bukan Git repository. + exit /b 1 +) + +set "CURRENT_BRANCH=" +for /f "delims=" %%B in ('git branch --show-current') do set "CURRENT_BRANCH=%%B" +if not defined CURRENT_BRANCH ( + echo [ERROR] Tidak dapat menentukan branch Git aktif. + exit /b 1 +) + +git remote get-url origin >nul 2>&1 || ( + echo [ERROR] Remote 'origin' belum dikonfigurasi. + exit /b 1 +) + +echo. +echo ============================================ +echo Git Release Preparation +echo ============================================ + +set "HAS_CHANGES=" +for /f "delims=" %%G in ('git status --porcelain') do set "HAS_CHANGES=1" + +if defined HAS_CHANGES ( + echo. + echo Perubahan source belum di-commit: + git status --short + echo. + choice /C YN /N /M "Commit dan push perubahan sebelum membuat release? [Y/N]: " + if errorlevel 2 ( + echo [WARN] Release dibatalkan. Source harus bersih agar tag sesuai dengan build. + exit /b 0 + ) + + set "COMMIT_MESSAGE=" + set /p "COMMIT_MESSAGE=Commit message [Prepare Item Despawn Timer %TAG% release]: " + if not defined COMMIT_MESSAGE set "COMMIT_MESSAGE=Prepare Item Despawn Timer %TAG% release" + + git add -A || exit /b 2 + git commit -m "!COMMIT_MESSAGE!" || exit /b 2 +) + +echo [INFO] Push branch !CURRENT_BRANCH! ke origin... +git push origin "!CURRENT_BRANCH!" +if errorlevel 1 ( + echo [ERROR] Push branch gagal. Release dibatalkan. + exit /b 2 +) + +set "HEAD_COMMIT=" +for /f "delims=" %%H in ('git rev-parse HEAD') do set "HEAD_COMMIT=%%H" + +set "TAG_COMMIT=" +for /f "delims=" %%T in ('git rev-list -n 1 "%TAG%" 2^>nul') do set "TAG_COMMIT=%%T" + +if defined TAG_COMMIT ( + if /I not "!TAG_COMMIT!"=="!HEAD_COMMIT!" ( + echo [ERROR] Tag %TAG% sudah ada tetapi menunjuk commit lain. + echo Tag : !TAG_COMMIT! + echo HEAD: !HEAD_COMMIT! + echo Naikkan mod_version sebelum membuat release baru. + exit /b 2 + ) + echo [INFO] Tag lokal %TAG% sudah ada pada commit saat ini. +) else ( + echo [INFO] Membuat tag %TAG%... + git tag -a "%TAG%" -m "Item Despawn Timer %TAG%" || exit /b 2 +) + +git ls-remote --exit-code --tags origin "refs/tags/%TAG%" >nul 2>&1 +if errorlevel 1 ( + echo [INFO] Push tag %TAG% ke origin... + git push origin "%TAG%" || exit /b 2 +) else ( + echo [INFO] Tag %TAG% sudah ada di origin. +) + +echo. +echo ============================================ +echo Gitea Release +echo ============================================ +choice /C YN /N /M "Buat Release %TAG% dan upload %JAR_NAME%? [Y/N]: " +if errorlevel 2 ( + echo [INFO] Pembuatan Gitea Release dilewati. Tag %TAG% tetap sudah tersimpan. + exit /b 0 +) + +if not defined GITEA_TOKEN ( + echo. + set /p "GITEA_TOKEN=Gitea Personal Access Token: " +) +if not defined GITEA_TOKEN ( + echo [ERROR] Token Gitea kosong. + exit /b 2 +) + +set "API_BASE=%GITEA_BASE_URL%/api/v1/repos/%GITEA_OWNER%/%GITEA_REPO%" +set "RELEASE_JSON=%TEMP%\idt-release-%RANDOM%.json" +set "CREATE_JSON=%TEMP%\idt-create-%RANDOM%.json" +set "ASSET_JSON=%TEMP%\idt-asset-%RANDOM%.json" + +set "HTTP_CODE=" +for /f "delims=" %%H in ('curl.exe -sS -o "!RELEASE_JSON!" -w "%%{http_code}" -H "Authorization: token !GITEA_TOKEN!" "!API_BASE!/releases/tags/%TAG%"') do set "HTTP_CODE=%%H" + +if "!HTTP_CODE!"=="200" ( + echo [INFO] Release %TAG% sudah ada. Akan menggunakan release tersebut. +) else if "!HTTP_CODE!"=="404" ( + >"!CREATE_JSON!" echo { + >>"!CREATE_JSON!" echo "tag_name": "%TAG%", + >>"!CREATE_JSON!" echo "target_commitish": "!CURRENT_BRANCH!", + >>"!CREATE_JSON!" echo "name": "Item Despawn Timer %TAG%", + >>"!CREATE_JSON!" echo "body": "Item Despawn Timer %TAG% untuk Minecraft %MINECRAFT_VERSION% ^(Fabric^).", + >>"!CREATE_JSON!" echo "draft": false, + >>"!CREATE_JSON!" echo "prerelease": false + >>"!CREATE_JSON!" echo } + + echo [INFO] Membuat Release %TAG% di Gitea... + set "HTTP_CODE=" + for /f "delims=" %%H in ('curl.exe -sS -o "!RELEASE_JSON!" -w "%%{http_code}" -X POST -H "Authorization: token !GITEA_TOKEN!" -H "Content-Type: application/json" --data-binary "@!CREATE_JSON!" "!API_BASE!/releases"') do set "HTTP_CODE=%%H" + if not "!HTTP_CODE!"=="201" ( + echo [ERROR] Gitea gagal membuat release. HTTP !HTTP_CODE! + type "!RELEASE_JSON!" + exit /b 2 + ) +) else ( + echo [ERROR] Gagal memeriksa release. HTTP !HTTP_CODE! + type "!RELEASE_JSON!" + exit /b 2 +) + +set "RELEASE_ID=" +for /f "delims=" %%I in ('powershell.exe -NoProfile -Command "$r=Get-Content -Raw -LiteralPath '!RELEASE_JSON!' ^| ConvertFrom-Json; $r.id"') do set "RELEASE_ID=%%I" +if not defined RELEASE_ID ( + echo [ERROR] Tidak dapat membaca release ID dari response Gitea. + type "!RELEASE_JSON!" + exit /b 2 +) + +echo [INFO] Release ID: !RELEASE_ID! +echo [INFO] Mengupload %JAR_NAME%... + +set "ASSET_CODE=" +for /f "delims=" %%H in ('curl.exe -sS -o "!ASSET_JSON!" -w "%%{http_code}" -X POST -H "Authorization: token !GITEA_TOKEN!" -F "attachment=@%JAR_PATH%" "!API_BASE!/releases/!RELEASE_ID!/assets?name=%JAR_NAME%"') do set "ASSET_CODE=%%H" + +if "!ASSET_CODE!"=="201" ( + echo. + echo [SUCCESS] Release %TAG% berhasil dibuat dan JAR berhasil diupload. +) else if "!ASSET_CODE!"=="409" ( + echo. + echo [WARN] Release sudah ada dan asset %JAR_NAME% sudah tersedia. +) else ( + echo [ERROR] Upload JAR gagal. HTTP !ASSET_CODE! + type "!ASSET_JSON!" + exit /b 2 +) + +del /q "!RELEASE_JSON!" "!CREATE_JSON!" "!ASSET_JSON!" >nul 2>&1 + +echo. +echo ============================================ +echo RELEASE SUCCESS +echo Tag: %TAG% +echo Asset: %JAR_NAME% +echo ============================================ +exit /b 0 diff --git a/release.sh b/release.sh new file mode 100644 index 0000000..f37e83f --- /dev/null +++ b/release.sh @@ -0,0 +1,183 @@ +#!/usr/bin/env bash +set -u +cd "$(dirname "${BASH_SOURCE[0]}")" || exit 1 + +GITEA_BASE_URL="${GITEA_BASE_URL:-https://git.darto.id}" +GITEA_OWNER="${GITEA_OWNER:-dartokloning}" +GITEA_REPO="${GITEA_REPO:-item-despawn-timer}" + +prop() { sed -n "s/^$1=//p" gradle.properties | head -n1 | tr -d '\r'; } +info() { echo "[INFO] $1"; } +error() { echo "[ERROR] $1"; } + +[[ -f gradle.properties ]] || { error "gradle.properties tidak ditemukan."; exit 1; } + +MOD_VERSION="$(prop mod_version)" +MINECRAFT_VERSION="$(prop minecraft_version)" +ARCHIVES_BASE_NAME="$(prop archives_base_name)" +ARCHIVES_BASE_NAME="${ARCHIVES_BASE_NAME:-item-despawn-timer}" + +[[ -n "$MOD_VERSION" && -n "$MINECRAFT_VERSION" ]] || { + error "mod_version/minecraft_version tidak lengkap."; exit 1; +} + +PROJECT_VERSION="${MOD_VERSION}+mc${MINECRAFT_VERSION}" +TAG="v${MOD_VERSION}" +JAR_NAME="${ARCHIVES_BASE_NAME}-${PROJECT_VERSION}.jar" +JAR_PATH="$PWD/build/libs/$JAR_NAME" + +echo "============================================" +echo " Item Despawn Timer - Release $TAG" +echo " Mod version: $MOD_VERSION" +echo " Minecraft: $MINECRAFT_VERSION" +echo " Asset: $JAR_NAME" +echo " Gitea: $GITEA_BASE_URL/$GITEA_OWNER/$GITEA_REPO" +echo "============================================" +echo + +[[ -f ./compiler.sh ]] || { error "compiler.sh tidak ditemukan."; exit 1; } +chmod +x ./compiler.sh +info "Menjalankan build release terlebih dahulu..." +./compiler.sh --build-only || { error "Release dibatalkan karena build gagal."; exit 1; } + +[[ -f "$JAR_PATH" ]] || { + error "JAR release tidak ditemukan: $JAR_PATH" + ls -1 build/libs/*.jar 2>/dev/null || true + exit 1 +} + +command -v git >/dev/null || { error "Git tidak ditemukan di PATH."; exit 1; } +command -v curl >/dev/null || { error "curl tidak ditemukan di PATH."; exit 1; } +git rev-parse --is-inside-work-tree >/dev/null 2>&1 || { error "Folder ini bukan Git repository."; exit 1; } + +CURRENT_BRANCH="$(git branch --show-current)" +[[ -n "$CURRENT_BRANCH" ]] || { error "Tidak dapat menentukan branch Git aktif."; exit 1; } +git remote get-url origin >/dev/null 2>&1 || { error "Remote origin belum dikonfigurasi."; exit 1; } + +echo +echo "============================================" +echo " Git Release Preparation" +echo "============================================" + +if [[ -n "$(git status --porcelain)" ]]; then + echo + echo "Perubahan source belum di-commit:" + git status --short + echo + read -r -p "Commit dan push perubahan sebelum membuat release? [Y/N]: " sync + [[ "$sync" =~ ^[Yy]$ ]] || { echo "[WARN] Release dibatalkan. Source harus bersih."; exit 0; } + + default="Prepare Item Despawn Timer $TAG release" + read -r -p "Commit message [$default]: " msg + msg="${msg:-$default}" + git add -A || exit 2 + git commit -m "$msg" || exit 2 +fi + +info "Push branch $CURRENT_BRANCH ke origin..." +git push origin "$CURRENT_BRANCH" || { error "Push branch gagal. Release dibatalkan."; exit 2; } + +HEAD_COMMIT="$(git rev-parse HEAD)" +if git rev-parse "$TAG" >/dev/null 2>&1; then + TAG_COMMIT="$(git rev-list -n 1 "$TAG")" + [[ "$TAG_COMMIT" == "$HEAD_COMMIT" ]] || { + error "Tag $TAG sudah ada tetapi menunjuk commit lain." + echo "Tag : $TAG_COMMIT" + echo "HEAD: $HEAD_COMMIT" + echo "Naikkan mod_version sebelum membuat release baru." + exit 2 + } + info "Tag lokal $TAG sudah ada pada commit saat ini." +else + info "Membuat tag $TAG..." + git tag -a "$TAG" -m "Item Despawn Timer $TAG" || exit 2 +fi + +if git ls-remote --exit-code --tags origin "refs/tags/$TAG" >/dev/null 2>&1; then + info "Tag $TAG sudah ada di origin." +else + info "Push tag $TAG ke origin..." + git push origin "$TAG" || exit 2 +fi + +echo +echo "============================================" +echo " Gitea Release" +echo "============================================" +read -r -p "Buat Release $TAG dan upload $JAR_NAME? [Y/N]: " confirm +[[ "$confirm" =~ ^[Yy]$ ]] || { + info "Pembuatan Gitea Release dilewati. Tag $TAG tetap sudah tersimpan." + exit 0 +} + +if [[ -z "${GITEA_TOKEN:-}" ]]; then + read -r -s -p "Gitea Personal Access Token: " GITEA_TOKEN + echo +fi +[[ -n "$GITEA_TOKEN" ]] || { error "Token Gitea kosong."; exit 2; } + +API_BASE="$GITEA_BASE_URL/api/v1/repos/$GITEA_OWNER/$GITEA_REPO" +TMP_DIR="$(mktemp -d)" +trap 'rm -rf "$TMP_DIR"' EXIT +RELEASE_JSON="$TMP_DIR/release.json" +CREATE_JSON="$TMP_DIR/create.json" +ASSET_JSON="$TMP_DIR/asset.json" + +HTTP_CODE="$(curl -sS -o "$RELEASE_JSON" -w '%{http_code}' \ + -H "Authorization: token $GITEA_TOKEN" "$API_BASE/releases/tags/$TAG")" + +if [[ "$HTTP_CODE" == "200" ]]; then + info "Release $TAG sudah ada. Akan menggunakan release tersebut." +elif [[ "$HTTP_CODE" == "404" ]]; then + cat > "$CREATE_JSON" <