Post

Git repository auto deploy shell

Git repository auto deploy shell

Why??

  • 회사에서 프로젝트를 개발하고 배포함에 있어서, 편하게 할수 있도록하는 배포용 shell 개발
  • 또한 commit후 배포하지 않아도 새벽마다 재배포 할 수 있는 cron 작성
  • 주로 java 기반의 maven 프로젝트를 위주로 개발하기 때문에 이를 위한 shell이다.
  • maven 빌드 후의 결과로 떨어지는 deploy.sh을 실행하면 서비스 파일 위치, 서비스 등록 등의 배포 작업을 해준다.
  • deploy.sh은 직접 개발한 것이 아니라 현재 팀의 팀장님께서 개발한 내용으로 팀장님께 문의 후, 기회가 되면 포스팅할 예정

deploy.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
249
250
251
252
253
254
255
256
257
258
259
260
261
#!/bin/bash

usage() {
    echo
    echo ">>> CALLED BY [[ $1 ]]"
    echo
    echo "[Usage]"
    echo
    echo "./update.sh -c <configuration> [-p|--profile] <profile-name> [-f|--force] [-rgd|--remove-git-directory]"
    echo
    echo "[Option]"
    echo " -c: 설정파일 경로"
    echo " -p, --profile: springboot profile name"
    echo " -f, --force: commit된 내용이 없어도 배포를 실행함"
    echo " -rgd, --remove-git-directory: 배포가 끝난 후 clone받은 git-directory를 삭제함"
    echo " -h, --help: 도움말"
    echo
}


# 파라미터가 없는 경우 종료
if [ "$1" == "" ];
then
    usage "No Paramters."
    exit 1
fi


## 파라미터 읽기
while [ "$1" != "" ]; do
    case $1 in
    -c)
        shift
        CONFIG_FILE=$1
        ;;
    -p | --profile)
        shift
        PROFILE=$1
        ;;
    -f | --force)
        shift
        IS_FORCE=true
        ;;
    -h | --help)
        usage "--help"
        exit 0
        ;;
    -rgd | --remove-git-directory)
        shift
        REMOVE_GIT_DIRECTORY=true
        ;;
    *)
        usage "Invalid option. option: $1"
        exit 1
        ;;
    esac
    shift
done


## 설정파일 읽기
prop() {
    grep -v -e "^#" ${CONFIG_FILE_PATH} | grep -w "${1}" | cut -d "=" -f2-
}

## 있어보이기 위한 sleep
set_to_look_great() {
    sleep 0.3
}

## 설정파일이 전달되지 않은 경우 종료
if [ -f "$CONFIG_FILE" ];
then
    echo "[Configurations] $CONFIG_FILE FOUND!"
else
    echo "[Configurations] $CONFIG_FILE NOT FOUND!"
    usage "No Configuration file"

    exit 1
fi

## PROFILE이 전달되지 않은 경우 종료
if [ -z "$PROFILE" ];
then
    echo "[Profile] $PROFILE NOT FOUND!"
    usage "No Profile"

    exit 1
else
    echo "[Profile] $PROFILE FOUND!"
fi

################ 서비스 로직 시작

echo "========================================================="

#
# !!!! 주의 !!!!
# config 값은 최초에 전부 불러와야함!
# config file의 경로를 상대 경로로 받고 있고, 중간에 디렉토리 변경이 있기 때문에,,
#
# START
#

# 현재 위치 저장
# 배포가 끝난뒤 현재 위치로 오기 위함
CURRENT_LOCATION=$(pwd)

# CONFIG FILE 위치
CONFIG_FILE_PATH=$CONFIG_FILE


# git repository를 저장할 directory 정보
REPOSITORY_PATH=$(prop 'git_directory')

# git 정보
GIT_REPOSITORY_URL=$(prop 'git_repository_url')
GIT_BRANCH=$(prop 'git_repository_branch') # git branch 정보
GIT_ID=$(prop 'git_id')
GIT_PASSWORD=$(prop 'git_password')

# maven 실행 command
MVN_EXECUTE_COMMAND=$(prop 'mvn_execute_command')" -Dbuild.profile=$PROFILE"

# maven 실행 결과 directory
MVN_EXECUTE_RESULT_DIRECTORY=$REPOSITORY_PATH/$(prop 'mvn_execute_result_directory')"/$PROFILE"

# 서비스 실행 command
SERVICE_EXECUTE_COMMAND=$(prop 'service_execute_command')

#
#
# E N D
#
#

echo
echo
echo "REPOSITORY_PATH: " $REPOSITORY_PATH
echo

