#!/bin/bash set -e # Vala SkillHub 自动同步脚本 # 自动检测本地skill变更并推送到SkillHub # 加载配置 CONFIG_FILE="/root/.openclaw/workspace/.vala_skillhub_config" if [ ! -f "${CONFIG_FILE}" ]; then echo "错误:配置文件 ${CONFIG_FILE} 不存在,请先创建配置文件" exit 1 fi source "${CONFIG_FILE}" # 检查必填配置 if [ -z "${GITEA_TOKEN}" ]; then echo "错误:GITEA_TOKEN 未配置,请在 ${CONFIG_FILE} 中填写有效的Gitea API Token" exit 1 fi if [ -z "${SOURCE_NAME}" ]; then echo "错误:SOURCE_NAME 未配置,请在 ${CONFIG_FILE} 中填写当前数字员工名称" exit 1 fi # 配置路径 SKILLS_DIR="/root/.openclaw/workspace/skills" HASH_FILE="/root/.openclaw/workspace/.vala_skill_hashes" TMP_DIR="/root/.openclaw/workspace/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=() 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}") # 跳过use_vala_skillhub自身 if [[ "${skill_name}" == use_vala_skillhub* ]]; 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 "🔄 检测到变更,开始推送..." synced_count=$((synced_count + 1)) 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 echo "📦 远程仓库不存在,创建新仓库:${repo_name}" # 读取skill描述 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}' > /dev/null fi # 复制到临时目录 rm -rf "${TMP_DIR}/${repo_name}" mkdir -p "${TMP_DIR}/${repo_name}" cp -r "${skill_dir}"/* "${TMP_DIR}/${repo_name}/" cp -r "${skill_dir}"/.[!.]* "${TMP_DIR}/${repo_name}/" 2>/dev/null || true # 执行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 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 remote add origin "https://oauth2:${GITEA_TOKEN}@${GITEA_URL#https://}/${GITEA_OWNER}/${repo_name}.git" > /dev/null 2>&1 git push -u origin main --force > /dev/null 2>&1 cd - > /dev/null # 清理临时目录 rm -rf "${TMP_DIR}/${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 "✅ 推送完成:${repo_name}" echo "" done # 输出同步摘要 echo "=== 同步完成 $(date +"%Y-%m-%d %H:%M:%S") ===" echo "本次同步技能数:${synced_count}" if [ ${synced_count} -gt 0 ]; then echo "已同步技能:${synced_skills[*]}" fi echo "跳过无变更技能数:${skipped_count}" echo "" # 如果有变更,返回非0码用于定时任务告警 exit ${synced_count}