2024. 7. 2. 21:58ㆍ개발 고민
목차
- branch 분리 구현 이유 및 방식
- gradle.yml 파일 전략 변경점
branch 분리 구현 이유 및 방식
자동화 배포로 인해 원치 않은 자료까지 배포되던 문제 해결을 위한 방법으로 개발 branch와 배포 branch를 분리해 사용하기로 하였다.
기존 프로젝트에서 저장 및 배포는 master 브랜치에서 이뤄졌다. 이론상으로 많은 사람들이 배포와 개발을 분리해서 진행하는 것이 옳다는 것을 알았지만 이번 자동화 배포를 왜 그렇게 하는지 절실하게 느끼게 되었다.
1. 문제점 단일 브랜치를 이용 문제
단일 브랜치(master)에서 개발/배포를 동시에 진행하면 별도의 pull request 없이 push하는 순간 테스트 후 자동 배포가 된다. 별도 작업 없이 push만하면 배포가되니 편하기는 했지만 하나의 컴퓨터를 이용할 때는 문제가 없었지만 개발이 완료되지 않은 기능을 push해야될 때 문제가 발생하였다. 외부에서 개발을 해야되는 경우 완료되지 않은 기능을 다른 컴퓨터에도 동기화해야되기 때문에 어쩔 수 없이 push를 해야되지만 단일 브랜치의 경우 ci/cd 구현을 해놨기 때문에 실제로 사용하는 프로그램이 망가지는 문제가 발생하였다.
2. 문제점 테스트를 위한 파일 수정 후 재변경
단일 브랜치에서 사용할 때 기능 구현 확인을 위해 프로젝트를 실행할 때 yml 파일을 testDB에 연결해 사용하였다. 하지만 재배포과정에서 변경된 환경을 다시 롤백하는데 실수를 해 실제 DB를 초기화를 하는 등의 문제가 발생하였다.
gradle.yml 파일 전략 변경점
두개의 브랜치를 이용해 ci/cd 배포 전략을 수정했다.
master의 경우 develop에서 수행한 테스트가 성공했을 때 pull request를 통해 병합을 한 경우 해당 파일을 재배포하는 방식
develop의 경우 로컬환경에서 push된 코드를 테스트하고 성공한 경우 pull reqeust를 대기한다.
name: CI/CD using GitHub Actions & Docker
on:
push:
branches:
- develop
pull_request:
types: [closed]
jobs:
build:
if: github.ref == 'refs/heads/develop'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Grant execute permission for Gradle
run: chmod +x ./gradlew
- name: Create application-api.properties
run: |
echo "naver-cloud-sms.accessKey=${{ secrets.ACCESS_KEY }}" >> src/main/resources/application-api.properties
echo "naver-cloud-sms.secretKey=${{ secrets.SECRET_KEY }}" >> src/main/resources/application-api.properties
echo "naver-cloud-sms.serviceId=${{ secrets.SERVICE_ID }}" >> src/main/resources/application-api.properties
echo "naver-cloud-sms.senderPhone=${{ secrets.PHONE }}" >> src/main/resources/application-api.properties
echo "SERVER_URL=${{ secrets.DB_URL }}" >> src/main/resources/application-api.properties
echo "DB_PASSWORD=${{ secrets.DB_PASSWORD }}" >> src/main/resources/application-api.properties
- name: Display application-api.properties content for verification
run: cat src/main/resources/application-api.properties
- name: Run tests
run: ./gradlew test
- name: Build JAR
run: ./gradlew clean build -x test
- name: Set artifact
run: echo "artifact=$(ls ./build/libs)" >> $GITHUB_ENV
- name: Build Docker image
run: |
docker build -t 이미지 이름/버전 .
echo "DOCKER_IMAGE=이미지 이름/버전" >> $GITHUB_ENV
- name: Log in to Docker Hub
run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
- name: Push Docker image to Docker Hub
run: docker push ${{ env.DOCKER_IMAGE }}
deploy:
if: ${{ github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'master' }}
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- name: Log in to Docker Hub
run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
- name: Set up SSH connection
uses: webfactory/ssh-agent@v0.5.3
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
- name: SSH into Synology NAS and deploy
env:
NAS_USERNAME: ${{ secrets.NAS_USERNAME }}
NAS_PASSWORD: ${{ secrets.NAS_PASSWORD }}
NAS_HOST: ${{ secrets.NAS_HOST }}
SSH_PORT: ${{ secrets.NAS_SSH_PORT }}
DOCKER_IMAGE: "이미지 이름/버전"
run: |
sshpass -p "$NAS_PASSWORD" ssh -o StrictHostKeyChecking=no -p $SSH_PORT $NAS_USERNAME@$NAS_HOST << EOF
docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
docker pull $DOCKER_IMAGE
docker stop 실행 중인 컨테이너 이름 || true
docker rm 컨테이너 이미지 이름 || true
docker run -d --name 컨테이너 이름 \
-p 8002:8002 ${{ env.DOCKER_IMAGE }}
EOF
'개발 고민' 카테고리의 다른 글
PostMan을 이용한 Auth2.0 KAKAO Login Test (1) | 2024.11.27 |
---|---|
[Spring] SSR에서 JWT를 이용한 인증/인가 처리 고민 (2) | 2024.02.14 |