115 lines
4.2 KiB
Bash
Executable File
115 lines
4.2 KiB
Bash
Executable File
#!/bin/bash
|
||
# Vala内部SkillHub自动同步脚本
|
||
source /root/.openclaw/workspace-xiaoyan/.vala_skillhub_config
|
||
WORK_DIR="/root/.openclaw/workspace-xiaoyan"
|
||
HASH_FILE="${WORK_DIR}/.vala_skill_hashes"
|
||
LOG_FILE="/tmp/skill_sync.log"
|
||
SYNCED_SKILLS=()
|
||
SKIPPED_SKILLS=()
|
||
|
||
cd "$WORK_DIR" || exit 1
|
||
|
||
# 计算技能目录哈希
|
||
compute_skill_hash() {
|
||
local skill_dir="$1"
|
||
(cd "${skill_dir}" && find . -type f -not -path '*/\.*' | LC_ALL=C sort | while read f; do echo "FILE:$f"; cat "$f"; done | sha256sum | awk '{print $1}')
|
||
}
|
||
|
||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 开始同步技能到内部SkillHub..." > "$LOG_FILE"
|
||
touch "${HASH_FILE}"
|
||
|
||
# 遍历所有技能目录
|
||
for skill_dir in ./skills/*/; do
|
||
skill_name=$(basename "${skill_dir}")
|
||
|
||
# 跳过use_vala_skillhub自身
|
||
if [ "${skill_name}" = "use_vala_skillhub" ]; then
|
||
continue
|
||
fi
|
||
|
||
# 计算当前哈希
|
||
current_hash=$(compute_skill_hash "${skill_dir}")
|
||
# 读取上次推送的哈希
|
||
stored_hash=$(grep "^${skill_name} " "${HASH_FILE}" | awk '{print $2}' || echo "")
|
||
|
||
if [ "${current_hash}" = "${stored_hash}" ]; then
|
||
SKIPPED_SKILLS+=("${skill_name}")
|
||
echo "[skip] ${skill_name} — 无变更" >> "$LOG_FILE"
|
||
continue
|
||
fi
|
||
|
||
echo "[sync] ${skill_name} — 检测到变更,开始推送..." >> "$LOG_FILE"
|
||
SYNCED_SKILLS+=("${skill_name}")
|
||
repo_name="${skill_name}.${SOURCE_NAME}"
|
||
|
||
# 检查远程仓库是否存在
|
||
http_code=$(curl -s -o /dev/null -w "%{http_code}" \
|
||
"${GITEA_URL}/api/v1/repos/${GITEA_OWNER}/${repo_name}" \
|
||
-H "Authorization: token ${GITEA_TOKEN}")
|
||
|
||
# 不存在则创建仓库
|
||
if [ "${http_code}" = "404" ]; then
|
||
desc=""
|
||
if [ -f "${skill_dir}/skill.json" ]; then
|
||
desc=$(cat "${skill_dir}/skill.json" | grep '"description"' | head -1 | sed 's/.*"description"[[:space:]]*:[[:space:]]*"\(.*\)".*/\1/')
|
||
fi
|
||
curl -s -X POST "${GITEA_URL}/api/v1/orgs/${GITEA_OWNER}/repos" \
|
||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"name": "'"${repo_name}"'", "private": false, "description": "'"${desc}"'", "auto_init": false}' >> "$LOG_FILE" 2>&1
|
||
fi
|
||
|
||
# 复制到临时目录并推送
|
||
rm -rf ./tmp/skill_push/${repo_name}
|
||
mkdir -p ./tmp/skill_push/${repo_name}
|
||
cp -r ${skill_dir}* ./tmp/skill_push/${repo_name}/
|
||
cp -r ${skill_dir}.[!.]* ./tmp/skill_push/${repo_name}/ 2>/dev/null || true
|
||
|
||
cd ./tmp/skill_push/${repo_name}
|
||
git init >> "$LOG_FILE" 2>&1
|
||
git config user.name "xiaoyan-bot" >> "$LOG_FILE" 2>&1
|
||
git config user.email "bot@valavala.com" >> "$LOG_FILE" 2>&1
|
||
git checkout -b main >> "$LOG_FILE" 2>&1
|
||
git add -A >> "$LOG_FILE" 2>&1
|
||
git commit -m "auto-sync: ${skill_name} $(date +%Y-%m-%d_%H:%M)" >> "$LOG_FILE" 2>&1
|
||
git remote add origin "https://oauth2:${GITEA_TOKEN}@${GITEA_URL#https://}/${GITEA_OWNER}/${repo_name}.git" >> "$LOG_FILE" 2>&1
|
||
git push -u origin main --force >> "$LOG_FILE" 2>&1
|
||
cd "$WORK_DIR"
|
||
|
||
# 清理临时目录
|
||
rm -rf ./tmp/skill_push/${repo_name}
|
||
|
||
# 更新哈希状态
|
||
grep -v "^${skill_name} " "${HASH_FILE}" > "${HASH_FILE}.tmp" || true
|
||
echo "${skill_name} ${current_hash}" >> "${HASH_FILE}.tmp"
|
||
mv "${HASH_FILE}.tmp" "${HASH_FILE}"
|
||
|
||
echo "[done] ${skill_name} — 推送完成" >> "$LOG_FILE"
|
||
done
|
||
|
||
# 有同步成功的技能,发消息通知李若松
|
||
if [ ${#SYNCED_SKILLS[@]} -gt 0 ]; then
|
||
APP_ID=$(jq -r '.apps[0].appId' /root/.openclaw/credentials/xiaoyan/config.json)
|
||
APP_SECRET=$(jq -r '.apps[0].appSecret' /root/.openclaw/credentials/xiaoyan/config.json)
|
||
TOKEN=$(curl -s -X POST "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" \
|
||
-H "Content-Type: application/json" \
|
||
-d "{\"app_id\":\"$APP_ID\",\"app_secret\":\"$APP_SECRET\"}" \
|
||
| jq -r '.tenant_access_token')
|
||
|
||
MSG_CONTENT="✅ 技能同步到内部SkillHub成功:
|
||
本次推送技能:${SYNCED_SKILLS[*]}
|
||
跳过无变更技能:${SKIPPED_SKILLS[*]}
|
||
同步日志:$(cat "$LOG_FILE")"
|
||
|
||
curl -s -X POST "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=user_id" \
|
||
-H "Authorization: Bearer $TOKEN" \
|
||
-H "Content-Type: application/json" \
|
||
-d "{
|
||
\"receive_id\": \"4aagb443\",
|
||
\"msg_type\": \"text\",
|
||
\"content\": \"{\\\"text\\\":\\\"${MSG_CONTENT//\\\"/\\\\\\\"}\\\"}\"
|
||
}" > /dev/null 2>&1
|
||
fi
|
||
|
||
exit 0
|