-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathShell.sh
More file actions
136 lines (105 loc) · 3.3 KB
/
Shell.sh
File metadata and controls
136 lines (105 loc) · 3.3 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
#!/usr/bin/env bash
set -euo pipefail
# ============ Configuration ============
readonly APP_NAME="gitcode-api"
readonly REGISTRY="registry.example.com/gitcode"
readonly HEALTH_ENDPOINT="/healthz"
readonly MAX_RETRIES=30
readonly RETRY_INTERVAL=5
# ============ Color Output ============
RED='\\033[0;31m'
GREEN='\\033[0;32m'
YELLOW='\\033[1;33m'
NC='\\033[0m'
info() { echo -e "\${GREEN}[INFO]\${NC} \${1}"; }
warn() { echo -e "\${YELLOW}[WARN]\${NC} \${1}"; }
error() { echo -e "\${RED}[ERROR]\${NC} \${1}" >&2; }
# ============ Argument Parsing ============
VERSION=""
ENVIRONMENT="staging"
DRY_RUN=false
usage() {
cat <<EOF
Usage: \${0##*/} [OPTIONS]
Options:
-v VERSION Version tag (required)
-e ENV Environment: staging|production (default: staging)
-d Dry run mode
-h Show this help
EOF
}
while getopts "v:e:dh" opt; do
case \${opt} in
v) VERSION="\${OPTARG}" ;;
e) ENVIRONMENT="\${OPTARG}" ;;
d) DRY_RUN=true ;;
h) usage; exit 0 ;;
*) usage; exit 1 ;;
esac
done
[[ -z "\${VERSION}" ]] && { error "Version is required (-v)"; usage; exit 1; }
# ============ Cleanup Trap ============
cleanup() {
local exit_code=0
if [[ \${exit_code} -ne 0 ]]; then
error "Deploy failed with exit code \${exit_code}"
fi
rm -f /tmp/\${APP_NAME}-deploy-*.tmp
info "Cleanup complete"
}
trap cleanup EXIT
# ============ Docker Build & Push ============
build_and_push() {
local image="\${REGISTRY}/\${APP_NAME}:\${VERSION}"
info "Building \${image}"
if [[ "\${DRY_RUN}" == true ]]; then
info "[DRY RUN] Would build and push \${image}"
return 0
fi
docker build \
--build-arg VERSION="\${VERSION}" \
--build-arg BUILD_DATE="$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--tag "\${image}" \
--tag "\${REGISTRY}/\${APP_NAME}:latest" \
--file Dockerfile \
.
docker push "\${image}"
docker push "\${REGISTRY}/\${APP_NAME}:latest"
info "Pushed \${image}"
}
# ============ Health Check ============
wait_for_healthy() {
local url="\${1}"
local attempt=0
info "Waiting for \${url} to be healthy..."
while (( attempt < MAX_RETRIES )); do
if curl -sf "\${url}\${HEALTH_ENDPOINT}" > /dev/null 2>&1; then
info "Service is healthy after \${attempt} attempts"
return 0
fi
(( attempt++ ))
warn "Attempt \${attempt}/\${MAX_RETRIES} - retrying in \${RETRY_INTERVAL}s"
sleep "\${RETRY_INTERVAL}"
done
error "Service failed to become healthy after \${MAX_RETRIES} attempts"
return 1
}
# ============ Main ============
main() {
info "Deploying \${APP_NAME} v\${VERSION} to \${ENVIRONMENT}"
info "Dry run: \${DRY_RUN}"
build_and_push
if [[ "\${DRY_RUN}" == true ]]; then
info "[DRY RUN] Skipping deploy and health check"
exit 0
fi
kubectl set image "deployment/\${APP_NAME}" \
"\${APP_NAME}=\${REGISTRY}/\${APP_NAME}:\${VERSION}" \
--namespace="\${ENVIRONMENT}"
kubectl rollout status "deployment/\${APP_NAME}" \
--namespace="\${ENVIRONMENT}" \
--timeout=300s
wait_for_healthy "https://\${APP_NAME}.\${ENVIRONMENT}.example.com"
info "Deploy complete: \${APP_NAME} v\${VERSION} -> \${ENVIRONMENT}"
}
main