Skip to content

Commit

Permalink
[FU-63] Github Action + AWS CodeDeploy를 사용하여 CI/CD 구축 (#5)
Browse files Browse the repository at this point in the history
* FU-63 feat: CI/CD를 수행할 작업스크립트 deploy.yml 추가

* FU-63 feat: code deploy가 수행할 작업스크립트 appspec.yml 프로젝트 루트 경로에 추가

* FU-63 fix: appspec.yml에서 destination경로 수정

* FU-63 feat: 애플리케이션을 실행하는 스크립트 start.sh 추가

* FU-63 feat: 실행 중인 애플리케이션을 중지하는 스크립트 stop.sh 추가

* FU-63 feat: Personal Access Token권한 부족으로 워크플로우 폴더 삭제

* FU-63 feat: CI/CD을 위한 작업스크립트 deploy.yml 추가

* FU-63 feat: deploy.yml에서 step 이름 수정

* FU-63 feat: deploy.yml steps의 첫번째 작업 제목 삭제

* FU-63 feat: deploy.yml에서 ubuntu version 변경

* FU-63 fix: start.sh에서 jar파일명 오류 수정

* FU-63 feat: start.sh에서 jar 실행 명령어 변경

* FU-63 feat: start.sh에서 service_pid를 찾는 명령어 변경

* FU-63 feat: start.sh에서 service_pid 찾는 명령어 변경

* FU-63 feat: start.sh에서 jar 실행 명령어 변경

* FU-63 feat: start.sh에서 jar파일 실행 명령어 변경

* FU-63 feat: start.sh에서 service_pid 찾는 명령어 변경

* FU-63 chore: start.sh에서 공백 제거

* FU-63 style: stop.sh에서 주석 삭제

* FU-63 feat: github.yml 추가

* FU-63 feat: github.yml에 AWS_REGION 환경 변수 추가

* FU-63 fix: github.yml에서 공백 수정

* FU-63 feat: github.yml 삭제

* FU-63 chore: test

* FU-63 feat: start.sh에서 권한 추가

* FU-63 feat: appspec.yml에서 pattern 추가

* FU-63 feat: appspec.yml에서 runas : root 추가

* FU-63 feat: start.sh에서 권한 부여 삭제

* FU-63 feat: gitHub.yml 추가

* FU-63 fix: gitHub.yml에서 오탈자 수정

* FU-63 feat: github.yml에서 환경변수 바인딩 수정

* FU-63 feat: deploy.yml 삭제

* FU-63 feat: github.yml에서 s3 업로드 경로 변경

* FU-63 feat: start.sh에 .env 환경변수 적용 명령어 추가

* FU-63 fix: start.sh에서 .env 적용 스크립트 변경

* FU-63 feat: github.yml에서 tracking하는 부분에서 PR파트 삭제

* FU-63 CI/CD 과정에서 test 코드에 대한 검증 단계를 추가

* FU-63 feat: push branch를 test branch로 변경

* FU-63 feat: develop 브랜치에 push 할 때 수행되는 cd_workflow 추가

* FU-63 refactor: github.yml을 ci workflow로 리팩터링

* FU-63 feat: test code DB를 h2 in-memory로 세팅

* FU-63 feat: DB관련 환경변수를 ci_workflow에 추가

* FU-63 fix: ci_workflow_dev name 오타 수정

---------

Co-authored-by: [email protected] <[email protected]>
  • Loading branch information
yuseok0215 and [email protected] authored Jul 30, 2024
1 parent cdef246 commit a006b42
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 45 deletions.
58 changes: 58 additions & 0 deletions .github/workflows/cd_workflow_dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Backend Dev Server CD

on:
push:
branches: [ "develop" ]

jobs:
build:
runs-on: ubuntu-22.04

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: JDK 17 설치
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'corretto'

- name: env 설정
run: |
echo "SPRING_DATASOURCE_URL=${{ secrets.SPRING_DATASOURCE_URL }}" >> .env
echo "SPRING_DATASOURCE_USERNAME=${{ secrets.SPRING_DATASOURCE_USERNAME }}" >> .env
echo "SPRING_DATASOURCE_PASSWORD=${{ secrets.SPRING_DATASOURCE_PASSWORD }}" >> .env
echo "AWS_REGION=${{ secrets.AWS_REGION }}" >> .env
echo "AWS_CODE_DEPLOY_APPLICATION=${{ secrets.AWS_CODE_DEPLOY_APPLICATION }}" >> .env
echo "AWS_CODE_DEPLOY_GROUP=${{ secrets.AWS_CODE_DEPLOY_GROUP }}" >> .env
echo "AWS_S3_BUCKET=${{ secrets.AWS_S3_BUCKET }}" >> .env
echo "AWS_ACCESS_KEY=${{ secrets.CICD_ACCESS_KEY }}" >> .env
echo "AWS_SECRET_KEY=${{ secrets.CICD_SECRET_KEY }}" >> .env
- name: gradlew에 실행 권한 부여
run: chmod +x ./gradlew

- name: 프로젝트 빌드
run: ./gradlew clean bootjar -x test

- name: 압축
run: zip -r ./freebe.zip .

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.CICD_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.CICD_SECRET_KEY }}
aws-region: ${{ secrets.AWS_REGION }}

