Initial commit
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
140
scripts/release.sh
Executable file
140
scripts/release.sh
Executable file
@@ -0,0 +1,140 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=lib/common.sh
|
||||
source "${SCRIPT_DIR}/lib/common.sh"
|
||||
|
||||
usage() {
|
||||
cat >&2 <<'EOF'
|
||||
Usage: release.sh <tag> [--name NAME] [--notes TEXT] [--target BRANCH]
|
||||
[--draft] [--prerelease] [--asset PATH]... [--repo NAME]
|
||||
|
||||
<tag> tag_name;若 tag 不存在 Gitea 會在 target 自動建
|
||||
--name release 標題(預設同 tag)
|
||||
--notes release 說明
|
||||
--target target_commitish;預設 HEAD 所在分支
|
||||
--draft 建成 draft
|
||||
--prerelease 標記 prerelease
|
||||
--asset PATH 要上傳的附件(可重複)
|
||||
--repo NAME 指定 repo;省略則從 cwd origin 推斷
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
[[ $# -ge 1 ]] || usage
|
||||
|
||||
TAG=""
|
||||
NAME=""
|
||||
NOTES=""
|
||||
TARGET=""
|
||||
DRAFT=false
|
||||
PRERELEASE=false
|
||||
ASSETS=()
|
||||
REPO_OVERRIDE=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--name) [[ $# -ge 2 ]] || { log_err "--name 需要值"; exit 1; }; NAME="$2"; shift 2 ;;
|
||||
--notes) [[ $# -ge 2 ]] || { log_err "--notes 需要值"; exit 1; }; NOTES="$2"; shift 2 ;;
|
||||
--target) [[ $# -ge 2 ]] || { log_err "--target 需要值"; exit 1; }; TARGET="$2"; shift 2 ;;
|
||||
--draft) DRAFT=true; shift ;;
|
||||
--prerelease) PRERELEASE=true; shift ;;
|
||||
--asset) [[ $# -ge 2 ]] || { log_err "--asset 需要值"; exit 1; }; ASSETS+=("$2"); shift 2 ;;
|
||||
--repo) [[ $# -ge 2 ]] || { log_err "--repo 需要值"; exit 1; }; REPO_OVERRIDE="$2"; shift 2 ;;
|
||||
-h|--help) usage ;;
|
||||
-*) log_err "未知參數:$1"; usage ;;
|
||||
*)
|
||||
if [[ -z "$TAG" ]]; then TAG="$1"; else log_err "多餘參數:$1"; usage; fi
|
||||
shift ;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ -n "$TAG" ]] || usage
|
||||
NAME="${NAME:-$TAG}"
|
||||
|
||||
load_config
|
||||
require_cmd jq
|
||||
|
||||
if [[ -n "$REPO_OVERRIDE" ]]; then
|
||||
OWNER_REPO="${GITEA_USER}/${REPO_OVERRIDE}"
|
||||
else
|
||||
if ! OWNER_REPO="$(infer_repo_from_cwd)"; then
|
||||
log_err "無法從 cwd 推斷 repo;請加 --repo"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z "$TARGET" ]]; then
|
||||
if git rev-parse --git-dir >/dev/null 2>&1; then
|
||||
TARGET="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || true)"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 驗證 asset 路徑
|
||||
for a in "${ASSETS[@]+"${ASSETS[@]}"}"; do
|
||||
if [[ ! -f "$a" ]]; then
|
||||
log_err "找不到 asset 檔案:$a"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# 組 release body
|
||||
BODY="$(jq -n \
|
||||
--arg tag "$TAG" \
|
||||
--arg name "$NAME" \
|
||||
--arg body "$NOTES" \
|
||||
--arg target "$TARGET" \
|
||||
--argjson draft "$DRAFT" \
|
||||
--argjson prerelease "$PRERELEASE" \
|
||||
'{tag_name:$tag, name:$name, body:$body, draft:$draft, prerelease:$prerelease}
|
||||
+ (if $target == "" then {} else {target_commitish:$target} end)')"
|
||||
|
||||
log_info "建立 release ${OWNER_REPO} / ${TAG}"
|
||||
gitea_api POST "/repos/${OWNER_REPO}/releases" "$BODY"
|
||||
|
||||
case "$HTTP_CODE" in
|
||||
201) log_ok "release 已建立" ;;
|
||||
404) log_err "找不到 repo:${OWNER_REPO}"; exit 1 ;;
|
||||
*) log_err "建立 release 失敗 (HTTP ${HTTP_CODE})"; { cat "$GITEA_API_RESP_FILE"; echo ""; } >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
RELEASE_ID="$(jq -r '.id' < "$GITEA_API_RESP_FILE")"
|
||||
RELEASE_URL="$(jq -r '.html_url' < "$GITEA_API_RESP_FILE")"
|
||||
|
||||
# stdout 先印 release URL
|
||||
echo "$RELEASE_URL"
|
||||
|
||||
# 上傳 asset
|
||||
FAILED=()
|
||||
for a in "${ASSETS[@]+"${ASSETS[@]}"}"; do
|
||||
local_name="$(basename "$a")"
|
||||
log_info "上傳 asset:${local_name}"
|
||||
UP_RESP="$(mktemp)"
|
||||
UP_CODE="$(curl -sS -o "$UP_RESP" -w '%{http_code}' \
|
||||
-X POST \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-F "attachment=@${a};filename=${local_name}" \
|
||||
"${GITEA_URL}/api/v1/repos/${OWNER_REPO}/releases/${RELEASE_ID}/assets?name=${local_name}")"
|
||||
case "$UP_CODE" in
|
||||
201)
|
||||
ASSET_URL="$(jq -r '.browser_download_url' < "$UP_RESP")"
|
||||
log_ok "$local_name"
|
||||
echo "$ASSET_URL"
|
||||
;;
|
||||
*)
|
||||
log_err "上傳 ${local_name} 失敗 (HTTP ${UP_CODE})"
|
||||
cat "$UP_RESP" >&2
|
||||
echo "" >&2
|
||||
FAILED+=("$local_name")
|
||||
;;
|
||||
esac
|
||||
rm -f "$UP_RESP"
|
||||
done
|
||||
|
||||
if [[ ${#FAILED[@]} -gt 0 ]]; then
|
||||
log_err "部分 asset 上傳失敗:${FAILED[*]}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_done "完成"
|
||||
Reference in New Issue
Block a user