Skip to content

Commit

Permalink
Merge pull request #65 from Open-Eye-Im-Developer/develop
Browse files Browse the repository at this point in the history
main에 v1 반영
  • Loading branch information
happyjamy authored Feb 18, 2024
2 parents 8b89e05 + 40c2c93 commit 93bf213
Show file tree
Hide file tree
Showing 78 changed files with 2,756 additions and 19 deletions.
101 changes: 101 additions & 0 deletions .github/workflows/cd_gradle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# 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 CD with Gradle in mogakGo

on:
workflow_dispatch:
push:
branches: [ "main" ]

permissions:
contents: read

jobs:
build-and-push-docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'

## caching Gradle
- name: Gradle caching
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
## create application.yml
- name: make application.yml
run: |
mkdir -p ./src/main/resources
touch ./src/main/resources/application.yml
shell: bash

## save application.yml for secrets
- name: save application.yml
run: echo "${{ secrets.APPLICATION }}" > ./src/main/resources/application.yml
shell: bash

## grant permission for gradlew
- name: Grant execute permission for gradlew
run: chmod +x gradlew

## build gradle
- name: Build with Gradle
run: ./gradlew build -x test

## login before push docker-hub
- name: login Docker-Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

## build docker and push image
- name: Docker Build and Push
run: |
docker build -f Dockerfile -t ${{ secrets.DOCKERHUB_USERNAME }}/mogakgo .
docer push ${{ secrets.DOCKERHUB_USERNAME }}/mogakgo
## deploy docker file to EC2
- name: Deploy to Prod
uses: appleboy/ssh-action@master
id: deploy-prod
with:
host: ${{ secrets.EC2_HOST }}
username: ubuntu
key: ${{ secrets.EC2_PEM_KEY }}
port: 22
script: |
if [ ! -z "$(docker ps -q)" ]; then
docker stop $(docker ps -q)
fi
if [ ! -z "$(docker ps -aq)" ]; then
docker rm $(docker ps -aq)
fi
docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_TOKEN }}
docker pull ${{ secrets.DOCKERHUB_USERNAME }}/mogakgo
docker run -d \
--log-driver=awslogs \
--log-opt awslogs-region=ap-northeast-2 \
--log-opt awslogs-group=web \
--log-opt awslogs-stream=log \
--name mogakgo \
-p 8080:8080 \
-e TZ=Asia/Seoul \
${{ secrets.DOCKERHUB_USERNAME }}/mogakgo
docker system prune -f
78 changes: 78 additions & 0 deletions .github/workflows/ci_gradle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# 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 in mogakGo

on:
workflow_dispatch:
push:
branches: [ "develop" ]
pull_request:
branches: [ "main", "develop" ]

permissions:
checks: write
pull-requests: write

jobs:
build:

runs-on: ubuntu-latest

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

## Gradle Wrapper grant permission
- name: Grant execute permission for gradlew
run: chmod +x gradlew

## create application.yml
- name: make application.yml
run: |
mkdir -p ./src/main/resources
touch ./src/main/resources/application.yml
shell: bash

- name: save application.yml for secrets
run: echo "${{ secrets.APPLICATION }}" > ./src/main/resources/application.yml
shell: bash

## create test_application.yml
- name: make test_application.yml
run: |
mkdir -p ./src/test/resources
touch ./src/test/resources/application.yml
shell: bash

- name: save test_application.yml for secrets
run: echo "${{ secrets.APPLICATION_TEST }}" > ./src/test/resources/application.yml
shell: bash

## create test_ddl.sql for test

## execute Gradle test
- name: Test with Gradle
run: ./gradlew --info test

## create Report after Test
- name: Public Test results
uses: EnricoMi/publish-unit-test-result-action@v2
if: always()
with:
files: '**/build/test-results/test/TEST-*.xml'

