-
Notifications
You must be signed in to change notification settings - Fork 162
/
entrypoint.sh
executable file
·248 lines (206 loc) · 6.17 KB
/
entrypoint.sh
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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
#!/bin/bash
DEBUG="${INPUT_DEBUG}"
if [[ "$DEBUG" == "true" ]]; then
set -x
fi
mkdir -p /root/.ssh
echo "${INPUT_DST_KEY}" > /root/.ssh/id_rsa
chmod 600 /root/.ssh/id_rsa
DST_TOKEN="${INPUT_DST_TOKEN}"
SRC_HUB="${INPUT_SRC}"
DST_HUB="${INPUT_DST}"
ACCOUNT_TYPE="${INPUT_ACCOUNT_TYPE}"
SRC_TYPE=`dirname $SRC_HUB`
DST_TYPE=`dirname $DST_HUB`
SRC_ACCOUNT=`basename $SRC_HUB`
DST_ACCOUNT=`basename $DST_HUB`
CLONE_STYLE="${INPUT_CLONE_STYLE}"
CACHE_PATH="${INPUT_CACHE_PATH}"
WHITE_LIST="${INPUT_WHITE_LIST}"
BLACK_LIST="${INPUT_BLACK_LIST}"
STATIC_LIST="${INPUT_STATIC_LIST}"
FORCE_UPDATE="${INPUT_FORCE_UPDATE}"
DELAY_EXIT=false
TIME_OUT="${INPUT_TIMEOUT}"
RETRY_TIMES=3
function err_exit {
echo -e "\033[31m $1 \033[0m"
exit 1
}
FAILED_LIST=()
function delay_exit {
echo -e "\033[31m $1 \033[0m"
FAILED_LIST+=($2)
DELAY_EXIT=true
return 1
}
if [[ "$ACCOUNT_TYPE" == "org" ]]; then
SRC_LIST_URL_SUFFIX=orgs/$SRC_ACCOUNT/repos
DST_LIST_URL_SUFFIX=orgs/$DST_ACCOUNT/repos
DST_CREATE_URL_SUFFIX=orgs/$DST_ACCOUNT/repos
elif [[ "$ACCOUNT_TYPE" == "user" ]]; then
SRC_LIST_URL_SUFFIX=users/$SRC_ACCOUNT/repos
DST_LIST_URL_SUFFIX=users/$DST_ACCOUNT/repos
DST_CREATE_URL_SUFFIX=user/repos
else
err_exit "Unknown account type, the `account_type` should be `user` or `org`"
fi
if [[ "$SRC_TYPE" == "github" ]]; then
SRC_REPO_LIST_API=https://api.github.com/$SRC_LIST_URL_SUFFIX
if [[ "$CLONE_STYLE" == "ssh" ]]; then
SRC_REPO_BASE_URL=git@github.com:
elif [[ "$CLONE_STYLE" == "https" ]]; then
SRC_REPO_BASE_URL=https://github.com/
fi
elif [[ "$SRC_TYPE" == "gitee" ]]; then
SRC_REPO_LIST_API=https://gitee.com/api/v5/$SRC_LIST_URL_SUFFIX
if [[ "$CLONE_STYLE" == "ssh" ]]; then
SRC_REPO_BASE_URL=git@gitee.com:
elif [[ "$CLONE_STYLE" == "https" ]]; then
SRC_REPO_BASE_URL=https://gitee.com/
fi
else
err_exit "Unknown src args, the `src` should be `[github|gittee]/account`"
fi
function retry {
local retries=$RETRY_TIMES
local count=0
until timeout $TIME_OUT "$@"; do
exit=$?
wait=$((2 ** $count))
count=$(($count + 1))
if [ $count -lt $retries ]; then
echo "Retry $count/$retries exited $exit, retrying in $wait seconds..."
sleep $wait
else
echo "Retry $count/$retries exited $exit, no more retries left."
return $exit
fi
done
return 0
}
function get_all_repo_names
{
PAGE_NUM=100
URL=$1
HUB_TYPE=$2
if [[ "$HUB_TYPE" == "github" ]]; then
total=`curl -sI "$URL?page=1&per_page=$PAGE_NUM" | sed -nr "s/^[lL]ink:.*page=([0-9]+)&per_page=$PAGE_NUM.*/\1/p"`
elif [[ "$HUB_TYPE" == "gitee" ]]; then
total=`curl -sI "$URL?page=1&per_page=$PAGE_NUM" | grep total_page: |cut -d ' ' -f2 |tr -d '\r'`
fi
# use pagination?
if [ -z "$total" ]; then
# no - this result has only one page
total=1
fi
p=1
while [ "$p" -le "$total" ]; do
x=`curl -s "$URL?page=$p&per_page=$PAGE_NUM" | jq '.[] | .name' | sed 's/"//g'`
echo $x
p=$(($p + 1))
done
}
if [[ -z $STATIC_LIST ]]; then
SRC_REPOS=`get_all_repo_names $SRC_REPO_LIST_API $SRC_TYPE`
else
SRC_REPOS=`echo $STATIC_LIST | tr ',' ' '`
fi
if [[ "$DST_TYPE" == "github" ]]; then
DST_REPO_CREATE_API=https://api.github.com/$DST_CREATE_URL_SUFFIX
DST_REPO_LIST_API=https://api.github.com/$DST_LIST_URL_SUFFIX
elif [[ "$DST_TYPE" == "gitee" ]]; then
DST_REPO_CREATE_API=https://gitee.com/api/v5/$DST_CREATE_URL_SUFFIX
DST_REPO_LIST_API=https://gitee.com/api/v5/$DST_LIST_URL_SUFFIX
else
err_exit "Unknown dst args, the `dst` should be `[github|gittee]/account`"
fi
DST_REPOS=`get_all_repo_names $DST_REPO_LIST_API $DST_TYPE`
function clone_repo
{
echo -e "\033[31m(0/3)\033[0m" "Downloading..."
if [ ! -d "$1" ]; then
retry git clone $SRC_REPO_BASE_URL$SRC_ACCOUNT/$1.git
fi
cd $1
}
function create_repo
{
# Auto create non-existing repo
has_repo=`echo $DST_REPOS | grep -Fx $1 | wc -l`
if [ $has_repo == 0 ]; then
echo "Create non-exist repo..."
if [[ "$DST_TYPE" == "github" ]]; then
curl -s -H "Authorization: token $2" --data '{"name":"'$1'"}' $DST_REPO_CREATE_API > /dev/null
elif [[ "$DST_TYPE" == "gitee" ]]; then
curl -s -X POST --header 'Content-Type: application/json;charset=UTF-8' $DST_REPO_CREATE_API -d '{"name": "'$1'","access_token": "'$2'"}' > /dev/null
fi
fi
git remote add $DST_TYPE git@$DST_TYPE.com:$DST_ACCOUNT/$1.git || echo "Remote already exists."
}
function update_repo
{
echo -e "\033[31m(1/3)\033[0m" "Updating..."
retry git pull -p
}
function import_repo
{
echo -e "\033[31m(2/3)\033[0m" "Importing..."
git remote set-head origin -d
if [[ "$FORCE_UPDATE" == "true" ]]; then
retry git push -f $DST_TYPE refs/remotes/origin/*:refs/heads/* --tags --prune
else
retry git push $DST_TYPE refs/remotes/origin/*:refs/heads/* --tags --prune
fi
}
function _check_in_list () {
local e match="$1"
shift
for e; do [[ "$e" == "$match" ]] && return 0; done
return 1
}
function test_black_white_list
{
WHITE_ARR=(`echo $WHITE_LIST | tr ',' ' '`)
BLACK_ARR=(`echo $BLACK_LIST | tr ',' ' '`)
_check_in_list $1 "${WHITE_ARR[@]}";in_white_list=$?
_check_in_list $1 "${BLACK_ARR[@]}";in_back_list=$?
if [[ $in_back_list -ne 0 ]] ; then
if [[ -z $WHITE_LIST ]] || [[ $in_white_list -eq 0 ]] ; then
return 0
else
echo "Skip, "$1" not in non-empty white list"$WHITE_LIST
return 1
fi
else
echo "Skip, "$1 "in black list: "$BLACK_LIST
return 1
fi
}
if [ ! -d "$CACHE_PATH" ]; then
mkdir -p $CACHE_PATH
fi
cd $CACHE_PATH
all=0
success=0
skip=0
for repo in $SRC_REPOS
{
all=$(($all + 1))
if test_black_white_list $repo ; then
echo -e "\n\033[31mBackup $repo ...\033[0m"
cd $CACHE_PATH
clone_repo $repo || delay_exit "clone and cd failed" $repo || continue
create_repo $repo $DST_TOKEN || delay_exit "create failed" $repo || continue
update_repo || delay_exit "Update failed" $repo || continue
import_repo && success=$(($success + 1)) || delay_exit "Push failed" $repo || continue
else
skip=$(($skip + 1))
fi
}
failed=$(($all - $skip - $success))
echo "Total: $all, skip: $skip, successed: $success, failed: $failed."
echo "Failed: "$FAILED_LIST
if [[ "$DELAY_EXIT" == "true" ]]; then
exit 1
fi