Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #48

Closed
wants to merge 14 commits into from
Closed

Dev #48

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Binary file added .DS_Store
Binary file not shown.
83 changes: 83 additions & 0 deletions .github/workflows/cicd-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: cicd-dev

on:
push:
branches: [ "dev" ]

env:
AWS_REGION: ap-northeast-2
ECR_REPOSITORY: dev_morandi_backend
ECR_REGISTRY: ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.ap-northeast-2.amazonaws.com/dev_morandi_backend
EC2_BASTION_HOST: ${{ secrets.RELEASE_BASTION_HOST }}
EC2_BACKEND_HOST: ${{ secrets.DEV_BACKEND_HOST }} # EC2 인스턴스의 Private IP
GITHUB_SHA: ${{ github.sha }}

permissions:
contents: read

jobs:
build-and-push:
runs-on: ubuntu-latest
env:
redis.enabled: "false"
steps:
- name: Checkout
uses: actions/checkout@v3

# Gradle 빌드를 추가합니다.
- name: Set up JDK 17
uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: '17'

- name: Cleanup application.yml
run: rm -f src/main/resources/application.yml

# GitHub Secret에서 application-prod.yml 내용을 불러와 파일로 저장
- name: Create application-dev.yml from GitHub Secret
run: |
mkdir -p src/main/resources
echo "${{ secrets.DEV_APPLICATION_YML }}" > src/main/resources/application.yml


- name: Build with Gradle
env:
ORG_GRADLE_OPTS: "-Duser.timezone=Asia/Seoul"
run: ./gradlew clean bootJar -x test

- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.ECR_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.ECR_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
mask-aws-account-id: true

- name: Login to Private ECR
run: aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin ${{ env.ECR_REGISTRY }}

- name: Build Docker Image
run: docker build -t ${{ env.ECR_REGISTRY }}:${{ github.sha }} .

- name: Push Docker Image to ECR
run: docker push ${{ env.ECR_REGISTRY }}:${{ github.sha }}

deploy:
name: Deploy to EC2
needs: build-and-push
runs-on: ubuntu-latest
env:
redis.enabled: "true"
steps:
- name: appleboy SSH and Deploy to EC2
uses: appleboy/ssh-action@master # ssh 접속하는 오픈소스
with:
host: ${{ env.EC2_BASTION_HOST }}
debug: true
key: ${{ secrets.BASTION_SSH_SECRET_KEY }}
username: ubuntu
port: 22
envs: EC2_BACKEND_HOST,GITHUB_SHA,ECR_REGISTRY
script: |
ssh -o StrictHostKeyChecking=no ubuntu@$EC2_BACKEND_HOST "export TAG=$GITHUB_SHA && bash /home/ubuntu/morandi-backend/deploy.sh"
46 changes: 46 additions & 0 deletions .github/workflows/sonarcloud.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: SonarCloud
on:
push:
branches:
- main
- dev
pull_request:
types: [opened, synchronize, reopened]
jobs:
build:
name: Build and analyze
runs-on: ubuntu-latest
env:
redis.enabled: "false"
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: 17
distribution: 'zulu' # Alternative distribution options are available

- name: Create application-test.yml from GitHub Secret
run: |
mkdir -p src/main/resources
echo "${{ secrets.TEST_APPLICATION_YML }}" > src/main/resources/application.yml

- name: Cache SonarCloud packages
uses: actions/cache@v3
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
- name: Cache Gradle packages
uses: actions/cache@v3
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
restore-keys: ${{ runner.os }}-gradle
- name: Build and analyze
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: ./gradlew build sonar --info
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
FROM openjdk:17-oracle
WORKDIR /app
COPY build/libs/*.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
183 changes: 180 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,57 @@ plugins {
id 'java'
id 'org.springframework.boot' version '3.2.2'
id 'io.spring.dependency-management' version '1.1.4'
id 'org.asciidoctor.jvm.convert' version '3.3.2'
}
plugins {
id "org.sonarqube" version "4.4.1.3373"
}

plugins {
id 'jacoco'
}


def jacocoDir = layout.buildDirectory.dir("reports/")
def QDomains = []
for (qPattern in '*.QA'..'*.QZ') { // qPattern = '*.QA', '*.QB', ... '*.QZ'
QDomains.add(qPattern + '*')
}

def jacocoExcludePatterns = [
// 측정 안하고 싶은 패턴
"**/*Application*",
"**/*Config*",
"**/*Exception*",
"**/*Request*",
"**/*Response*",
"**/*Dto*",
"**/*Interceptor*",
"**/*Filter*",
"**/*Resolver*",
"**/*Entity*",
"**/test/**",
"**/resources/**"
]

sonar {
properties {
property "sonar.projectKey", "SWM-Morandi_NewMorandi-Backend"
property "sonar.organization", "swm-morandi"
property "sonar.host.url", "https://sonarcloud.io"
property 'sonar.gradle.skipCompile', 'true'
property 'sonar.sources', 'src'
property 'sonar.language', 'java'
property 'sonar.sourceEncoding', 'UTF-8'
property 'sonar.test.exclusions', jacocoExcludePatterns.join(',')
property 'sonar.test.inclusions', '**/*Test.java'
property 'sonar.java.coveragePlugin', 'jacoco'
property 'sonar.coverage.jacoco.xmlReportPaths', jacocoDir.get().file("jacoco/index.xml").asFile
}
}