- name: S3에 업로드
run: aws s3 cp freebe.zip s3://${{secrets.AWS_S3_BUCKET}}/cicdtest/freebe.zip --region ap-northeast-2

- name: Code Deploy 로 배포
run: >
aws deploy create-deployment --application-name ${{ secrets.AWS_CODE_DEPLOY_APPLICATION }}
--deployment-config-name CodeDeployDefault.AllAtOnce
--deployment-group-name ${{ secrets.AWS_CODE_DEPLOY_GROUP }}
--s3-location bucket=${{ secrets.AWS_S3_BUCKET }},bundleType=zip,key=cicdtest/freebe.zip
31 changes: 31 additions & 0 deletions .github/workflows/ci_workflow_dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Backend Dev Server CI

on:
pull_request:
branches: [ "develop" ]



jobs:
build:
runs-on: ubuntu-22.04
env:
SPRING_DATASOURCE_URL: 'jdbc:mysql://freebe-database.cvqyku8gmbgo.ap-northeast-2.rds.amazonaws.com:3306/freebe_rds'
SPRING_DATASOURCE_USERNAME: 'yuseok'
SPRING_DATASOURCE_PASSWORD: 'dbtjrz123'

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: JDK 17 설치
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'corretto'

- name: gradlew에 실행 권한 부여
run: chmod +x ./gradlew

- name: test code 실행
run: ./gradlew test
23 changes: 23 additions & 0 deletions appspec.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
version: 0.0
os: linux

files:
- source: /
destination: /home/ubuntu/freebe-backend
overwrite: yes

permissions:
- object: /
pattern: "**"
owner: ubuntu
group: ubuntu

hooks:
AfterInstall:
- location: scripts/stop.sh
timeout: 60
runas : root
ApplicationStart:
- location: scripts/start.sh
timeout: 60
runas : root
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ dependencies {
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testRuntimeOnly 'com.h2database:h2'
}