## make comment about error
- name: add comments to pull-request
uses: mikepenz/action-junit-report@v3
if: always()
with:
report_paths: '**/build/test-results/test/TEST-*.xml'
18 changes: 18 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# 어플리케이션 .jar 파일을 여러 레이어로 extracting
FROM eclipse-temurin:17-jre AS builder
WORKDIR applicatio
ARG JAR_FILE=build/libs/*SNAPSHOT.jar
COPY ${JAR_FILE} application.jar
RUN java -Djarmode=layertools -jar application.jar extract

# 실제 어플리케이션의 실행 환경
FROM eclipse-temurin:17-jre
WORKDIR application
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/application/ ./

# 어플리케이션 .jar 파일의 압축 해제로, JarLauncher를 통해 어플리케이션 실행
ENV TZ=Asia/Seoul
ENTRYPOINT ["java", "-Duser.timezone=Asia/Seoul", "org.springframework.boot.loader.launch.JarLauncher"]
64 changes: 46 additions & 18 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.2' apply(false)
id 'io.spring.dependency-management' version '1.1.4' apply(false)
id 'org.springframework.boot' version '3.1.8'
id 'io.spring.dependency-management' version '1.1.4'
}

allprojects {
Expand All @@ -16,24 +16,52 @@ allprojects {
}
}

subprojects {
apply { plugin('java') }
apply { plugin('org.springframework.boot') }
apply { plugin('io.spring.dependency-management') }
dependencies {
// Spring Boot Web
implementation 'org.springframework.boot:spring-boot-starter-web:3.1.8'
// Spring Boot Data JPA
implementation 'org.springframework.boot:spring-boot-starter-data-jpa:3.1.8'
// Spring Boot Validation
implementation 'org.springframework.boot:spring-boot-starter-validation:3.1.8'
// Lombok
compileOnly 'org.projectlombok:lombok:1.18.30'
annotationProcessor 'org.projectlombok:lombok:1.18.30'
// QueryDSL
implementation 'com.querydsl:querydsl-jpa:5.1.0:jakarta'
annotationProcessor 'com.querydsl:querydsl-apt:5.1.0:jakarta'
annotationProcessor "jakarta.annotation:jakarta.annotation-api:2.1.1"
annotationProcessor "jakarta.persistence:jakarta.persistence-api:3.1.0"
// MySQL
runtimeOnly 'com.mysql:mysql-connector-j:8.2.0'
// for spatial type in jpa 경도위도 계산
implementation 'org.hibernate:hibernate-spatial:6.4.1.Final'
implementation 'org.locationtech.jts:jts-core'
// Spring Boot Security
implementation 'org.springframework.boot:spring-boot-starter-security:3.1.8'
// Spring Boot OAuth2 Client
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client:3.1.8'
// Feign Client
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign:4.0.6'
// Firebase Admin
implementation 'com.google.firebase:firebase-admin:9.2.0'
// JWT
implementation 'com.auth0:java-jwt:4.4.0'
// Spring Boot Data Redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis:3.1.8'
// Swagger
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'

configurations {
compileOnly {
extendsFrom annotationProcessor
}
}

dependencies {
// Lombok
compileOnly 'org.projectlombok:lombok:1.18.30'
annotationProcessor 'org.projectlombok:lombok:1.18.30'
}
// SpringBoot Test
testImplementation 'org.springframework.boot:spring-boot-starter-test:3.1.8'
// TestContainers
testImplementation 'org.springframework.boot:spring-boot-testcontainers:3.1.8'
testImplementation 'org.testcontainers:junit-jupiter:1.19.3'
testImplementation 'org.testcontainers:mysql:1.19.3'
// Spring Security Test
testImplementation 'org.springframework.security:spring-security-test:6.1.3'
}

test {
useJUnitPlatform()
}
}

2 changes: 1 addition & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
@@ -1 +1 @@
rootProject.name = 'MogakGo'
rootProject.name = 'MogakGo'
15 changes: 15 additions & 0 deletions src/main/java/io/oeid/mogakgo/MogakGoApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package io.oeid.mogakgo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients
public class MogakGoApplication {

public static void main(String[] args) {
SpringApplication.run(MogakGoApplication.class, args);
}

}
12 changes: 12 additions & 0 deletions src/main/java/io/oeid/mogakgo/common/annotation/UserId.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.oeid.mogakgo.common.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface UserId {

}
26 changes: 26 additions & 0 deletions src/main/java/io/oeid/mogakgo/common/base/BaseTimeEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package io.oeid.mogakgo.common.base;

import jakarta.persistence.Column;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.MappedSuperclass;
import java.time.LocalDateTime;
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseTimeEntity {

@CreatedDate
@Column(name = "created_at")
private LocalDateTime createdAt;

@Column(name = "deleted_at")
private LocalDateTime deletedAt;

protected void delete() {
this.deletedAt = LocalDateTime.now();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.oeid.mogakgo.common.resolver;


import io.oeid.mogakgo.common.annotation.UserId;
import io.oeid.mogakgo.domain.auth.exception.AuthException;
import io.oeid.mogakgo.exception.code.ErrorCode401;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

public class UserIdAnnotationResolver implements HandlerMethodArgumentResolver {

@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterAnnotation(UserId.class) != null;
}

@Override
public Object resolveArgument(
MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory
) {
Long userId = (Long) webRequest.getAttribute("userId", RequestAttributes.SCOPE_REQUEST);
if (userId == null) {
throw new AuthException(ErrorCode401.AUTH_MISSING_CREDENTIALS);
}
return userId;
}

}
Loading

0 comments on commit 93bf213

Please sign in to comment.