jacoco {
toolVersion = "0.8.8"
}

group = 'kr.co.morandi'
Expand All @@ -15,25 +66,151 @@ configurations {
compileOnly {
extendsFrom annotationProcessor
}

asciidoctorExt
}

repositories {
mavenCentral()
}

dependencies {

// Spring Data Jpa
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

// Spring Data Redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'

// Spring Security
implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation 'org.springframework.security:spring-security-test'

// validation
implementation 'org.springframework.boot:spring-boot-starter-validation'

// Jsoup
implementation 'org.jsoup:jsoup:1.16.1'

// Pusher java client
implementation group: 'com.pusher', name: 'pusher-java-client', version: '2.4.4'


// WebFlux (WebClient)
implementation 'org.springframework.boot:spring-boot-starter-webflux'

// Spring Web
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'

// JWT
implementation 'io.jsonwebtoken:jjwt-api:0.11.2'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.2'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.2'

// MariaDB
runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'

// lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'

// Test Dependencies
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'com.h2database:h2'

// RestDocs
asciidoctorExt 'org.springframework.restdocs:spring-restdocs-asciidoctor'
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'

// AWS SQS
implementation group: 'org.springframework.cloud', name: 'spring-cloud-aws-messaging', version: '2.2.1.RELEASE'
implementation group: 'org.springframework.cloud', name: 'spring-cloud-aws-autoconfigure', version: '2.2.1.RELEASE'
implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-aws', version: '2.2.1.RELEASE'
implementation platform("io.awspring.cloud:spring-cloud-aws-dependencies:3.0.1")
implementation 'io.awspring.cloud:spring-cloud-aws-starter-sqs'
implementation 'org.springframework:spring-messaging:6.1.3'
}

tasks.named('sonarqube').configure {
dependsOn 'compileJava'
}

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

ext { //전역 변수
snippetsDir = file("build/generated-snippets")
}

test {
outputs.dir snippetsDir
}

asciidoctor {
inputs.dir snippetsDir
configurations 'asciidoctorExt'

sources { // 특정 파일만 html로 만든다
include '**/index.adoc'
}
baseDirFollowsSourceFile() // 다른 adoc 파일을 참조할 때 경로를 baseDir 기준으로 찾음
dependsOn test
}

bootJar {
dependsOn asciidoctor
from("${asciidoctor.outputDir}") {
into 'static/docs'
}
}

jacocoTestReport {
dependsOn test
reports {
html.required.set(true)
xml.required.set(true)
csv.required.set(true)
html.destination jacocoDir.get().file("jacoco/index.html").asFile
xml.destination jacocoDir.get().file("jacoco/index.xml").asFile
csv.destination jacocoDir.get().file("jacoco/index.csv").asFile
}

afterEvaluate {
classDirectories.setFrom(
files(classDirectories.files.collect {
fileTree(dir: it, excludes: jacocoExcludePatterns + QDomains) // Querydsl 관련 제거
})
)
}
finalizedBy jacocoTestCoverageVerification
}



jacocoTestCoverageVerification {

violationRules {
rule {
enabled = true

element = 'BUNDLE'

limit {
counter = 'LINE'
value = 'COVEREDRATIO'
minimum = 0.40
}

limit {
counter = 'BRANCH'
value = 'COVEREDRATIO'
minimum = 0.40
}


excludes = jacocoExcludePatterns + QDomains
}
}
}
11 changes: 11 additions & 0 deletions src/docs/asciidoc/api/cookie/cookie.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[[Baekjoon-Cookie]]
== 백준 쿠키 저장하기

=== Request
include::{snippets}/save-member-baekjoon-cookie/http-request.adoc[]
include::{snippets}/save-member-baekjoon-cookie/request-fields.adoc[]

=== Response
include::{snippets}/save-member-baekjoon-cookie/http-response.adoc[]


28 changes: 28 additions & 0 deletions src/docs/asciidoc/api/dailydefense/dailydefense.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[[Daily-Defense]]
== 오늘의 문제 정보 조회

=== Request
include::{snippets}/daily-defense-info/http-request.adoc[]

=== Response
include::{snippets}/daily-defense-info/http-response.adoc[]
include::{snippets}/daily-defense-info/response-fields.adoc[]

== 오늘의 문제 기록 조회

=== Request
include::{snippets}/daily-defense-ranking/http-request.adoc[]

=== Response
include::{snippets}/daily-defense-ranking/http-response.adoc[]
include::{snippets}/daily-defense-ranking/response-fields.adoc[]


== 오늘의 문제 시작

=== Request
include::{snippets}/daily-defense-start/http-request.adoc[]

=== Response
include::{snippets}/daily-defense-start/http-response.adoc[]
include::{snippets}/daily-defense-start/response-fields.adoc[]
Loading
Loading