들어가기에 앞서 적용기 (1)에 이어서 모노레포 구조 변경과 CI 작업을 수행하게 되면서 회사 본부에 공유하게 된 내용을 작성하였습니다.
어드민 모노레포를 수행하면서 변경된 구조에 대한 공유와 더불어 최근 여러 사업건들의 배포들로 인한 CI 환경을 구성한 부분을 공유하고자 가이드 작성합니다.
# 어드민 모노레포 gitlab-ci 파이프라인
# 환경 별 어드민 빌드하고 AppStore의 서비스에 등록한다.
# Author: soohyun
# 시나리오
# Stage 1: build
# - 배포를 위해 빌드하고 dist 파일을 zip 파일로 저장한다.
# Stage 2: deploy
# - IS_DEPLOY 일 경우 apache에 해당 zip 파일을 배포한다.
# - IS_DEPLOY 이면서 BUSINESS_NAME이 foodist인 경우 shell의 fix/admin-module 브랜치로 커밋 & 푸시한다.
# - IS_DEPLOY 가 없을 경우 앱스토어에 해당 zip 파일 요청하여 실환경에 반영한다.
image: docker:23.0.0-rc.1-cli-alpine3.17
stages:
- build
- deploy
build:
stage: build
variables:
VERSION_NAME: ''
before_script:
- apk upgrade
- apk update
- apk add nodejs npm zip
- apk add --no-cache bash
script:
- npm install -g pnpm@8.15.8
- pnpm install
- BUSINESS_NAME=$(echo ${CI_COMMIT_TAG} | awk -F"_" '{print $1}')
- echo 'BUSINESS_NAME :::' ${BUSINESS_NAME}
- APP_NAME=$(echo ${CI_COMMIT_TAG} | awk -F"_" '{print $2}')
- echo 'APP_NAME :::' ${APP_NAME}
- VERSION_NAME=$(echo ${CI_COMMIT_TAG} | awk -F"_" '{print $3}')
- echo 'VERSION_NAME :::' ${VERSION_NAME}
- |
if [ "${BUSINESS_NAME}" != "ekr" ] && [ "${BUSINESS_NAME}" != "superApp" ] && [ "${BUSINESS_NAME}" != "foodist" ]; then
echo "BUSINESS_NAME is ekr or superApp or foodist"
exit 1
fi
- |
if [ -z "${VERSION_NAME}" ]; then
echo "VERSION_NAME is Required"
exit 1
fi
- |
case "${APP_NAME}" in
appmaster)
APP_NAME="app-master"
;;
admin)
APP_NAME="${BUSINESS_NAME}-admin"
;;
*)
echo "Invalid APP_NAME"
exit 1
;;
esac
echo 'Modified APP_NAME :::' ${APP_NAME}
- pnpm ${APP_NAME}_ci ${VERSION_NAME}
- cd apps/${APP_NAME}/build
- zip -r ../../../target.zip .
- cd ../../../
- ls -la
artifacts:
paths:
- target.zip
expire_in: 1 hour
only:
- tags
tags:
- pl2-2
deploy:
stage: deploy
variables:
APACHE_IP: 220.90.208.23
APACHE_ID: ***
APACHE_PW: ***
before_script:
- apk update
- apk add nodejs npm sshpass unzip git
- apk add --no-cache bash
- npm install -g pnpm@8.15.8
- pnpm install
- export BUSINESS_NAME=$(echo ${CI_COMMIT_TAG} | awk -F"_" '{print $1}')
- export APP_NAME=$(echo ${CI_COMMIT_TAG} | awk -F"_" '{print $2}')
- export VERSION_NAME=$(echo ${CI_COMMIT_TAG} | awk -F"_" '{print $3}')
- export DEPLOY_PATH=/usr/local/apache2/htdocs/${BUSINESS_NAME}/wapl-${APP_NAME}-front
- export IS_DEPLOY=$(echo ${CI_COMMIT_TAG} | awk -F"_" '{print $4}')
- export USER_NAME=***
- export PRIVATE_ACCESS_TOKEN=***
script:
- echo 'BUSINESS_NAME :::' ${BUSINESS_NAME} 'APACHE_IP :::' ${APACHE_IP}
- echo 'VERSION_NAME :::' ${VERSION_NAME} 'APACHE_PW :::' ${APACHE_PW}
- echo 'DEPLOY_PATH :::' ${DEPLOY_PATH} 'IS_DEPLOY :::' ${IS_DEPLOY}
- |
if [ "${BUSINESS_NAME}" != "foodist" ] && [ "$IS_DEPLOY" = "deploy" ]; then
ls -al
echo "Uploading target.zip to ${DEPLOY_PATH}/${BUSINESS_NAME}-wapl-${APP_NAME}-web-${VERSION_NAME}.zip"
sshpass -p ${APACHE_PW} ssh -o StrictHostKeyChecking=no ${APACHE_ID}@${APACHE_IP} "cd ${DEPLOY_PATH}; echo 'Current directory:'; pwd"
sshpass -p ${APACHE_PW} scp -o StrictHostKeyChecking=no target.zip ${APACHE_ID}@${APACHE_IP}:${DEPLOY_PATH}/${BUSINESS_NAME}-wapl-${APP_NAME}-web-${VERSION_NAME}.zip
echo 'Apache Deploy Finished'
# 푸디스트와 같은 경우는 쉘git에 새로운 branch만들어서 커밋하고 푸시합니다.
elif [ "${BUSINESS_NAME}" = "foodist" ] && [ "$IS_DEPLOY" = "deploy" ]; then
ls -al
echo "wapl-shell.git clone....."
git clone http://${USER_NAME}:${PRIVATE_ACCESS_TOKEN}@192.168.158.11/wapl/wapl-shell.git temp_shell
cd temp_shell
echo "cd temp_shell"
git checkout develop_foodist
rm -rf ./public/apps/admin/*
ls -al
unzip ../target.zip -d ./public/apps/admin
# 각 환경 runner 돌릴 담당자의 username 키와 private_access_token 값 넣어주시면 됩니다.
git config user.email "***"
git config user.name "${USER_NAME}"
git branch -D fix/admin-module || true
git checkout -b fix/admin-module
git add .
git commit -m "fix: admin modules fixed"
git push http://${USER_NAME}:${PRIVATE_ACCESS_TOKEN}@192.168.158.11/wapl/wapl-shell.git fix/admin-module
ls -al
echo 'Foodist Admin Deploy Finished'
else
ls -al
echo "Starting WebSocket operation"
node scripts/ci/wsClient.js 3 ${VERSION_NAME} ${BUSINESS_NAME}
echo "Finishing WebSocket AppStore Uploaded"
fi
dependencies:
- build
only:
- tags
tags:
- pl2-2
이 가이드는 모노레포 환경 별 어드민을 빌드하고 AppStore의 서비스에 등록하거나 실환경에 배포하는 등의 자동화 파이프라인을 포함하고 있습니다.
build
결과 파일을 target.zip
파일로 저장합니다.IS_DEPLOY
가 deploy
일 경우 Apache에 해당 zip
파일을 배포합니다.IS_DEPLOY
가 deploy
이면서 BUSINESS_NAME
이 foodist인 경우 shell의 fix/admin-module
브랜치로 커밋 & 푸시합니다.IS_DEPLOY
가 없을 경우 WebSocket
을 통해 해당 zip
파일을 앱스토어에 업로드 하고 실환경에 반영합니다.APACHE_IP
: Apache 서버의 IP 주소APACHE_ID
: Apache 서버에 접속할 사용자 IDAPACHE_PW
: Apache 서버에 접속할 사용자 비밀번호BUSINESS_NAME
: 태그에서 추출한 비즈니스 이름APP_NAME
: 태그에서 추출한 애플리케이션 이름VERSION_NAME
: 태그에서 추출한 버전 이름IS_DEPLOY
: 태그에서 추출한 배포 여부 변수태그는 ${BUSINESS_NAME}_${APP_NAME}_${VERSION_NAME}_${IS_DEPLOY}
형식을 따라야 합니다. 각 필드는 다음과 같은 의미를 가집니다:
BUSINESS_NAME
: 비즈니스 이름 (예: superApp, ekr, foodist)APP_NAME
: 애플리케이션 이름 (예: appmaster, ekr, foodist)VERSION_NAME
: 버전 이름 (예: 실환경(앱스토어): v1.0.0, 아파치: 1.0.0)IS_DEPLOY
: 배포 여부IS_DEPLOY
같은 경우 생략 가능합니다. 생략일 경우 실환경에 반영예시
ekr_admin_1.0.0
foodist_admin_v1.0.0_deploy
appmaster_1.0.0_deploy
pnpm
설치 및 의존성 설치BUSINESS_NAME
, APP_NAME
, VERSION_NAME
추출appmaster
-> app-master
, admin
-> ${BUSINESS_NAME}-admin
)${APP_NAME}_ci
명령어 실행target.zip
으로 압축BUSINESS_NAME
, APP_NAME
, VERSION_NAME
, IS_DEPLOY
추출IS_DEPLOY
가 deploy
일 경우 Apache 서버에 target.zip
을 ${BUSINESS_NAME}-wapl-${APP_NAME}-web-${VERSION_NAME}.zip
명으로 업로드BUSINESS_NAME
이 foodist
이고 IS_DEPLOY
가 deploy
일 경우 쉘의 git에 fix/admin-module
브랜치 생성 후 변경 사항 커밋 및 푸시IS_DEPLOY
가 없는 경우 앱스토어에 웹소켓을 통해 zip 파일 요청 및 실환경 반영2024년 상반기동안 여러 사업 건을 대응하면서 정신없는 와중에 진행해보고 싶었던 모노레포 구조를 적용해보고 팀원들에게 개발성을 향상 시켜주게되면서 뿌듯하기도 하고 조금 더 깊게 알게 된 것 같았습니다. 아직은 미흡하고 좀 더 개선해나가야 할 부분들이 있지만, 추가적으로 변경된 부분들은 작성할 예정입니다. 혹여나 이 글을 보게 될 분들께 조금이나마 도움이 되었으면 합니다. 감사합니다.