-
-
Notifications
You must be signed in to change notification settings - Fork 11
180 lines (171 loc) · 7.04 KB
/
sync-release.yml
File metadata and controls
180 lines (171 loc) · 7.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
name: Sync Release to Gitee
on:
workflow_dispatch:
jobs:
sync-release-to-gitee:
runs-on: ubuntu-latest
timeout-minutes: 180
env:
GITEE_TOKEN: ${{ secrets.GITEE_TOKEN }}
GH_TOKEN: ${{ github.token }}
steps:
- uses: actions/checkout@v4
- name: Install jq and curl
run: |
sudo apt-get update -y
sudo apt-get install -y jq curl
- name: Sync to Gitee via bash
env:
GH_OWNER: xOS
GH_REPO: ServerStatus
GITEE_OWNER: Ten
GITEE_REPO: ServerStatus
CURL_RETRY: '5'
CURL_RETRY_DELAY: '3'
run: |
set -euo pipefail
GH_API="https://api.github.com/repos/${GH_OWNER}/${GH_REPO}"
GITEE_API="https://gitee.com/api/v5/repos/${GITEE_OWNER}/${GITEE_REPO}"
# 获取最新 release 信息
echo "Fetching latest GitHub release..."
rel_json=$(curl -sS -H "Authorization: Bearer ${GH_TOKEN}" -H "Accept: application/vnd.github+json" "${GH_API}/releases/latest")
tag=$(echo "$rel_json" | jq -r .tag_name)
body=$(echo "$rel_json" | jq -r .body)
if [ -z "$tag" ] || [ "$tag" = "null" ]; then
echo "No release found on GitHub" >&2
exit 1
fi
echo "Latest tag: $tag"
# 下载资产
asset_count=$(echo "$rel_json" | jq '.assets | length')
if [ "$asset_count" -eq 0 ]; then
echo "No assets to sync." >&2
exit 1
fi
echo "Downloading $asset_count assets..."
echo "$rel_json" | jq -r '.assets[] | "\(.name) \(.browser_download_url)"' | while read -r name url; do
echo "Downloading $name"
curl -L --fail --retry ${CURL_RETRY} --retry-delay ${CURL_RETRY_DELAY} -H "Authorization: Bearer ${GH_TOKEN}" -o "$name" "$url"
done
# 创建或复用 Gitee release
echo "Creating or reusing Gitee release..."
create_resp=$(curl -sS -X POST "${GITEE_API}/releases" \
-F access_token="${GITEE_TOKEN}" \
-F tag_name="$tag" \
-F name="$tag" \
-F body="$body" \
-F target_commitish="master" \
-w "\n%{http_code}")
http_code=$(echo "$create_resp" | tail -n1)
create_body=$(echo "$create_resp" | sed '$d')
if [ "$http_code" = "201" ]; then
release_id=$(echo "$create_body" | jq -r .id)
else
echo "Create release failed ($http_code), try list to reuse..."
list_json=$(curl -sS "${GITEE_API}/releases?access_token=${GITEE_TOKEN}&page=1&per_page=100")
release_id=$(echo "$list_json" | jq -r ".[] | select(.tag_name==\"$tag\") | .id" | head -n1)
if [ -z "$release_id" ]; then
echo "No Gitee release id available for tag $tag" >&2
echo "Create response: $create_body" >&2
exit 1
fi
fi
echo "Gitee release id: $release_id"
# 列出已有资产,避免重复
detail_json=$(curl -sS "${GITEE_API}/releases/${release_id}?access_token=${GITEE_TOKEN}")
existing=$(echo "$detail_json" | jq -r '.assets[]?.name' | tr '\n' ' ')
echo "Existing assets: $existing"
# 生成上传列表(以下载得到的资产为准),并按大小排序(先小后大)
echo "$rel_json" | jq -r '.assets[] | .name' > asset_names.txt
: > upload_list.txt
while read -r n; do
[ -f "$n" ] || continue
sz=$(stat -c %s "$n" 2>/dev/null || stat -f %z "$n")
printf "%s %s\n" "$sz" "$n" >> upload_list.txt
done < asset_names.txt
mapfile -t files < <(sort -n upload_list.txt | awk '{print $2}')
attach_api="${GITEE_API}/releases/${release_id}/attach_files"
# 上传辅助函数:尝试多种参数形式
upload_one() {
local filepath="$1"
local attempt ok http_code body tmp
ok=0
tmp=$(mktemp)
# 依据前一轮日志,Gitee 需要字段名为 file;优先用 form token + file,其次 URL token + file
for attempt in 1 2; do
case "$attempt" in
1)
echo " - try1: form token + file=@\"$filepath\""
http_code=$(curl --http1.1 -4 -sS -X POST \
--retry ${CURL_RETRY} --retry-delay ${CURL_RETRY_DELAY} --retry-all-errors \
--no-keepalive --tcp-nodelay --expect100-timeout 0 \
--connect-timeout 10 --max-time 3600 \
-F access_token="${GITEE_TOKEN}" \
-F file=@"$filepath" \
-o "$tmp" -w "%{http_code}" \
"$attach_api")
;;
2)
echo " - try2: url token + file=@\"$filepath\""
http_code=$(curl --http1.1 -4 -sS -X POST \
--retry ${CURL_RETRY} --retry-delay ${CURL_RETRY_DELAY} --retry-all-errors \
--no-keepalive --tcp-nodelay --expect100-timeout 0 \
--connect-timeout 10 --max-time 3600 \
-F file=@"$filepath" \
-o "$tmp" -w "%{http_code}" \
"$attach_api?access_token=${GITEE_TOKEN}")
;;
esac
body=$(head -c 256 "$tmp" || true)
echo " http=$http_code body=${body}"
if [ "$http_code" = "201" ]; then
ok=1; break
fi
# 容错:若服务端提示已存在,视为成功
if echo "$body" | grep -Eqi '已存在|already exists|exist'; then
ok=1; break
fi
done
rm -f "$tmp"
[ "$ok" = "1" ]
}
# 并发上传(最多 3 个同时进行)
MAX_PAR=3
tmpdir=$(mktemp -d)
pids=()
names=()
i=0
for f in "${files[@]}"; do
name="$f"
if echo " $existing " | grep -q " $name "; then
echo "Skip $name (exists)"
continue
fi
echo "Uploading $name ..."
(
if upload_one "$name"; then
echo ok >"$tmpdir/${name}.status"
echo " -> uploaded"
else
echo fail >"$tmpdir/${name}.status"
echo "Upload failed for $name after all attempts" >&2
fi
) &
pids+=("$!")
names+=("$name")
i=$((i+1))
if [ "$((i % MAX_PAR))" -eq 0 ]; then
wait -n || true
fi
done
# 等待剩余任务
wait || true
# 汇总结果
fails=$(ls "$tmpdir" | grep -c \.status$ || true)
if ls "$tmpdir"/*.status >/dev/null 2>&1; then
if grep -q '^fail$' "$tmpdir"/*.status; then
echo "One or more uploads failed." >&2
exit 1
fi
fi
rm -rf "$tmpdir"