-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathgit-clone.sh
More file actions
301 lines (262 loc) · 10.8 KB
/
git-clone.sh
File metadata and controls
301 lines (262 loc) · 10.8 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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
#!/bin/bash
# Git repository cloning module
clone_repository() {
if [ -d "$TMP_DIR" ] && [ "$(ls -A "$TMP_DIR" 2>/dev/null)" ]; then
echo "ℹ️ Cloning tests repository is not required, because tests are already in image..."
return 0
fi
echo "📥 Preparing tests repository..."
# ============================================
# Pre-flight validation
# ============================================
if [ -z "${ATP_TESTS_GIT_TOKEN:-}" ]; then
echo "❌ ERROR: ATP_TESTS_GIT_TOKEN is not set (required to download repository archive)"
return 1
fi
if [ -z "${ATP_TESTS_GIT_REPO_URL:-}" ]; then
echo "❌ ERROR: ATP_TESTS_GIT_REPO_URL is not set"
return 1
fi
if [ -z "${ATP_TESTS_GIT_REPO_BRANCH:-}" ]; then
echo "❌ ERROR: ATP_TESTS_GIT_REPO_BRANCH is not set"
return 1
fi
if [ -z "${TMP_DIR:-}" ]; then
echo "❌ ERROR: TMP_DIR is not set"
return 1
fi
# Basic URL sanity check (no whitespace, http/https)
if [[ "$ATP_TESTS_GIT_REPO_URL" =~ [[:space:]] ]] || [[ ! "$ATP_TESTS_GIT_REPO_URL" =~ ^https?:// ]]; then
echo "❌ ERROR: ATP_TESTS_GIT_REPO_URL is invalid URL: $ATP_TESTS_GIT_REPO_URL"
return 1
fi
# Strip .git from URL and extract repo name
REPO_PATH=$(echo "$ATP_TESTS_GIT_REPO_URL" | sed 's|\.git$||')
GIT_BRANCH_CLEANED=$(echo "$ATP_TESTS_GIT_REPO_BRANCH" | sed 's|/|-|')
REPO_NAME=$(basename "$REPO_PATH")
ARCHIVE_URL="${REPO_PATH}/-/archive/${ATP_TESTS_GIT_REPO_BRANCH}/${REPO_NAME}-${GIT_BRANCH_CLEANED}.zip"
mkdir -p "$TMP_DIR" 2>/dev/null || true
ZIP_PATH="$TMP_DIR/repo.zip"
CURL_ERR_PATH="$TMP_DIR/curl_download.err"
fetch_by_clone_with_submodules() {
if ! command -v git >/dev/null 2>&1; then
echo "❌ git is not installed in the container, cannot clone repository with submodules"
return 1
fi
echo "📥 .gitmodules detected — switching to git clone with submodules..."
rm -rf "$TMP_DIR"
AUTH_REPO_URL="$ATP_TESTS_GIT_REPO_URL"
if [[ "$AUTH_REPO_URL" =~ ^https:// ]]; then
AUTH_REPO_URL=$(echo "$AUTH_REPO_URL" | sed "s|^https://|https://oauth2:${ATP_TESTS_GIT_TOKEN}@|")
fi
git clone \
--branch "$ATP_TESTS_GIT_REPO_BRANCH" \
--single-branch \
"$AUTH_REPO_URL" \
"$TMP_DIR" || return 1
cd "$TMP_DIR" || return 1
if [ -f .gitmodules ]; then
echo "🔧 Configuring credential substitution for submodule authentication..."
GIT_HOST=$(echo "$ATP_TESTS_GIT_REPO_URL" | sed 's|^https://||; s|/.*||')
git config --global \
"url.https://oauth2:${ATP_TESTS_GIT_TOKEN}@${GIT_HOST}/.insteadOf" \
"https://${GIT_HOST}/"
fi
git submodule update --init --recursive || return 1
if [ -f .gitmodules ] && [ -n "${GIT_HOST:-}" ]; then
git config --global --unset-all \
"url.https://oauth2:${ATP_TESTS_GIT_TOKEN}@${GIT_HOST}/.insteadOf" 2>/dev/null || true
fi
echo "📋 Submodule status after initialization:"
git submodule status || true
echo "✅ Repository cloned with submodules to: $TMP_DIR"
}
echo "📥 Downloading archive from: $ARCHIVE_URL"
# ============================================
# Download archive with enhanced error handling
# - connect timeout: 30s
# - max time: 120s
# ============================================
HTTP_CODE="$(
curl -sS -L \
--connect-timeout 30 \
--max-time 120 \
--fail \
-H "PRIVATE-TOKEN: ${ATP_TESTS_GIT_TOKEN}" \
"$ARCHIVE_URL" \
-o "$ZIP_PATH" \
-w "%{http_code}" \
2>"$CURL_ERR_PATH"
)"
CURL_EXIT_CODE=$?
# ============================================
# Error detection and messaging
# ============================================
if [ "$CURL_EXIT_CODE" -ne 0 ]; then
CURL_ERR_MSG=""
if [ -f "$CURL_ERR_PATH" ]; then
CURL_ERR_MSG=$(tr '\n' ' ' < "$CURL_ERR_PATH" | sed 's/[[:space:]]\+/ /g' | sed 's/[[:space:]]*$//')
fi
case "$CURL_EXIT_CODE" in
6)
echo "❌ ERROR: Couldn't resolve host while downloading repository archive."
;;
7)
echo "❌ ERROR: Failed to connect to host while downloading repository archive."
;;
22)
# HTTP error (4xx/5xx). We'll handle using HTTP_CODE below.
;;
28)
echo "❌ ERROR: Download timed out (connect-timeout=30s, max-time=120s)."
;;
35)
echo "❌ ERROR: SSL/TLS connection error while downloading repository archive."
;;
52)
echo "❌ ERROR: Empty reply from server while downloading repository archive."
;;
56)
echo "❌ ERROR: Network receive error while downloading repository archive."
;;
*)
echo "❌ ERROR: Network error while downloading repository archive (curl exit code: $CURL_EXIT_CODE)."
;;
esac
if [ -n "$CURL_ERR_MSG" ]; then
echo " curl: $CURL_ERR_MSG"
fi
# For non-HTTP curl failures, stop here (HTTP_CODE may be empty/undefined).
if [ "$CURL_EXIT_CODE" -ne 22 ]; then
return 1
fi
fi
# HTTP code interpretation (also covers curl --fail exit 22)
if [ "$HTTP_CODE" != "200" ]; then
case "$HTTP_CODE" in
200)
;;
000)
echo "❌ ERROR: No HTTP response received from server (HTTP 000)."
echo " Check network connectivity and URL: $ARCHIVE_URL"
return 1
;;
401|403)
echo "❌ ERROR: Authentication failed (HTTP $HTTP_CODE)."
echo " Check that ATP_TESTS_GIT_TOKEN is valid and has access to the repository."
return 1
;;
404)
echo "❌ ERROR: Repository or branch not found (HTTP 404)."
echo " Check URL and branch:"
echo " - URL: $ATP_TESTS_GIT_REPO_URL"
echo " - Branch: $ATP_TESTS_GIT_REPO_BRANCH"
echo " - Archive URL: $ARCHIVE_URL"
return 1
;;
429)
echo "❌ ERROR: Rate limited by the server (HTTP 429)."
echo " Try again later or reduce request frequency."
return 1
;;
5??)
echo "❌ ERROR: Server error while downloading archive (HTTP $HTTP_CODE)."
echo " The Git server may be temporarily unavailable."
return 1
;;
*)
echo "❌ ERROR: Failed to download repository archive (HTTP $HTTP_CODE, curl exit code: $CURL_EXIT_CODE)."
echo " Archive URL: $ARCHIVE_URL"
return 1
;;
esac
fi
# ============================================
# Downloaded archive validation
# ============================================
if [ ! -f "$ZIP_PATH" ] || [ ! -s "$ZIP_PATH" ]; then
echo "❌ ERROR: Downloaded file is missing or empty: $ZIP_PATH"
return 1
fi
if command -v file >/dev/null 2>&1; then
FILE_TYPE="$(file "$ZIP_PATH" 2>/dev/null || true)"
if ! printf '%s' "$FILE_TYPE" | grep -qi "zip archive"; then
# Git servers sometimes return an HTML login page when the token is invalid/expired.
if printf '%s' "$FILE_TYPE" | grep -qi "html"; then
echo "❌ ERROR: Downloaded an HTML login page instead of a repository."
echo " Check that ATP_TESTS_GIT_TOKEN is valid and has access to the repository."
echo " Check that the repository URL is correct."
else
echo "❌ ERROR: Downloaded repository is not recognized as a zip archive."
fi
echo " File type: $FILE_TYPE"
return 1
fi
else
echo "⚠️ 'file' command not available; skipping zip magic-byte validation."
fi
if command -v unzip >/dev/null 2>&1; then
if ! unzip -t "$ZIP_PATH" > /dev/null 2>&1; then
echo "❌ ERROR: Archive integrity test failed (unzip -t). Please retry the operation."
return 1
fi
else
echo "❌ ERROR: 'unzip' command is not available; cannot validate/extract archive."
return 1
fi
echo "📦 Unzipping..."
unzip -q "$ZIP_PATH" -d "$TMP_DIR" || {
echo "❌ Failed to unzip repository archive"
return 1
}
extracted_dir="$TMP_DIR/${REPO_NAME}-${GIT_BRANCH_CLEANED}"
if [ -f "$extracted_dir/.gitmodules" ]; then
rm -rf "$extracted_dir"
rm -f "$ZIP_PATH"
fetch_by_clone_with_submodules || {
echo "❌ Failed to clone repository with submodules"
return 1
}
else
shopt -s dotglob
mv "$extracted_dir"/* "$TMP_DIR" || {
shopt -u dotglob
echo "❌ Failed to move extracted repository contents"
return 1
}
shopt -u dotglob
rm -rf "$extracted_dir"
rm -f "$ZIP_PATH"
echo "✅ Repository extracted to: $TMP_DIR"
fi
if [ -d "$TMP_DIR/app" ]; then
echo "✅ Validation successful. Found 'app/' directory in the repo."
elif [ -d "$TMP_DIR/tests" ]; then
echo "✅ Validation successful. Found 'tests/' directory in the repo."
elif find "$TMP_DIR" -mindepth 1 -type f -iname "*postman_collection*" -print -quit | grep -q .; then
echo "✅ Validation successful. Found 'postman_collection' files in the repo."
elif [ -d "$TMP_DIR/collections" ]; then
echo "✅ Validation successful. Found 'collections/' directory in the repo."
else
echo "❌ ERROR: Neither 'app/' nor 'tests/' nor 'collections/' directory nor 'postman_collection' file found in the cloned repo!"
return 1
fi
cd "$TMP_DIR" || return 1
if [ -d "$TMP_DIR/app" ]; then
echo "📋 Contents of $TMP_DIR/app directory:"
ls -la app
elif [ -d "$TMP_DIR/tests" ]; then
echo "📋 Contents of $TMP_DIR/tests directory:"
ls -la tests
fi
if [ -f "$TMP_DIR/.gitmodules" ]; then
if command -v git >/dev/null 2>&1; then
echo "📋 Submodule status:"
git submodule status || true
fi
fi
# Clear Git token from environment for security
unset ATP_TESTS_GIT_TOKEN
echo "🔐 Git token cleared from environment"
echo "✅ Tests repository prepared successfully"
}