if [ -d "$REPOSITORY_PATH" ];
then # 01-1. repository가 있을 경우 pull받음.
    echo "[GIT] repository is founded"

    echo
    echo "[Linux] cd repository ('$REPOSITORY_PATH')"
    cd $REPOSITORY_PATH
    echo

    set_to_look_great

    echo
    echo "[GIT] switch branch to '$GIT_BRANCH'"
    git checkout $GIT_BRANCH
    echo

    set_to_look_great

    echo
    cd $REPOSITORY_PATH
    echo "[GIT] pull"
    GIT_PULL_RESULT=`git pull`
    echo
else # 01-2. repository가 없을 경우 clone 받음
    echo "[GIT] repository is not founded"

    set_to_look_great

    echo
    echo "[GIT] GIT_REPOSITORY_URL:" $GIT_REPOSITORY_URL

    set_to_look_great

    echo
    echo "[GIT] disable global http.sslVerify in git"
    git config --global http.sslVerify false
    echo

    set_to_look_great

    echo
    echo "[GIT] clone"
    echo
    git clone https://$GIT_ID:$GIT_PASSWORD@$GIT_REPOSITORY_URL $REPOSITORY_PATH
    echo

    set_to_look_great

    echo
    echo "[Linux] cd repository ('$REPOSITORY_PATH')"
    cd $REPOSITORY_PATH
    echo

    set_to_look_great

    echo
    echo "[GIT] switch branch to '$GIT_BRANCH'"
    git checkout $GIT_BRANCH
    echo
fi

echo
echo "[GIT] force update:" $IS_FORCE
echo "[GIT] git pull result:" $GIT_PULL_RESULT

# git에서 pull 받은 내용이 있는지 확인
if [[ $IS_FORCE ]] || ([[ $GIT_PULL_RESULT != "Already up-to-date." ]] && [[ $GIT_PULL_RESULT != "Already up to date." ]]);
then # 배포 실행
    echo
    echo "[MVN] execute maven command"
    echo "[MVN] command:" $MVN_EXECUTE_COMMAND
    $MVN_EXECUTE_COMMAND
    echo

    set_to_look_great

    # 배포 폴더가 있을 경우 진행
    if [ -d "$MVN_EXECUTE_RESULT_DIRECTORY" ];
    then
        echo
        echo "[Linux] cd deploy directory('$MVN_EXECUTE_RESULT_DIRECTORY' -Dspring.profile=$PROFILE)"
        cd $MVN_EXECUTE_RESULT_DIRECTORY
        echo

        set_to_look_great

        echo
        echo "[Service] execute service"
        echo "[Service] execute command('$SERVICE_EXECUTE_COMMAND' --profile=$PROFILE)"
        $SERVICE_EXECUTE_COMMAND
        echo
    else
        echo
        echo " !!! mvn_execute_result_directory('$MVN_EXECUTE_RESULT_DIRECTORY') NOT FOUND !!!"
        echo
    fi
else # 배포 중단
    echo
    echo "Alreay up to date."
    echo
fi

cd $CURRENT_LOCATION

if [[ $REMOVE_GIT_DIRECTORY ]] && [[ -d "$REPOSITORY_PATH" ]];
then # git directory 삭제 명령이 있으면 삭제
    echo
    echo "[Linux] rm repository('$REPOSITORY_PATH')"
    rm -rf $REPOSITORY_PATH
    echo

    set_to_look_great
fi

echo "-------------------------------------------"
echo "-------------------------------------------"
echo "-------------------------------------------"
echo
echo "Bye~"

properties

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
# git repository 주소 (protocol은 제외하고 작성해야함)
# clone시 id:password@url 형태로 만들기 때문에
git_repository_url=gitlab.ymtech.co.kr/test/test.git

# git branch 정보
git_repository_branch=master

# git 계정정보
git_id=id
git_password=password

# git clone 받은 repository를 저장할 directory 
# 절대 경로로 설정
git_directory=/root/deploy/test-repository

# mvn 실행 명령어
# mvn_execute_command=mvn clean package
mvn_execute_command=mvn clean package

# mvn 실행 후 결과 directory
mvn_execute_result_directory=deploy

# service 실행 command
# 'mvn_execute_result_directory' 안에서 실행할 명령어
service_execute_command=./deploy.sh

crontab

1
2
3
4
5
6
7
8
# 매일 새벽 1시 59분에 cron 동작 log를 남기기 위한 directory를 생성
59 1 * * * mkdir -p /opt/<service>/logs/cron_log

# 매일 새벽 2시에 배포하고, 로그를 남기는 cron 설정
0 2 * * * /root/deploy/deploy.sh -c /root/deploy/service.conf >> /opt/<service>/logs/deploy/service_$(date +\%Y\%m\%d\%H\%M\%S).log 2>&1

# 매일 새벽 2시 1분에 작성일 기준 28일이 지난 log를 삭제하는 cron 설정
1 2 * * * (/opt/<service>/logs/deploy/* -ctime + 28 -exec rm -rf {} \;)
This post is licensed under CC BY 4.0 by the author.