Skip to content

Commit

Permalink
Merge pull request #3 from OurMenu/feat/deploy
Browse files Browse the repository at this point in the history
Feat/deploy
  • Loading branch information
david-parkk authored Jul 21, 2024
2 parents 6ceae9a + 12c72aa commit ee1ff8b
Show file tree
Hide file tree
Showing 29 changed files with 723 additions and 14 deletions.
13 changes: 13 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
### ✏️ 작업 개요


### ⛳ 작업 분류
- [ ] 작업1
- [ ] 작업2
- [ ] 작업3

### 🔨 작업 상세 내용
1.

### 💡 생각해볼 문제
- 생각해볼 내용을 적습니다
109 changes: 109 additions & 0 deletions .github/workflows/CD.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
name: Java CD with Gradle

on:
issue_comment:
types: [ created, edited ]

jobs:
build:
if: github.event.issue.pull_request && contains(github.event.comment.body, '/아워메뉴') && contains(github.event.comment.body, '배포')
runs-on: ubuntu-latest
permissions:
write-all
services:
mysql:
image: mysql:8.0
ports:
- 3306:3306
env:
MYSQL_DATABASE: testdb
MYSQL_ROOT_PASSWORD: testdb
options: >-
--health-cmd="mysqladmin ping --silent"
--health-interval=10s
--health-timeout=5s
--health-retries=3
steps:
- uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'

# Configure Gradle for optimal use in GiHub Actions, including caching of downloaded dependencies.
# See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md
- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Setup Gradle
uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0

- name: Build with Gradle Wrapper
env:
SPRING_DATASOURCE_URL: jdbc:mysql://127.0.0.1:3306/testdb
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: testdb
run: ./gradlew build --stacktrace

# dockerfile을 통해 이미지를 빌드하고, 이를 docker repo로 push
- name: docker login
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Build Push Docker images
run: |
docker build -f Dockerfile -t ${{ secrets.DOCKER_REPO }} .
docker push ${{ secrets.DOCKER_REPO }}
deploy:
needs: build
runs-on: ubuntu-latest
permissions:
write-all
steps:
# appleboy/ssh-action@master 액션을 사용하여 지정한 서버에 ssh로 접속하고, script를 실행합니다.
# script의 내용은 도커의 기존 프로세스들을 제거하고, docker repo로부터 방금 위에서 push한 내용을 pull 받아 실행하는 것입니다.
# 실행 시, docker-compose를 사용합니다.
- name: Deploy to server
uses: appleboy/ssh-action@master
env:
COMPOSE: ${{ secrets.DOCKER_COMPOSE }}
id: deploy
with:
host: ${{ secrets.HOST }}
username: ubuntu
port: 22
key: ${{ secrets.KEY }}
envs: GITHUB_SHA
script: |
sudo docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
cd ${{secrets.PROJECT_PATH}}
sudo docker-compose down
sudo docker rm $(sudo docker ps -a -q)
sudo docker rmi $(sudo docker images -q)
sudo docker pull ${{secrets.DOCKER_REPO }}
sudo docker-compose up --build -d
- name: Notify
uses: actions/github-script@v5
with:
github-token: ${{secrets.TOKEN}}
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '🌎 배포하였습니다.'
})
- name: add label
uses: actions-ecosystem/action-add-labels@v1
with:
labels: ":satellite: 자동 배포"
93 changes: 93 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle

name: Java CI with Gradle

on:
pull_request:
branches: [ "main" ]

jobs:
build:
runs-on: ubuntu-latest
permissions:
write-all
#contents: read
services:
mysql:
image: mysql:8.0
ports:
- 3306:3306
env:
MYSQL_DATABASE: testdb
MYSQL_ROOT_PASSWORD: testdb
options: >-
--health-cmd="mysqladmin ping --silent"
--health-interval=10s
--health-timeout=5s
--health-retries=3
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'

# Configure Gradle for optimal use in GiHub Actions, including caching of downloaded dependencies.
# See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md
- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Setup Gradle
uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0

- name: Build with Gradle Wrapper
env:
SPRING_DATASOURCE_URL: jdbc:mysql://127.0.0.1:3306/testdb
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: testdb
run: ./gradlew build --stacktrace


# Test 후 Report 생성
- name: Publish Test Results
uses: EnricoMi/publish-unit-test-result-action@v2
if: always()
with:
junit_files: '**/build/test-results/test/TEST-*.xml'
# NOTE: The Gradle Wrapper is the default and recommended way to run Gradle (https://docs.gradle.org/current/userguide/gradle_wrapper.html).
# If your project does not have the Gradle Wrapper configured, you can use the following configuration to run Gradle with a specified version.
#
# - name: Setup Gradle
# uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0
# with:
# gradle-version: '8.5'
#
# - name: Build with Gradle 8.5
# run: gradle build

dependency-submission:

runs-on: ubuntu-latest
permissions:
contents: write

steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'

# Generates and submits a dependency graph, enabling Dependabot Alerts for all project dependencies.
# See: https://github.com/gradle/actions/blob/main/dependency-submission/README.md
- name: Generate and submit dependency graph
uses: gradle/actions/dependency-submission@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0


