ai_member_xiaokui/scripts/sync_skill_to_skillhub.sh
2026-04-11 08:10:01 +08:00

158 lines
5.5 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# Vala SkillHub 自动同步脚本 - 遵循use_vala_skillhub.vala技能规范
# 自动检测本地skill变更自动创建远程仓库推送到对应${skill_name}.xiaokui仓库
set -e
# 加载配置文件
CONFIG_FILE="/root/.openclaw/workspace-xiaokui/.vala_skillhub_config"
if [ ! -f "${CONFIG_FILE}" ]; then
echo "错误:配置文件 ${CONFIG_FILE} 不存在,请先创建配置文件"
exit 1
fi
source "${CONFIG_FILE}"
# 检查必填配置
if [ -z "${GITEA_TOKEN}" ] || [ -z "${SOURCE_NAME}" ] || [ -z "${GITEA_URL}" ] || [ -z "${GITEA_OWNER}" ]; then
echo "错误:配置项缺失,请检查${CONFIG_FILE}中所有配置项是否填写完整"
exit 1
fi
# 配置路径
SKILLS_DIR="/root/.openclaw/workspace-xiaokui/skills"
HASH_FILE="/root/.openclaw/workspace-xiaokui/.vala_skill_hashes"
TMP_DIR="/root/.openclaw/workspace-xiaokui/tmp/skill_push"
# 创建必要目录
mkdir -p "${TMP_DIR}"
touch "${HASH_FILE}"
# 计算skill目录哈希函数校验变更用
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}')
}
# 统计变量
synced_count=0
skipped_count=0
synced_skills=()
failed_skills=()
echo "=== Vala SkillHub 自动同步开始 $(date +"%Y-%m-%d %H:%M:%S") ==="
echo "当前数字员工:${SOURCE_NAME}"
echo "SkillHub地址${GITEA_URL}/${GITEA_OWNER}"
echo ""
# 遍历所有skill目录
for skill_dir in "${SKILLS_DIR}"/*/; do
skill_name=$(basename "${skill_dir}")
# 跳过非技能目录:.git、logs、符号链接、无SKILL.md的目录
if [[ "${skill_name}" == ".git" ]] || [[ "${skill_name}" == "logs" ]] || [ -L "${skill_dir%/}" ] || [ ! -f "${skill_dir}/SKILL.md" ]; then
continue
fi
echo "检查技能:${skill_name}"
# 计算当前哈希
current_hash=$(compute_skill_hash "${skill_dir}")
# 读取上次推送的哈希
stored_hash=$(grep "^${skill_name} " "${HASH_FILE}" | awk '{print $2}' || true)
if [ "${current_hash}" = "${stored_hash}" ]; then
echo "✅ 无变更,跳过推送"
skipped_count=$((skipped_count + 1))
echo ""
continue
fi
echo "🔄 检测到变更,开始推送..."
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
echo "📦 远程仓库不存在,自动创建新仓库:${repo_name}"
# 从SKILL.md提取描述
desc=""
if [ -f "${skill_dir}/SKILL.md" ]; then
desc=$(grep -A5 "description:" "${skill_dir}/SKILL.md" | head -3 | tr '\n' ' ' | sed 's/.*description:[[:space:]]*//g' | sed 's/---.*//g' | sed 's/"/\\"/g' | cut -c 1-200)
fi
# 调用Gitea API创建仓库
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}' > /dev/null
sleep 2 # 等待仓库创建完成
fi
# 复制到临时目录处理避免污染本地skill目录
rm -rf "${TMP_DIR}/${repo_name}"
mkdir -p "${TMP_DIR}/${repo_name}"
# 排除.git目录
rsync -a --exclude '.git' "${skill_dir}" "${TMP_DIR}/${repo_name}/"
# 执行Git推送
cd "${TMP_DIR}/${repo_name}"
git init > /dev/null 2>&1
git checkout -b main > /dev/null 2>&1
git config user.name "OpenClaw Skill Sync Bot"
git config user.email "bot@valavala.com"
git add -A > /dev/null 2>&1
git commit -m "auto-sync: ${skill_name} $(date +%Y-%m-%d_%H:%M)" > /dev/null 2>&1
# 注意Git认证使用oauth2:前缀格式
git remote add origin "https://oauth2:${GITEA_TOKEN}@${GITEA_URL#https://}/${GITEA_OWNER}/${repo_name}.git" > /dev/null 2>&1
# 推送,失败则记录
if git push -u origin main --force > /tmp/sync_${skill_name}.log 2>&1; then
synced_count=$((synced_count + 1))
synced_skills+=("${skill_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 "✅ 推送完成:${repo_name}"
else
error_msg=$(cat /tmp/sync_${skill_name}.log)
failed_skills+=("${skill_name}: ${error_msg}")
echo "❌ 推送失败:${error_msg}"
fi
cd - > /dev/null
rm -rf "${TMP_DIR}/${repo_name}"
echo ""
done
# 输出同步摘要
echo "=== 同步完成 $(date +"%Y-%m-%d %H:%M:%S") ==="
echo "本次同步成功技能数:${synced_count}"
echo "跳过无变更技能数:${skipped_count}"
echo "推送失败技能数:${#failed_skills[@]}"
echo ""
# 发送通知
if [ ${synced_count} -gt 0 ] || [ ${#failed_skills[@]} -gt 0 ]; then
message=""
if [ ${synced_count} -gt 0 ]; then
message="${message}✅ 同步成功技能:${synced_skills[*]}\n"
fi
if [ ${#failed_skills[@]} -gt 0 ]; then
message="${message}❌ 同步失败技能:\n$(printf "%s\n" "${failed_skills[@]}")"
fi
# 给李若松发送通知
/root/.nvm/versions/node/v24.14.0/bin/openclaw message send --channel feishu --target "user:ou_088ee79216826be4a24af44f7268f880" --message "$(echo -e "SkillHub同步结果\n${message}")"
fi
# 清理临时文件
rm -rf "${TMP_DIR}"
# 有失败技能则返回非0
exit ${#failed_skills[@]}