Some checks failed
Secrets MCP — Build & Release / 版本 & Release (push) Failing after 2s
Secrets MCP — Build & Release / 质量检查 (fmt / clippy / test) (push) Failing after 2m8s
Secrets MCP — Build & Release / Build Linux (secrets-mcp, musl) (push) Has been skipped
Secrets MCP — Build & Release / 部署 secrets-mcp (push) Has been skipped
Secrets MCP — Build & Release / 发布草稿 Release (push) Has been skipped
Made-with: Cursor
245 lines
9.4 KiB
Bash
Executable File
245 lines
9.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
#
|
||
# 为 refining/secrets 仓库配置 Gitea Actions 所需的 Secrets 和 Variables
|
||
# 参考: .gitea/workflows/secrets.yml
|
||
#
|
||
# 所需配置:
|
||
# - secrets.RELEASE_TOKEN (可选,推荐) Gitea PAT;未配置则工作流跳过 Release 创建与产物上传
|
||
# - vars.WEBHOOK_URL (可选) 飞书通知
|
||
# - vars.DEPLOY_HOST (可选) 部署目标 SSH 主机(IP 或域名)
|
||
# - vars.DEPLOY_USER (可选) SSH 用户名
|
||
# - secrets.DEPLOY_SSH_KEY (可选) SSH 私钥 PEM 全文(原始字符,含 BEGIN/END 行);通过 DEPLOY_SSH_KEY_FILE 写入 API
|
||
#
|
||
# 注意:
|
||
# - Gitea 不允许 secret/variable 名以 GITEA_ 或 GITHUB_ 开头,故使用 RELEASE_TOKEN
|
||
# - Gitea Actions 的 secrets(API 的 data 字段,及网页里粘贴的值)必须是未经 base64 的原始值。
|
||
# 若事先 base64 再写入,工作流里拿到的仍是「一串 base64 文本」,SSH/OpenSSH 无法识别,部署会失败。
|
||
# DEPLOY_SSH_KEY 须与 .pem 文件内容一致:本脚本用 jq --rawfile 按原文上传。
|
||
# - Variables 的 value 字段同样为原始字符串,不要 base64。
|
||
#
|
||
# 用法:
|
||
# 1. 从 ~/.config/gitea/config.env 读取 GITEA_URL, GITEA_TOKEN, GITEA_WEBHOOK_URL
|
||
# 2. 或通过环境变量覆盖: GITEA_TOKEN(作为 RELEASE_TOKEN 的值), WEBHOOK_URL,
|
||
# DEPLOY_HOST, DEPLOY_USER, DEPLOY_SSH_KEY_FILE(部署到 ECS)
|
||
# 3. 凭据勿用 base64;部署私钥路径见 DEPLOY_SSH_KEY_FILE
|
||
#
|
||
|
||
set -e
|
||
|
||
OWNER="refining"
|
||
REPO="secrets"
|
||
|
||
# 解析参数
|
||
while [[ $# -gt 0 ]]; do
|
||
case $1 in
|
||
--from-secrets)
|
||
echo "❌ --from-secrets 尚未实现,请使用 ~/.config/gitea/config.env 或环境变量" >&2
|
||
exit 1
|
||
;;
|
||
-h|--help)
|
||
echo "用法: $0"
|
||
echo ""
|
||
echo "从 ~/.config/gitea/config.env 读取,或由环境变量覆盖。"
|
||
echo ""
|
||
echo "环境变量:"
|
||
echo " GITEA_URL Gitea 实例根地址(可误带尾部 /api/v1,脚本会规范化后拼接)"
|
||
echo " GITEA_TOKEN 用于 Release 的 PAT → secrets.RELEASE_TOKEN"
|
||
echo " WEBHOOK_URL 或 GITEA_WEBHOOK_URL → vars.WEBHOOK_URL(可选)"
|
||
echo " DEPLOY_HOST 部署 SSH 主机(可选,须与下面两项同时设置)"
|
||
echo " DEPLOY_USER 部署 SSH 用户"
|
||
echo " DEPLOY_SSH_KEY_FILE 本地 PEM 路径 → secrets.DEPLOY_SSH_KEY(原文上传,勿 base64)"
|
||
exit 0
|
||
;;
|
||
*)
|
||
echo "❌ 未知参数: $1" >&2
|
||
echo " 使用 $0 --help 查看用法" >&2
|
||
exit 1
|
||
;;
|
||
esac
|
||
done
|
||
|
||
for cmd in curl jq; do
|
||
if ! command -v "$cmd" &>/dev/null; then
|
||
echo "❌ 未找到命令: $cmd(本脚本依赖 curl 与 jq)" >&2
|
||
exit 1
|
||
fi
|
||
done
|
||
|
||
# 加载配置
|
||
load_config() {
|
||
local config="$HOME/.config/gitea/config.env"
|
||
if [[ -f "$config" ]]; then
|
||
# shellcheck source=/dev/null
|
||
source "$config"
|
||
fi
|
||
}
|
||
|
||
load_config
|
||
|
||
# 优先使用环境变量
|
||
if [[ -n "$GITEA_TOKEN" && -z "$GITEA_URL" ]]; then
|
||
echo "❌ 请设置 GITEA_URL (或确保 config.env 中有)" >&2
|
||
exit 1
|
||
fi
|
||
|
||
if [[ -z "$GITEA_URL" ]]; then
|
||
echo "❌ GITEA_URL 未配置"
|
||
echo " 请创建 ~/.config/gitea/config.env 或设置环境变量" >&2
|
||
exit 1
|
||
fi
|
||
|
||
# 规范为实例根 URL:去尾部斜杠,并去掉重复的 .../api/v1 后缀(避免拼成 .../api/v1/api/v1)
|
||
GITEA_URL="${GITEA_URL%/}"
|
||
while [[ "$GITEA_URL" == */api/v1 ]]; do
|
||
GITEA_URL="${GITEA_URL%/api/v1}"
|
||
GITEA_URL="${GITEA_URL%/}"
|
||
done
|
||
|
||
API_BASE="${GITEA_URL}/api/v1"
|
||
|
||
# 获取 GITEA_TOKEN(作为 workflow 中 secrets.RELEASE_TOKEN 的值)
|
||
if [[ -z "$GITEA_TOKEN" ]]; then
|
||
echo "❌ GITEA_TOKEN 未配置"
|
||
echo " 在 ~/.config/gitea/config.env 中设置,或 export GITEA_TOKEN=xxx" >&2
|
||
echo " Token 需具备 repo 写权限(创建 Release、上传附件)" >&2
|
||
exit 1
|
||
fi
|
||
|
||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
echo "配置 Gitea Actions: $OWNER/$REPO"
|
||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
echo ""
|
||
|
||
# 1. 创建 Secret: RELEASE_TOKEN(data = PAT 原文,勿 base64)
|
||
echo "1. 创建 Secret: RELEASE_TOKEN"
|
||
secret_payload=$(jq -n --arg t "$GITEA_TOKEN" '{data: $t}')
|
||
resp=$(curl -s -w "\n%{http_code}" -X PUT \
|
||
-H "Authorization: token $GITEA_TOKEN" \
|
||
-H "Content-Type: application/json" \
|
||
-d "$secret_payload" \
|
||
"${API_BASE}/repos/${OWNER}/${REPO}/actions/secrets/RELEASE_TOKEN")
|
||
http_code=$(echo "$resp" | tail -n1)
|
||
body=$(echo "$resp" | sed '$d')
|
||
|
||
if [[ "$http_code" == "200" || "$http_code" == "201" || "$http_code" == "204" ]]; then
|
||
echo " ✓ RELEASE_TOKEN 已创建/更新"
|
||
else
|
||
echo " ❌ 失败 (HTTP $http_code)" >&2
|
||
echo "$body" | jq -r '.message // .' 2>/dev/null || echo "$body" >&2
|
||
exit 1
|
||
fi
|
||
|
||
# 2. 创建/更新 Variable: WEBHOOK_URL(可选,value 为原始 URL 字符串,勿 base64)
|
||
WEBHOOK_VALUE="${WEBHOOK_URL:-$GITEA_WEBHOOK_URL}"
|
||
if [[ -n "$WEBHOOK_VALUE" ]]; then
|
||
echo ""
|
||
echo "2. 创建/更新 Variable: WEBHOOK_URL"
|
||
var_payload=$(jq -n --arg v "$WEBHOOK_VALUE" '{value: $v}')
|
||
resp=$(curl -s -w "\n%{http_code}" -X POST \
|
||
-H "Authorization: token $GITEA_TOKEN" \
|
||
-H "Content-Type: application/json" \
|
||
-d "$var_payload" \
|
||
"${API_BASE}/repos/${OWNER}/${REPO}/actions/variables/WEBHOOK_URL")
|
||
http_code=$(echo "$resp" | tail -n1)
|
||
body=$(echo "$resp" | sed '$d')
|
||
|
||
if [[ "$http_code" == "200" || "$http_code" == "201" || "$http_code" == "204" ]]; then
|
||
echo " ✓ WEBHOOK_URL 已创建/更新"
|
||
elif [[ "$http_code" == "409" ]]; then
|
||
# 变量已存在,用 PUT 更新
|
||
resp=$(curl -s -w "\n%{http_code}" -X PUT \
|
||
-H "Authorization: token $GITEA_TOKEN" \
|
||
-H "Content-Type: application/json" \
|
||
-d "$var_payload" \
|
||
"${API_BASE}/repos/${OWNER}/${REPO}/actions/variables/WEBHOOK_URL")
|
||
http_code=$(echo "$resp" | tail -n1)
|
||
if [[ "$http_code" == "200" || "$http_code" == "204" ]]; then
|
||
echo " ✓ WEBHOOK_URL 已更新"
|
||
else
|
||
echo " ⚠ 更新失败 (HTTP $http_code)" >&2
|
||
fi
|
||
else
|
||
echo " ⚠ 失败 (HTTP $http_code),飞书通知将不可用" >&2
|
||
fi
|
||
else
|
||
echo ""
|
||
echo "2. 跳过 WEBHOOK_URL(未配置 GITEA_WEBHOOK_URL 或 WEBHOOK_URL)"
|
||
echo " 飞书通知将不可用;如需可后续在仓库 Settings → Variables 中添加"
|
||
fi
|
||
|
||
# 3. 部署用 Variable + Secret(与 .gitea/workflows/secrets.yml 中 deploy-mcp 一致)
|
||
upsert_repo_variable() {
|
||
local var_name="$1" var_value="$2"
|
||
local var_payload http_code body resp
|
||
var_payload=$(jq -n --arg v "$var_value" '{value: $v}')
|
||
resp=$(curl -s -w "\n%{http_code}" -X POST \
|
||
-H "Authorization: token $GITEA_TOKEN" \
|
||
-H "Content-Type: application/json" \
|
||
-d "$var_payload" \
|
||
"${API_BASE}/repos/${OWNER}/${REPO}/actions/variables/${var_name}")
|
||
http_code=$(echo "$resp" | tail -n1)
|
||
if [[ "$http_code" == "200" || "$http_code" == "201" || "$http_code" == "204" ]]; then
|
||
return 0
|
||
fi
|
||
if [[ "$http_code" == "409" ]]; then
|
||
resp=$(curl -s -w "\n%{http_code}" -X PUT \
|
||
-H "Authorization: token $GITEA_TOKEN" \
|
||
-H "Content-Type: application/json" \
|
||
-d "$var_payload" \
|
||
"${API_BASE}/repos/${OWNER}/${REPO}/actions/variables/${var_name}")
|
||
http_code=$(echo "$resp" | tail -n1)
|
||
[[ "$http_code" == "200" || "$http_code" == "204" ]]
|
||
return
|
||
fi
|
||
body=$(echo "$resp" | sed '$d')
|
||
echo " ❌ 变量 ${var_name} 失败 (HTTP $http_code)" >&2
|
||
echo "$body" | jq -r '.message // .' 2>/dev/null || echo "$body" >&2
|
||
return 1
|
||
}
|
||
|
||
if [[ -n "$DEPLOY_HOST" && -n "$DEPLOY_USER" && -n "$DEPLOY_SSH_KEY_FILE" ]]; then
|
||
echo ""
|
||
echo "3. 部署目标: vars.DEPLOY_HOST / vars.DEPLOY_USER + secrets.DEPLOY_SSH_KEY"
|
||
if [[ ! -f "$DEPLOY_SSH_KEY_FILE" ]]; then
|
||
echo " ❌ DEPLOY_SSH_KEY_FILE 不是文件: $DEPLOY_SSH_KEY_FILE" >&2
|
||
exit 1
|
||
fi
|
||
upsert_repo_variable DEPLOY_HOST "$DEPLOY_HOST" || exit 1
|
||
echo " ✓ DEPLOY_HOST"
|
||
upsert_repo_variable DEPLOY_USER "$DEPLOY_USER" || exit 1
|
||
echo " ✓ DEPLOY_USER"
|
||
# PEM 原文写入 secret.data;勿对文件先做 base64,否则 runner 侧 ssh 无法解析密钥
|
||
secret_payload=$(jq -n --rawfile k "$DEPLOY_SSH_KEY_FILE" '{data: $k}')
|
||
resp=$(curl -s -w "\n%{http_code}" -X PUT \
|
||
-H "Authorization: token $GITEA_TOKEN" \
|
||
-H "Content-Type: application/json" \
|
||
-d "$secret_payload" \
|
||
"${API_BASE}/repos/${OWNER}/${REPO}/actions/secrets/DEPLOY_SSH_KEY")
|
||
http_code=$(echo "$resp" | tail -n1)
|
||
body=$(echo "$resp" | sed '$d')
|
||
if [[ "$http_code" == "200" || "$http_code" == "201" || "$http_code" == "204" ]]; then
|
||
echo " ✓ DEPLOY_SSH_KEY"
|
||
else
|
||
echo " ❌ DEPLOY_SSH_KEY 失败 (HTTP $http_code)" >&2
|
||
echo "$body" | jq -r '.message // .' 2>/dev/null || echo "$body" >&2
|
||
exit 1
|
||
fi
|
||
else
|
||
echo ""
|
||
echo "3. 跳过部署配置(需同时设置 DEPLOY_HOST、DEPLOY_USER、DEPLOY_SSH_KEY_FILE)"
|
||
fi
|
||
|
||
echo ""
|
||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
echo "✓ 配置完成"
|
||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
echo ""
|
||
echo "Workflow 将使用:"
|
||
echo " - secrets.RELEASE_TOKEN 创建 Release 并上传二进制"
|
||
echo " - vars.WEBHOOK_URL 发送飞书通知(如已配置)"
|
||
echo " - vars.DEPLOY_* / secrets.DEPLOY_SSH_KEY deploy-mcp(如已配置)"
|
||
echo ""
|
||
echo "推送代码触发构建:"
|
||
echo " git push origin main"
|
||
echo ""
|