1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
git HELP.md
.env
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
Expand Down
5 changes: 5 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM openjdk:17-jdk-slim
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
# docker-compose build --no-cache
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
## OurMenu backend
### git convention
| 태그이름 | 내용 |
|------------|---------------------------------------------|
| `feat` | 새로운 기능을 추가할 경우 |
| `fix ` | 버그를 고친 경우 |
| `style` | 코드 포맷 변경, 세미 콜론 누락, 코드 수정이 없는 경우 |
| `refactor` | 코드 리팩토링 |
| `comment` | 필요한 주석 추가 및 변경 |
| `docs` | 문서, Swagger 를 수정한 경우 |
| `test` | 테스트 추가, 테스트 리팩토링(프로덕션 코드 변경 X) |
| `chore` | 빌드 태스트 업데이트, 패키지 매니저를 설정하는 경우(프로덕션 코드 변경 X) |
| `rename` | 파일 혹은 폴더명을 수정하거나 옮기는 작업만인 경우 |
| `remove` | 파일을 삭제하는 작업만 수행한 경우 |
###

### review
- PR은 코드 변경이 없는 경우를 제외하고 리뷰와 승인을 필요로 합니다
- PR는 build가 성공되는 경우에 merge 할 수 있도록 합니다.
- main는 최종, develop은 개발 branch이고, 브랜치명으로 해당 작업을 명세합니다 ex) feat/deploy
- [패키지를 도메인별로 분리하는 작업합니다](https://velog.io/@jsb100800/Spring-boot-directory-package)
-
14 changes: 14 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,22 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
//mysql,jpa
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.mysql:mysql-connector-j'
//lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
//swagger
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'
//validation
implementation 'org.springframework.boot:spring-boot-starter-validation'
}

tasks.named('test') {
useJUnitPlatform()
}

jar {
enabled = false
}
43 changes: 43 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
version: '3'

services:
database:
container_name: mysql_db
image: mysql/mysql-server:5.7
restart: unless-stopped
environment:
MYSQL_DATABASE: users_db
MYSQL_ROOT_HOST: '%'
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
TZ: 'Asia/Seoul'
ports:
- "8081:3306"
#volumes:
# - ./mysql/conf.d:/etc/mysql/conf.d # MySQL 설정 파일 위치
command:
- "mysqld"
- "--character-set-server=utf8mb4"
- "--collation-server=utf8mb4_unicode_ci"
networks:
- test_network

application:
container_name: docker-compose-test
restart: on-failure
image: ji0513ji/ourmenu:latest
# build:
# context: ./
# dockerfile: Dockerfile
ports:
- "8080:8080"
environment:
SPRING_DATASOURCE_URL: ${SPRING_DATASOURCE_URL}
SPRING_DATASOURCE_USERNAME: ${SPRING_DATASOURCE_USERNAME}
SPRING_DATASOURCE_PASSWORD: ${SPRING_DATASOURCE_PASSWORD}
depends_on:
- database
networks:
- test_network

networks:
test_network:
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.ourMenu.backend.domain.test.api;

import com.ourMenu.backend.domain.test.api.request.SaveEntityRequest;
import com.ourMenu.backend.domain.test.api.request.SaveJdbcRequest;
import com.ourMenu.backend.domain.test.api.response.FindEntityByIdResponse;
import com.ourMenu.backend.domain.test.api.response.FindJdbcByIdResponse;
import com.ourMenu.backend.domain.test.api.response.SaveEntityResponse;
import com.ourMenu.backend.domain.test.application.TestService;
import com.ourMenu.backend.domain.test.domain.JdbcEntity;
import com.ourMenu.backend.domain.test.domain.TestEntity;
import com.ourMenu.backend.global.common.ApiResponse;
import com.ourMenu.backend.global.util.ApiUtils;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;

@RestController
@RequestMapping(path = "api/test")
@RequiredArgsConstructor
public class TestController {

private final TestService testService;

@PostMapping("/jpa/save")
@Operation(summary = "테스트회원 저장", description = "swagger 테스트를 위한 저장 API")
public ApiResponse<SaveEntityResponse> saveTestEntity(@RequestBody SaveEntityRequest saveEntityRequest) throws IOException {
TestEntity testEntity=TestEntity
.builder()
.name(saveEntityRequest.name())
.build();

TestEntity saveTestEntity = testService.saveTestEntity(testEntity);

SaveEntityResponse saveEntityResponse = SaveEntityResponse
.builder()
.id(saveTestEntity.getId())
.name(saveEntityRequest.name())
.build();
return ApiUtils.success(saveEntityResponse);
}

@GetMapping("/jpa/{SaveEntityId}")
@Operation(summary = "테스트회원 조회", description = "swagger 테스트를 위한 조회 API")
public ApiResponse<FindEntityByIdResponse> findById(@PathVariable("SaveEntityId")Long saveEntityId){
TestEntity findTestEntity = testService.findTestEntity(saveEntityId);
FindEntityByIdResponse findEntityByIdResponse = FindEntityByIdResponse
.builder()
.id(findTestEntity.getId())
.name(findTestEntity.getName())
.build();
return ApiUtils.success(findEntityByIdResponse);
}

@PostMapping("/jdbc/save")
public void save(@RequestBody @Valid SaveJdbcRequest saveJdbcRequest){
testService.saveJdbcEntity(saveJdbcRequest.name());
}

@GetMapping("/jdbc/{SaveEntityId}")
public ApiResponse<FindJdbcByIdResponse> findJdbcEntityById(@PathVariable("SaveEntityId")Long saveEntityId){
JdbcEntity jdbcEntity = testService.findJdbcEntity(saveEntityId);
FindJdbcByIdResponse findJdbcByIdResponse = FindJdbcByIdResponse
.builder()
.id(jdbcEntity.getId())
.name(jdbcEntity.getName())
.build();
return ApiUtils.success(findJdbcByIdResponse);
}
}
Loading

0 comments on commit ee1ff8b

Please sign in to comment.