Transform Plugin Data #678
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Transform Plugin Data | |
on: | |
schedule: | |
# 每小时执行一次 (UTC时间) | |
- cron: '0 * * * *' | |
workflow_dispatch: # 允许手动触发 | |
permissions: | |
contents: write | |
actions: read | |
jobs: | |
transform-data: | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout repository | |
uses: actions/checkout@v4 | |
with: | |
token: ${{ secrets.PAT_TOKEN }} | |
fetch-depth: 0 | |
- name: Configure Git | |
run: | | |
git config --local user.email "[email protected]" | |
git config --local user.name "GitHub Action" | |
echo "✅ Git 配置完成" | |
- name: Fetch original plugin data | |
id: fetch-data | |
run: | | |
echo "开始获取原始插件数据..." | |
echo "当前工作目录: $(pwd)" | |
echo "PAT_TOKEN 权限检查..." | |
if [ -n "${{ secrets.PAT_TOKEN }}" ]; then | |
echo "✓ PAT_TOKEN 已设置" | |
else | |
echo "✗ PAT_TOKEN 未设置" | |
fi | |
# 创建临时文件存储响应和HTTP状态码 | |
temp_response="temp_response.txt" | |
temp_headers="temp_headers.txt" | |
# 获取GitHub原始文件内容 | |
github_url="https://raw.githubusercontent.com/AstrBotDevs/AstrBot_Plugins_Collection/main/plugins.json" | |
# 使用curl获取数据,添加-L参数自动跟随重定向,增加重定向限制 | |
http_code=$(curl -L -s --max-time 30 --retry 3 --retry-delay 5 \ | |
--max-redirs 10 \ | |
-H "Authorization: token ${{ secrets.PAT_TOKEN }}" \ | |
-H "User-Agent: GitHub-Action-Plugin-Transformer" \ | |
-H "Accept: application/json" \ | |
-w "%{http_code}" \ | |
-D "$temp_headers" \ | |
-o "$temp_response" \ | |
"$github_url") | |
curl_exit_code=$? | |
# 检查curl命令是否执行成功 | |
if [ $curl_exit_code -ne 0 ]; then | |
echo "❌ 网络请求失败,curl退出码: $curl_exit_code" | |
case $curl_exit_code in | |
5) echo "无法解析代理" ;; | |
6) echo "无法解析主机名" ;; | |
7) echo "无法连接到服务器" ;; | |
28) echo "请求超时" ;; | |
35) echo "SSL连接错误" ;; | |
47) echo "重定向次数过多" ;; | |
*) echo "其他网络错误" ;; | |
esac | |
echo "should_update=false" >> $GITHUB_OUTPUT | |
rm -f "$temp_response" "$temp_headers" | |
exit 0 | |
fi | |
echo "HTTP状态码: $http_code" | |
# 检查是否发生了重定向 | |
if [ -f "$temp_headers" ]; then | |
redirect_count=$(grep -c "^HTTP/" "$temp_headers" || echo "1") | |
if [ "$redirect_count" -gt 1 ]; then | |
echo "ℹ️ 检测到重定向,共发生 $((redirect_count - 1)) 次重定向" | |
# 显示重定向链 | |
echo "重定向详情:" | |
grep -E "^(HTTP/|Location:)" "$temp_headers" | head -10 | |
fi | |
fi | |
# 检查HTTP状态码 | |
if [ "$http_code" -ne 200 ]; then | |
echo "❌ 最终返回非200状态码: $http_code" | |
case $http_code in | |
301) echo "永久重定向 (301 Moved Permanently) - 可能需要更新URL" ;; | |
302) echo "临时重定向 (302 Found)" ;; | |
404) echo "文件不存在或仓库不可访问 (404 Not Found)" ;; | |
403) echo "访问被拒绝,可能是API限制 (403 Forbidden)" ;; | |
500) echo "GitHub服务器内部错误 (500 Internal Server Error)" ;; | |
*) echo "HTTP错误状态码: $http_code" ;; | |
esac | |
echo "should_update=false" >> $GITHUB_OUTPUT | |
rm -f "$temp_response" "$temp_headers" | |
exit 0 | |
fi | |
# 读取响应内容 | |
if [ ! -f "$temp_response" ]; then | |
echo "❌ 响应文件不存在" | |
echo "should_update=false" >> $GITHUB_OUTPUT | |
exit 0 | |
fi | |
response=$(cat "$temp_response") | |
# 检查响应是否为空 | |
if [ -z "$response" ] || [ "$response" = "" ]; then | |
echo "❌ 获取到的响应为空,跳过更新" | |
echo "should_update=false" >> $GITHUB_OUTPUT | |
rm -f "$temp_response" "$temp_headers" | |
exit 0 | |
fi | |
# 检查响应大小 | |
response_size=$(wc -c < "$temp_response") | |
if [ "$response_size" -lt 50 ]; then | |
echo "❌ 响应内容过小 ($response_size 字节),可能是错误响应" | |
echo "should_update=false" >> $GITHUB_OUTPUT | |
rm -f "$temp_response" "$temp_headers" | |
exit 0 | |
fi | |
# 检查是否为有效的JSON | |
if ! echo "$response" | jq . > /dev/null 2>&1; then | |
echo "❌ 响应不是有效的JSON格式,跳过更新" | |
echo "Content preview: $(echo "$response" | head -c 200)" | |
echo "should_update=false" >> $GITHUB_OUTPUT | |
rm -f "$temp_response" "$temp_headers" | |
exit 0 | |
fi | |
# 检查JSON是否为空对象或空数组 | |
if [ "$response" = "{}" ] || [ "$response" = "[]" ] || [ "$response" = "null" ]; then | |
echo "❌ 获取到空的JSON数据,跳过更新" | |
echo "should_update=false" >> $GITHUB_OUTPUT | |
rm -f "$temp_response" "$temp_headers" | |
exit 0 | |
fi | |
# 保存原始数据到临时文件 | |
echo "$response" > original_plugins.json | |
echo "should_update=true" >> $GITHUB_OUTPUT | |
echo "✅ 成功获取原始插件数据 ($response_size 字节)" | |
# 清理临时文件 | |
rm -f "$temp_response" "$temp_headers" | |
- name: Load existing cache for fallback | |
if: steps.fetch-data.outputs.should_update == 'true' | |
id: load-cache | |
run: | | |
echo "检查现有缓存文件..." | |
if [ -f plugin_cache_original.json ]; then | |
echo "发现现有缓存文件,将用作回退数据" | |
cp plugin_cache_original.json existing_cache.json | |
echo "has_existing_cache=true" >> $GITHUB_OUTPUT | |
else | |
echo "没有现有缓存文件" | |
echo "has_existing_cache=false" >> $GITHUB_OUTPUT | |
fi | |
- name: Get GitHub API info for repositories | |
if: steps.fetch-data.outputs.should_update == 'true' | |
id: get-repo-info | |
run: | | |
echo "开始获取仓库信息..." | |
# 创建一个临时文件存储仓库信息 | |
echo "{}" > repo_info.json | |
# 初始化统计计数器 | |
total_repos=0 | |
success_count=0 | |
failed_count=0 | |
deleted_count=0 | |
network_error_count=0 | |
redirect_count=0 | |
# 重试配置 | |
MAX_RETRIES=5 | |
BASE_DELAY=2 | |
MAX_DELAY=30 | |
# 重试函数 | |
retry_api_call() { | |
local owner="$1" | |
local repo="$2" | |
local attempt="$3" | |
# 计算退避延迟 (指数退避 + 随机抖动) | |
local delay=$((BASE_DELAY * (2 ** (attempt - 1)))) | |
if [ $delay -gt $MAX_DELAY ]; then | |
delay=$MAX_DELAY | |
fi | |
# 添加随机抖动 (0-50% 的延迟时间) | |
local jitter=$((RANDOM % (delay / 2 + 1))) | |
delay=$((delay + jitter)) | |
echo " 第 $attempt 次尝试 (延迟 ${delay}s)..." | |
sleep $delay | |
# 使用临时文件捕获响应头 | |
local temp_headers="temp_api_headers_${total_repos}_${attempt}.txt" | |
# 执行API调用,增强网络配置 | |
local response=$(curl -L -s \ | |
--max-time 20 \ | |
--connect-timeout 10 \ | |
--retry 0 \ | |
--max-redirs 5 \ | |
--keepalive-time 60 \ | |
--tcp-nodelay \ | |
-H "Authorization: token ${{ secrets.PAT_TOKEN }}" \ | |
-H "Accept: application/vnd.github.v3+json" \ | |
-H "User-Agent: GitHub-Action-Plugin-Transformer" \ | |
-H "Connection: keep-alive" \ | |
-D "$temp_headers" \ | |
-w "HTTPSTATUS:%{http_code}:CURL_EXIT:%{exitcode}" \ | |
"https://api.github.com/repos/$owner/$repo" 2>/dev/null || echo "CURL_ERROR:-1") | |
# 解析响应 | |
if [[ "$response" == "CURL_ERROR"* ]]; then | |
rm -f "$temp_headers" | |
return 1 | |
fi | |
# 提取状态码和curl退出码 | |
local http_code=$(echo "$response" | grep -o "HTTPSTATUS:[0-9]*" | cut -d: -f2) | |
local curl_exit=$(echo "$response" | grep -o "CURL_EXIT:[0-9]*" | cut -d: -f2) | |
local body=$(echo "$response" | sed 's/HTTPSTATUS:[0-9]*:CURL_EXIT:[0-9]*$//') | |
# 检查curl退出码 | |
if [ "$curl_exit" != "0" ]; then | |
echo " CURL错误码: $curl_exit" | |
rm -f "$temp_headers" | |
return 1 | |
fi | |
# 检查HTTP状态码是否需要重试 | |
case "$http_code" in | |
200) | |
# 验证响应是否为有效JSON | |
if echo "$body" | jq -e '.stargazers_count' > /dev/null 2>&1; then | |
echo "$body" | |
rm -f "$temp_headers" | |
return 0 | |
else | |
echo " 响应不是有效JSON" | |
rm -f "$temp_headers" | |
return 1 | |
fi | |
;; | |
429|502|503|504) | |
# 这些状态码应该重试 | |
echo " 临时错误 HTTP $http_code,将重试" | |
rm -f "$temp_headers" | |
return 1 | |
;; | |
301|302|404|403) | |
# 这些状态码不应该重试,直接返回 | |
echo "$body:HTTP:$http_code" | |
rm -f "$temp_headers" | |
return 0 | |
;; | |
*) | |
echo " 未知HTTP状态码: $http_code" | |
rm -f "$temp_headers" | |
return 1 | |
;; | |
esac | |
} | |
# 从原始数据中提取所有仓库URL | |
jq -r 'to_entries[] | .value.repo // empty' original_plugins.json | while read -r repo_url; do | |
# 提取GitHub用户名和仓库名 | |
if [[ "$repo_url" =~ https://github\.com/([^/]+)/([^/]+) ]]; then | |
owner="${BASH_REMATCH[1]}" | |
repo="${BASH_REMATCH[2]}" | |
total_repos=$((total_repos + 1)) | |
echo "[$total_repos] 获取仓库信息: $owner/$repo" | |
# 执行重试逻辑 | |
api_response="" | |
success=false | |
for attempt in $(seq 1 $MAX_RETRIES); do | |
if [ $attempt -eq 1 ]; then | |
echo " 初次尝试..." | |
# 第一次尝试,无延迟 | |
temp_headers="temp_api_headers_${total_repos}_1.txt" | |
api_response=$(curl -L -s \ | |
--max-time 15 \ | |
--connect-timeout 8 \ | |
--retry 0 \ | |
--max-redirs 5 \ | |
-H "Authorization: token ${{ secrets.PAT_TOKEN }}" \ | |
-H "Accept: application/vnd.github.v3+json" \ | |
-H "User-Agent: GitHub-Action-Plugin-Transformer" \ | |
-D "$temp_headers" \ | |
-w "HTTPSTATUS:%{http_code}" \ | |
"https://api.github.com/repos/$owner/$repo" 2>/dev/null || echo "CURL_ERROR") | |
if [[ "$api_response" != "CURL_ERROR" ]]; then | |
http_code=$(echo "$api_response" | grep -o "HTTPSTATUS:[0-9]*" | cut -d: -f2) | |
api_response=$(echo "$api_response" | sed 's/HTTPSTATUS:[0-9]*$//') | |
# 检查是否成功或不需要重试的错误 | |
case "$http_code" in | |
200) | |
if echo "$api_response" | jq -e '.stargazers_count' > /dev/null 2>&1; then | |
success=true | |
break | |
fi | |
;; | |
301|302|404|403) | |
# 不需要重试的状态码 | |
success=true | |
break | |
;; | |
429|502|503|504) | |
# 需要重试的状态码 | |
echo " 临时错误 HTTP $http_code,准备重试" | |
;; | |
esac | |
fi | |
rm -f "$temp_headers" | |
else | |
# 重试调用 | |
retry_response=$(retry_api_call "$owner" "$repo" "$attempt") | |
if [ $? -eq 0 ]; then | |
api_response="$retry_response" | |
success=true | |
break | |
fi | |
fi | |
# 如果不是最后一次尝试,显示重试信息 | |
if [ $attempt -lt $MAX_RETRIES ]; then | |
echo " 尝试 $attempt/$MAX_RETRIES 失败,准备重试..." | |
fi | |
done | |
# 处理最终结果 | |
stars=0 | |
updated_at="" | |
version="" | |
status="unknown" | |
if [ "$success" = true ]; then | |
# 检查是否包含HTTP状态码信息 | |
if [[ "$api_response" == *":HTTP:"* ]]; then | |
http_code=$(echo "$api_response" | grep -o ":HTTP:[0-9]*" | cut -d: -f3) | |
api_response=$(echo "$api_response" | sed 's/:HTTP:[0-9]*$//') | |
fi | |
case "$http_code" in | |
200) | |
if echo "$api_response" | jq -e '.stargazers_count' > /dev/null 2>&1; then | |
stars=$(echo "$api_response" | jq -r '.stargazers_count // 0') | |
updated_at=$(echo "$api_response" | jq -r '.updated_at // ""') | |
success_count=$((success_count + 1)) | |
status="success" | |
echo " ✅ 成功 - Stars: $stars, 更新时间: $updated_at" | |
# 获取metadata版本 | |
for metadata_file in "metadata.yml" "metadata.yaml"; do | |
metadata_response=$(curl -L -s --max-time 10 --max-redirs 3 \ | |
-H "Authorization: token ${{ secrets.PAT_TOKEN }}" \ | |
-H "Accept: application/vnd.github.v3.raw" \ | |
-H "User-Agent: GitHub-Action-Plugin-Transformer" \ | |
"https://api.github.com/repos/$owner/$repo/contents/$metadata_file" 2>/dev/null || echo "{}") | |
if [[ ! "$metadata_response" =~ "Not Found" ]] && [[ ! "$metadata_response" =~ "Bad Gateway" ]]; then | |
# 检查是否是base64编码的内容 | |
if echo "$metadata_response" | jq -e '.content' > /dev/null 2>&1; then | |
metadata_content=$(echo "$metadata_response" | jq -r '.content' | base64 -d 2>/dev/null || echo "") | |
else | |
metadata_content="$metadata_response" | |
fi | |
# 尝试解析YAML并提取版本 | |
if [ ! -z "$metadata_content" ]; then | |
parsed_version=$(echo "$metadata_content" | grep -E "^version:\s*['\"]?([^'\"]+)['\"]?" | sed -E "s/version:\s*['\"]?([^'\"]+)['\"]?/\1/" || echo "") | |
# 去除注释和多余的空白字符 | |
cleaned_version=$(echo "$parsed_version" | sed -E 's/[#].*$//' | sed -E 's/\r$//' | xargs) | |
if [ ! -z "$cleaned_version" ]; then | |
version="$cleaned_version" | |
break | |
fi | |
fi | |
fi | |
done | |
fi | |
;; | |
301|302) | |
echo " 🔄 仓库重定向 ($http_code)" | |
redirect_count=$((redirect_count + 1)) | |
status="redirected" | |
;; | |
404) | |
echo " 🗑️ 仓库已删除或不可访问 (404)" | |
deleted_count=$((deleted_count + 1)) | |
status="deleted" | |
;; | |
403) | |
echo " ⚠️ API限制或访问被拒绝 (403)" | |
failed_count=$((failed_count + 1)) | |
status="api_limit" | |
;; | |
esac | |
else | |
echo " ❌ 所有重试均失败" | |
network_error_count=$((network_error_count + 1)) | |
status="network_error" | |
fi | |
# 如果失败,尝试使用缓存数据 | |
if [ "$status" != "success" ] && [ "${{ steps.load-cache.outputs.has_existing_cache }}" = "true" ]; then | |
cached_data=$(jq -r --arg url "$repo_url" '.data // {} | to_entries[] | select(.value.repo == $url) | .value | {stars: .stars, updated_at: .updated_at, version: .version}' existing_cache.json 2>/dev/null || echo "{}") | |
if [ "$cached_data" != "{}" ] && [ "$cached_data" != "" ]; then | |
cached_stars=$(echo "$cached_data" | jq -r '.stars // 0') | |
cached_updated=$(echo "$cached_data" | jq -r '.updated_at // ""') | |
cached_version=$(echo "$cached_data" | jq -r '.version // ""') | |
if [ "$cached_stars" != "0" ] || [ "$cached_updated" != "" ]; then | |
echo " 🔄 使用缓存数据: Stars: $cached_stars" | |
stars="$cached_stars" | |
updated_at="$cached_updated" | |
version="$cached_version" | |
status="cached" | |
fi | |
fi | |
fi | |
# 将信息添加到repo_info.json | |
jq --arg url "$repo_url" \ | |
--arg stars "$stars" \ | |
--arg updated "$updated_at" \ | |
--arg version "$version" \ | |
--arg status "$status" \ | |
'. + {($url): {stars: ($stars | tonumber), updated_at: $updated, version: $version, status: $status}}' \ | |
repo_info.json > temp_repo_info.json && mv temp_repo_info.json repo_info.json | |
# 添加基础延迟避免API限制 | |
sleep 0.5 | |
fi | |
done | |
# 成功率检查 | |
if [ $total_repos -gt 0 ]; then | |
success_rate=$((success_count * 100 / total_repos)) | |
echo "📈 成功率: $success_rate%" | |
if [ $success_rate -lt 50 ]; then | |
echo "⚠️ 警告: 成功率过低,可能存在网络问题或GitHub服务异常" | |
if [ "${{ steps.load-cache.outputs.has_existing_cache }}" = "true" ]; then | |
echo "已启用缓存回退机制" | |
fi | |
fi | |
fi | |
echo "✅ 仓库信息获取完成" | |
- name: Transform plugin data | |
if: steps.fetch-data.outputs.should_update == 'true' | |
run: | | |
echo "开始转换插件数据格式..." | |
# 使用jq转换数据格式,增加容错处理,并过滤掉404的仓库 | |
jq --slurpfile repo_info repo_info.json ' | |
to_entries | | |
# 只过滤掉确认已删除(404)的仓库,保留网络错误的仓库 | |
map(select( | |
if .value.repo and ($repo_info[0][.value.repo]) then | |
($repo_info[0][.value.repo].status != "deleted") | |
else | |
true | |
end | |
)) | | |
map({ | |
key: .key, | |
value: ( | |
.value + { | |
# 保持原有字段 | |
desc: .value.desc, | |
author: .value.author, | |
repo: .value.repo, | |
tags: (.value.tags // []) | |
} + | |
# 仅当social_link存在且不为空时添加 | |
(if .value.social_link then { social_link: .value.social_link } else {} end) + | |
# 添加新字段,从repo_info中获取 | |
(if .value.repo and ($repo_info[0][.value.repo]) then | |
($repo_info[0][.value.repo] | { | |
stars: .stars, | |
updated_at: .updated_at, | |
version: (if .version != "" then .version else "1.0.0" end) | |
}) | |
else | |
{ | |
stars: 0, | |
version: "1.0.0" | |
} | |
end) | |
) | |
}) | from_entries' original_plugins.json > temp_plugin_cache_original.json | |
# 格式化JSON使其更易读 | |
jq . temp_plugin_cache_original.json > plugin_cache_original.json | |
echo "✅ 数据转换完成" | |
# 显示转换统计 | |
original_count=$(jq 'keys | length' original_plugins.json) | |
new_count=$(jq 'keys | length' plugin_cache_original.json) | |
removed_count=$((original_count - new_count)) | |
# 统计不同状态的仓库 | |
success_repos=$(jq '[.[] | select(.status == "success")] | length' repo_info.json) | |
cached_repos=$(jq '[.[] | select(.status == "cached")] | length' repo_info.json) | |
redirected_repos=$(jq '[.[] | select(.status == "redirected")] | length' repo_info.json) | |
deleted_repos=$(jq '[.[] | select(.status == "deleted")] | length' repo_info.json) | |
failed_repos=$(jq '[.[] | select(.status != "success" and .status != "cached" and .status != "redirected" and .status != "deleted")] | length' repo_info.json) | |
echo "" | |
echo "📊 转换统计:" | |
echo " 插件数量变化: $original_count -> $new_count" | |
if [ $removed_count -gt 0 ]; then | |
echo " 🗑️ 已移除: $removed_count 个失效插件" | |
fi | |
echo " ✅ 实时数据: $success_repos 个仓库" | |
echo " 🔄 缓存数据: $cached_repos 个仓库" | |
echo " 🔄 重定向: $redirected_repos 个仓库" | |
echo " 🗑️ 已删除(已移除): $deleted_repos 个仓库" | |
echo " ❌ 网络错误(已保留): $failed_repos 个仓库" | |
# 列出被移除的仓库 | |
if [ $removed_count -gt 0 ]; then | |
echo "" | |
echo "🗑️ 以下仓库已从缓存中移除:" | |
jq -r 'to_entries[] | select(.value.status == "deleted") | " - " + .key + " (404 Not Found)"' repo_info.json | |
fi | |
# 列出网络错误的仓库(保留但使用缓存数据) | |
if [ "$failed_repos" -gt 0 ]; then | |
echo "" | |
echo "❌ 网络错误的仓库(已保留,使用缓存数据):" | |
jq -r 'to_entries[] | select(.value.status != "success" and .value.status != "cached" and .value.status != "redirected" and .value.status != "deleted") | " - " + .key + " (" + .value.status + ")"' repo_info.json | |
fi | |
# 列出重定向的仓库(保留但标记) | |
if [ "$redirected_repos" -gt 0 ]; then | |
echo "" | |
echo "🔄 发生重定向的仓库列表(已保留):" | |
jq -r 'to_entries[] | select(.value.status == "redirected") | " - " + .key' repo_info.json | |
fi | |
- name: Pull latest changes before checking (rebase with autostash) | |
run: | | |
set -e | |
git fetch origin main --depth=1 | |
# 在 Actions 的 detached HEAD 下也能切换到 main | |
if git rev-parse --abbrev-ref HEAD | grep -q '^HEAD$'; then | |
git checkout -B main origin/main | |
else | |
git checkout main 2>/dev/null || git checkout -b main origin/main | |
fi | |
# 使用 autostash 自动 stash 未暂存更改,rebase 完成后会自动 pop | |
if git pull --rebase --autostash origin main; then | |
echo "✅ pull --rebase --autostash 成功" | |
else | |
echo "❌ pull --rebase --autostash 失败,工作流将退出以便人工检查" | |
git rebase --abort 2>/dev/null || true | |
exit 1 | |
fi | |
- name: Check for changes | |
if: steps.fetch-data.outputs.should_update == 'true' | |
id: git-check | |
run: | | |
echo "检查文件状态..." | |
echo "检查远程仓库是否存在 plugin_cache_original.json..." | |
if git ls-tree --name-only -r origin/main | grep -q "^plugin_cache_original.json$"; then | |
echo "文件在远程仓库中已存在" | |
remote_exists="true" | |
else | |
echo "文件在远程仓库中不存在" | |
remote_exists="false" | |
fi | |
echo "检查本地 plugin_cache_original.json 是否存在..." | |
if [ -f plugin_cache_original.json ]; then | |
echo "文件存在,大小: $(wc -c < plugin_cache_original.json) bytes" | |
# 验证JSON格式 | |
if jq empty plugin_cache_original.json > /dev/null 2>&1; then | |
echo "✅ JSON格式有效" | |
else | |
echo "❌ JSON格式无效" | |
echo "has_changes=false" >> $GITHUB_OUTPUT | |
exit 1 | |
fi | |
else | |
echo "❌ 本地文件不存在" | |
echo "has_changes=false" >> $GITHUB_OUTPUT | |
exit 1 | |
fi | |
# 检查是否有变更 | |
if [ -f plugin_cache_original.json ]; then | |
if [ "$remote_exists" = "true" ]; then | |
# 文件在远程存在,检查是否有内容变更 | |
git add plugin_cache_original.json # 先添加到暂存区以便比较 | |
if git diff --cached --exit-code plugin_cache_original.json > /dev/null 2>&1; then | |
echo "has_changes=false" >> $GITHUB_OUTPUT | |
echo "ℹ️ 文件内容没有变化" | |
else | |
echo "has_changes=true" >> $GITHUB_OUTPUT | |
echo "✅ 检测到文件内容变更" | |
echo "变更详情:" | |
git diff --cached plugin_cache_original.json | |
fi | |
else | |
# 文件在远程不存在,这是新文件 | |
echo "has_changes=true" >> $GITHUB_OUTPUT | |
echo "✅ 这是新文件,需要提交" | |
# 预先添加到暂存区 | |
git add plugin_cache_original.json | |
fi | |
else | |
# 本地文件不存在 | |
echo "has_changes=false" >> $GITHUB_OUTPUT | |
echo "❌ 本地文件不存在,跳过提交" | |
exit 1 | |
fi | |
# 输出 Git 状态以便调试 | |
echo "Git 状态:" | |
git status | |
- name: Commit and push changes | |
if: steps.fetch-data.outputs.should_update == 'true' && steps.git-check.outputs.has_changes == 'true' | |
run: | | |
# 验证认证状态 | |
echo "验证Git认证状态..." | |
if git ls-remote origin HEAD > /dev/null 2>&1; then | |
echo "✅ Git认证成功" | |
else | |
echo "❌ Git认证失败,检查PAT_TOKEN权限" | |
exit 1 | |
fi | |
# 添加和提交文件 | |
git add plugin_cache_original.json | |
# 获取统计信息用于提交信息 | |
total_plugins=$(jq '.data | keys | length' plugin_cache_original.json 2>/dev/null || echo "0") | |
success_repos=$(jq '[.[] | select(.status == "success")] | length' repo_info.json 2>/dev/null || echo "0") | |
commit_message="🔄 Update plugin cache: $total_plugins plugins, $success_repos fresh updates - $(date -u '+%Y-%m-%d %H:%M:%S UTC')" | |
git commit -m "$commit_message" | |
# 推送更改 | |
echo "推送更改到远程仓库..." | |
if git push origin HEAD; then | |
echo "✅ 成功推送到远程仓库" | |
else | |
echo "❌ 推送失败,可能是权限问题" | |
exit 1 | |
fi | |
- name: Clean up | |
if: always() | |
run: | | |
# 清理所有临时文件 | |
rm -f temp_plugin_cache_original.json temp_response.txt temp_headers.txt original_plugins.json repo_info.json temp_repo_info.json existing_cache.json temp_api_headers_*.txt | |
echo "🧹 临时文件清理完成" | |
- name: Summary | |
if: always() | |
run: | | |
if [ "${{ steps.fetch-data.outputs.should_update }}" = "true" ]; then | |
if [ "${{ steps.git-check.outputs.has_changes }}" = "true" ]; then | |
echo "✅ 插件数据已成功转换并提交" | |
# 显示详细统计 | |
if [ -f plugin_cache_original.json ]; then | |
total_plugins=$(jq 'keys | length' plugin_cache_original.json) | |
echo "📊 最终结果: $total_plugins 个插件已更新" | |
fi | |
else | |
echo "ℹ️ 数据获取和转换成功,但内容未发生变化" | |
fi | |
else | |
echo "❌ 由于网络问题、GitHub服务错误或数据异常,跳过了数据转换" | |
echo "请检查GitHub服务状态或查看上面的错误详情" | |
fi |