forked from semaphoreci/toolbox
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlibcheckout
More file actions
executable file
·268 lines (227 loc) · 6.89 KB
/
libcheckout
File metadata and controls
executable file
·268 lines (227 loc) · 6.89 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
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
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
function checkout() {
local use_cache=${1:-""}
if [ -z $SEMAPHORE_GIT_BRANCH ] || [ -z $SEMAPHORE_GIT_URL ] || [ -z $SEMAPHORE_GIT_DIR ] || [ -z $SEMAPHORE_GIT_SHA ]; then
checkout::validation_message
return 1
fi
rm -rf "$SEMAPHORE_GIT_DIR"
if [ "$use_cache" = "--use-cache" ]; then
echo "[Experimental stability] Using cached Git repository."
checkout::use_cache
else
if [ ! -z ${SEMAPHORE_GIT_REF_TYPE:-} ]; then
checkout::refbased
else
checkout::shallow
fi
exit_code=$?
if [ "$exit_code" -ne "0" ]; then
checkout::metric 0
fi
return $exit_code
fi
}
function checkout::validation_message() {
echo "[CHECKOUT ERROR] Some of these variables are unset:"
echo "SEMAPHORE_GIT_URL=$SEMAPHORE_GIT_URL"
echo "SEMAPHORE_GIT_DIR=$SEMAPHORE_GIT_DIR"
echo "SEMAPHORE_GIT_BRANCH=$SEMAPHORE_GIT_BRANCH"
echo "SEMAPHORE_GIT_SHA=$SEMAPHORE_GIT_SHA"
}
function checkout::use_cache() {
export CACHE_FAIL_ON_ERROR="true"
cache restore git-cache-
if [ "$?" -ne "0" ]; then
echo "Failed to restore from the cache"
rm -rf $SEMAPHORE_GIT_DIR
fi
if [ -d "$HOME/$SEMAPHORE_GIT_DIR" ]; then
checkout::fetch
else
checkout::clone
fi
if [ "$?" -eq "0" ]; then
checkout::cache_store
else
return 1
fi
}
function checkout::fetch() {
echo "Restored cache"
cd $HOME/$SEMAPHORE_GIT_DIR
git remote prune origin
retry git fetch --tags origin
checkout::switch_revision
}
function checkout::clone() {
retry git clone $SEMAPHORE_GIT_URL $SEMAPHORE_GIT_DIR
cd $SEMAPHORE_GIT_DIR
checkout::switch_revision
}
function checkout::reset_to_sha {
checkout::checkrevision
if [ "$?" -eq "0" ]; then
git reset --hard $SEMAPHORE_GIT_SHA 2>/dev/null
checkout::metric "$(du -s . | awk '{ print $1 }')"
return 0
else
return 1
fi
}
function checkout::switch_revision() {
if [ ${SEMAPHORE_GIT_REF_TYPE:-""} = "pull-request" ]; then
retry git fetch origin +$SEMAPHORE_GIT_REF: 2>/dev/null
if [ $? -ne 0 ]; then
echo "Reference: ${SEMAPHORE_GIT_REF} not found .... Exiting"
return 1
else
checkout::reset_to_sha
fi
elif [ ${SEMAPHORE_GIT_REF_TYPE:-""} = "tag" ]; then
git checkout -qf $SEMAPHORE_GIT_TAG_NAME
if [ $? -ne 0 ]; then
echo "Release $SEMAPHORE_GIT_TAG_NAME not found .... Exiting"
return 1
else
checkout::metric "$(du -s . | awk '{ print $1 }')"
echo "HEAD is now at ${SEMAPHORE_GIT_SHA} Release ${SEMAPHORE_GIT_TAG_NAME}"
return 0
fi
else
local branch_ref="refs/heads/$SEMAPHORE_GIT_BRANCH"
local branch_origin="origin/$SEMAPHORE_GIT_BRANCH"
if [[ -n $(git show-ref $SEMAPHORE_GIT_REF) ]]; then
git checkout $SEMAPHORE_GIT_BRANCH
else
git checkout -b $SEMAPHORE_GIT_BRANCH -t $branch_origin;
fi
checkout::reset_to_sha
fi
}
function checkout::cache_store() {
# update cache if older then 72h -> 25920s
if [ -z ${SEMAPHORE_GIT_CACHE_AGE:-""} ]; then
SEMAPHORE_GIT_CACHE_AGE=259200
fi
local cache_key=$(cache list 2>&1 | grep git-cache- | awk '{ print $1 }' | head -1)
local cache_age=$(echo $cache_key | cut -d'-' -f8)
if [[ ! -z "$cache_age" ]] && [[ $cache_age =~ ^[0-9]+$ ]]; then
local now=$(date +%s)
local diff=$(expr $now - $cache_age)
echo "diff: $diff"
if (( diff > $SEMAPHORE_GIT_CACHE_AGE )); then
echo "Git cache outdated, refreshing..."
cd ..
checkout::cleanupcache
cache store "git-cache-$SEMAPHORE_JOB_ID-`date +%s`" $SEMAPHORE_GIT_DIR
cd $SEMAPHORE_GIT_DIR
else
echo "Git cache up-to-data."
fi
else
echo "No git cache... caching"
cd ..
cache store "git-cache-${SEMAPHORE_JOB_ID}-`date +%s`" $SEMAPHORE_GIT_DIR
cd $SEMAPHORE_GIT_DIR
fi
}
function checkout::cleanupcache {
if [ -z ${SEMAPHORE_GIT_CACHE_KEEP:-""} ]; then
SEMAPHORE_GIT_CACHE_KEEP=0
fi
local k=$SEMAPHORE_GIT_CACHE_KEEP
local list=($(cache list 2>&1 | grep git-cache- | awk '{ print $1 }' | xargs))
for i in ${list[@]:$k}; do
cache delete $i
done
}
function checkout::checkrevision {
git rev-list HEAD..$SEMAPHORE_GIT_SHA 2>/dev/null
if [ $? -ne 0 ]; then
echo "Revision: ${SEMAPHORE_GIT_SHA} not found .... Exiting"
return 1
fi
}
function checkout::branch_checkout {
git checkout -f "$SEMAPHORE_GIT_BRANCH"
if [ $? -ne 0 ]; then
echo "Branch: ${SEMAPHORE_GIT_BRANCH} not found .... Exiting"
return 1
fi
}
function checkout::shallow() {
if [ -z ${SEMAPHORE_GIT_DEPTH:-""} ]; then
SEMAPHORE_GIT_DEPTH=50
fi
echo "Performing shallow clone with depth: $SEMAPHORE_GIT_DEPTH"
retry git clone --depth $SEMAPHORE_GIT_DEPTH -b $SEMAPHORE_GIT_BRANCH $SEMAPHORE_GIT_URL $SEMAPHORE_GIT_DIR
if [ $? -ne 0 ]; then
echo "Branch not found performing full clone"
retry git clone $SEMAPHORE_GIT_URL $SEMAPHORE_GIT_DIR
cd "$SEMAPHORE_GIT_DIR"
checkout::branch_checkout
if [ $? -ne 0 ]; then
return 1
fi
checkout::checkrevision
if [ "$?" -eq "0" ]; then
git reset --hard $SEMAPHORE_GIT_SHA 2>/dev/null
else
return 1
fi
else
cd $SEMAPHORE_GIT_DIR
git reset --hard $SEMAPHORE_GIT_SHA 2>/dev/null
if [ $? -ne 0 ]; then
echo "SHA: $SEMAPHORE_GIT_SHA not found performing full clone"
retry git fetch --unshallow
checkout::checkrevision
if [ "$?" -eq "0" ]; then
git reset --hard $SEMAPHORE_GIT_SHA 2>/dev/null
else
return 1
fi
fi
fi
checkout::metric "$(du -s . | awk '{ print $1 }')"
}
function checkout::refbased() {
if [ -z ${SEMAPHORE_GIT_DEPTH:-""} ]; then
SEMAPHORE_GIT_DEPTH=50
fi
if [ ${SEMAPHORE_GIT_REF_TYPE:-""} = "pull-request" ]; then
retry git clone --depth $SEMAPHORE_GIT_DEPTH $SEMAPHORE_GIT_URL $SEMAPHORE_GIT_DIR
cd $SEMAPHORE_GIT_DIR
retry git fetch origin +$SEMAPHORE_GIT_REF: 2>/dev/null
if [ $? -ne 0 ]; then
echo "Revision: ${SEMAPHORE_GIT_SHA} not found .... Exiting"
return 1
else
git checkout -qf FETCH_HEAD
echo "HEAD is now at ${SEMAPHORE_GIT_SHA}"
return 0
fi
fi
if [ ${SEMAPHORE_GIT_REF_TYPE:-""} = "tag" ]; then
retry git clone --depth $SEMAPHORE_GIT_DEPTH -b $SEMAPHORE_GIT_TAG_NAME $SEMAPHORE_GIT_URL $SEMAPHORE_GIT_DIR
if [ $? -ne 0 ]; then
echo "Release $SEMAPHORE_GIT_TAG_NAME not found .... Exiting"
return 1
else
cd $SEMAPHORE_GIT_DIR
git checkout -qf $SEMAPHORE_GIT_TAG_NAME
echo "HEAD is now at ${SEMAPHORE_GIT_SHA} Release ${SEMAPHORE_GIT_TAG_NAME}"
return 0
fi
fi
checkout::shallow
}
function checkout::metric() {
if [[ "${SEMAPHORE_TOOLBOX_METRICS_ENABLED:-''}" == "true" ]]; then
ref_type=${SEMAPHORE_GIT_REF_TYPE:-""}
size=${1:-"0"}
[[ $size -gt 0 ]] && status='success' || status='fail'
echo "libcheckout,provider='$SEMAPHORE_GIT_PROVIDER',reftype='$ref_type',status=$status size=$1" >> /tmp/toolbox_checkout
fi
}
export -f checkout