tasks.named('test') {
Expand Down
23 changes: 23 additions & 0 deletions scripts/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash

set -o allexport
source /home/ubuntu/freebe-backend/.env
set +o allexport

ROOT_PATH="/home/ubuntu/freebe-backend"
JAR="$ROOT_PATH/application.jar"

APP_LOG="$ROOT_PATH/application.log"
ERROR_LOG="$ROOT_PATH/error.log"
START_LOG="$ROOT_PATH/start.log"

NOW=$(date +%c)

echo "[$NOW] $JAR 복사" >> $START_LOG
cp $ROOT_PATH/build/libs/freebe-0.0.1-SNAPSHOT.jar $JAR

echo "[$NOW] > $JAR 실행" >> $START_LOG
nohup java -jar $JAR > $APP_LOG 2> $ERROR_LOG &

SERVICE_PID=$(pgrep -f $JAR)
echo "[$NOW] > 서비스 PID: $SERVICE_PID" >> $START_LOG
13 changes: 13 additions & 0 deletions scripts/stop.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash

ROOT_PATH="/home/ubuntu/freebe-backend"
JAR="$ROOT_PATH/application.jar"
STOP_LOG="$ROOT_PATH/stop.log"
SERVICE_PID=$(pgrep -f $JAR)

if [ -z "$SERVICE_PID" ]; then
echo "서비스 NouFound" >> $STOP_LOG
else
echo "서비스 종료 " >> $STOP_LOG
kill "$SERVICE_PID"
fi
75 changes: 37 additions & 38 deletions src/test/java/com/foru/freebe/member/MemberRepositoryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.ActiveProfiles;

Expand All @@ -16,50 +15,50 @@
import com.foru.freebe.member.repository.MemberRepository;

@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
// @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ActiveProfiles("test")
public class MemberRepositoryTest {
@Autowired
private MemberRepository memberRepository;
private Member member;
@Autowired
private MemberRepository memberRepository;
private Member member;

@BeforeEach
public void setUp() {
member = Member.builder(1111111111L, Role.ROLE_USER, "test Member", "[email protected]", "+82 10-0000-0000")
.instagramId("testInstagramId")
.build();
}
@BeforeEach
public void setUp() {
member = Member.builder(1111111111L, Role.ROLE_USER, "test Member", "[email protected]", "+82 10-0000-0000")
.instagramId("testInstagramId")
.build();
}

@Test
public void testSaveMember() {
//when
Member savedMember = memberRepository.save(member);
@Test
public void testSaveMember() {
//when
Member savedMember = memberRepository.save(member);

//then
assertThat(savedMember).isNotNull();
assertThat(savedMember.getId()).isNotNull();
assertThat(savedMember.getEmail()).isEqualTo(member.getEmail());
assertThat(savedMember.getName()).isEqualTo(member.getName());
assertThat(savedMember.getPhoneNumber()).isEqualTo(member.getPhoneNumber());
assertThat(savedMember.getKakaoId()).isEqualTo(member.getKakaoId());
assertThat(savedMember.getInstagramId()).isEqualTo(member.getInstagramId());
}
//then
assertThat(savedMember).isNotNull();
assertThat(savedMember.getId()).isNotNull();
assertThat(savedMember.getEmail()).isEqualTo(member.getEmail());
assertThat(savedMember.getName()).isEqualTo(member.getName());
assertThat(savedMember.getPhoneNumber()).isEqualTo(member.getPhoneNumber());
assertThat(savedMember.getKakaoId()).isEqualTo(member.getKakaoId());
assertThat(savedMember.getInstagramId()).isEqualTo(member.getInstagramId());
}

@Test
public void testFindByKakaoId() {
//given
memberRepository.save(member);
@Test
public void testFindByKakaoId() {
//given
memberRepository.save(member);

//when
Optional<Member> foundMember = memberRepository.findByKakaoId(member.getKakaoId());
//when
Optional<Member> foundMember = memberRepository.findByKakaoId(member.getKakaoId());

// Then
assertThat(foundMember).isPresent();
assertThat(foundMember.get().getEmail()).isEqualTo(member.getEmail());
assertThat(foundMember.get().getName()).isEqualTo(member.getName());
assertThat(foundMember.get().getPhoneNumber()).isEqualTo(member.getPhoneNumber());
assertThat(foundMember.get().getKakaoId()).isEqualTo(member.getKakaoId());
assertThat(foundMember.get().getInstagramId()).isEqualTo(member.getInstagramId());
}
// Then
assertThat(foundMember).isPresent();
assertThat(foundMember.get().getEmail()).isEqualTo(member.getEmail());
assertThat(foundMember.get().getName()).isEqualTo(member.getName());
assertThat(foundMember.get().getPhoneNumber()).isEqualTo(member.getPhoneNumber());
assertThat(foundMember.get().getKakaoId()).isEqualTo(member.getKakaoId());
assertThat(foundMember.get().getInstagramId()).isEqualTo(member.getInstagramId());
}

}
13 changes: 6 additions & 7 deletions src/test/resources/application-test.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: ${TEST_DATASOURCE_URL}
username: ${TEST_DATASOURCE_USERNAME}
password: ${TEST_DATASOURCE_PASSWORD}

url: jdbc:h2:mem:test
driverClassName: org.h2.Driver
username: sa
password: test123
jpa:
hibernate:
ddl-auto: create
properties:
hibernate:
show_sql: true
dialect: org.hibernate.dialect.H2Dialect
format_sql: true
dialect: org.hibernate.dialect.MySQLDialect
show_sql: true

0 comments on commit a006b42

Please sign in to comment.