Skip to content
Merged
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.git
.gradle
build
*.log
.DS_Store
.env
*.env
**/*.env
deploy-*.zip
File renamed without changes.
19 changes: 10 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,31 @@ jobs:

steps:
- uses: actions/checkout@v4

- uses: actions/setup-java@v4
with: { distribution: temurin, java-version: 17 }
with:
distribution: temurin
java-version: 17

- uses: gradle/actions/setup-gradle@v3
if: ${{ !env.ACT }}
with:
cache-read-only: ${{ github.event_name == 'pull_request' }}
gradle-home-cache-cleanup: true

- name: Create dummy .env for CI
working-directory: gdgoc
run: echo "# ci dummy" > .env

- name: Gradle build (skip tests)
id: assemble
working-directory: gdgoc
env: { GRADLE_OPTS: "-Dorg.gradle.vfs.watch=false" }
env:
GRADLE_OPTS: "-Dorg.gradle.vfs.watch=false"
run: |
chmod +x ./gradlew
./gradlew build -x test --no-daemon --stacktrace --info --no-watch-fs | tee ../build.log
./gradlew build -x test --no-daemon --stacktrace --info --no-watch-fs | tee build.log

- name: Gradle test (H2 in-memory)
id: test
working-directory: gdgoc
env:
GRADLE_OPTS: "-Dorg.gradle.vfs.watch=false"
SPRING_PROFILES_ACTIVE: test
Expand All @@ -55,7 +57,7 @@ jobs:
SPRING_JPA_DATABASE_PLATFORM: org.hibernate.dialect.H2Dialect
SPRING_JPA_HIBERNATE_DDL_AUTO: create-drop
SPRING_FLYWAY_ENABLED: "false"
run: ./gradlew test --no-daemon --stacktrace --info --no-watch-fs | tee ../test.log
run: ./gradlew test --no-daemon --stacktrace --info --no-watch-fs | tee test.log

- name: Publish unit-test results (check UI)
id: publish
Expand Down Expand Up @@ -111,7 +113,6 @@ jobs:
**CI status**
${{ steps.status.outputs.message }}


- name: Fail if any failed
if: ${{ always() && (steps.assemble.outcome != 'success' || steps.test.outcome != 'success') }}
run: exit 1
run: exit 1
72 changes: 36 additions & 36 deletions .github/workflows/deploy-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,51 +24,51 @@ jobs:
docker build -t ${{ secrets.DOCKER_HUB_USERNAME }}/gdgoc-be-app-dev:latest .
docker push ${{ secrets.DOCKER_HUB_USERNAME }}/gdgoc-be-app-dev:latest

- name: move files to Root
run: |
cp gdgoc/docker-compose-dev.yml ./docker-compose-dev.yml
cp gdgoc/deploy.dev.sh ./deploy.dev.sh
cp gdgoc/appspec.dev.yml ./appspec.yml
- name: Prepare appspec.yml (dev)
run: cp appspec.dev.yml appspec.yml

- name: Create Deployment Package
run: |
echo "DOCKER_HUB_USERNAME=${{ secrets.DOCKER_HUB_USERNAME }}" > .env
echo "DB_HOST=${{ secrets.DB_HOST }}" >> .env
echo "DB_PORT=${{ secrets.DB_PORT }}" >> .env
echo "DB_NAME_DEV=${{ secrets.DB_NAME_DEV }}" >> .env
echo "DB_USERNAME=${{ secrets.DB_USERNAME }}" >> .env
echo "DB_PASSWORD=${{ secrets.DB_PASSWORD }}" >> .env
echo "GOOGLE_CLIENT_ID=${{ secrets.GOOGLE_CLIENT_ID }}" >> .env
echo "GOOGLE_CLIENT_SECRET=${{ secrets.GOOGLE_CLIENT_SECRET }}" >> .env
echo "GOOGLE_REDIRECT_URI=${{ secrets.GOOGLE_REDIRECT_URI }}" >> .env
echo "GOOGLE_ISSUER=${{secrets.GOOGLE_ISSUER}}" >> .env
echo "SELF_ISSUER=${{secrets.SELF_ISSUER}}" >> .env
echo "SECRET_KEY=${{secrets.SECRET_KEY}}" >> .env
echo "AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }}" >> .env
echo "AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }}" >> .env
echo "AWS_REGION=${{ secrets.AWS_REGION }}" >> .env
echo "AWS_RESOURCE_BUCKET=${{secrets.AWS_RESOURCE_BUCKET}}" >> .env
echo "AWS_TEST_RESOURCE_BUCKET=${{secrets.AWS_TEST_RESOURCE_BUCKET}}" >> .env
echo "GMAIL=${{secrets.GMAIL}}" >> .env
echo "GMAIL_PASSWORD=${{secrets.GMAIL_PASSWORD}}" >> .env
echo "DOZZLE_USERNAME=${{ secrets.DOZZLE_USERNAME }}" >> .env
echo "DOZZLE_PASSWORD=${{ secrets.DOZZLE_PASSWORD }}" >> .env

zip -r deploy.zip .env docker-compose-dev.yml deploy.dev.sh appspec.yml
cat > .env <<EOF
DOCKER_HUB_USERNAME=${{ secrets.DOCKER_HUB_USERNAME }}
DB_HOST=${{ secrets.DB_HOST }}
DB_PORT=${{ secrets.DB_PORT }}
DB_NAME_DEV=${{ secrets.DB_NAME_DEV }}
DB_USERNAME=${{ secrets.DB_USERNAME }}
DB_PASSWORD=${{ secrets.DB_PASSWORD }}
GOOGLE_CLIENT_ID=${{ secrets.GOOGLE_CLIENT_ID }}
GOOGLE_CLIENT_SECRET=${{ secrets.GOOGLE_CLIENT_SECRET }}
GOOGLE_REDIRECT_URI=${{ secrets.GOOGLE_REDIRECT_URI }}
GOOGLE_ISSUER=${{ secrets.GOOGLE_ISSUER }}
SELF_ISSUER=${{ secrets.SELF_ISSUER }}
SECRET_KEY=${{ secrets.SECRET_KEY }}
AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION=${{ secrets.AWS_REGION }}
AWS_RESOURCE_BUCKET=${{ secrets.AWS_RESOURCE_BUCKET }}
AWS_TEST_RESOURCE_BUCKET=${{ secrets.AWS_TEST_RESOURCE_BUCKET }}
GMAIL=${{ secrets.GMAIL }}
GMAIL_PASSWORD=${{ secrets.GMAIL_PASSWORD }}
DOZZLE_USERNAME=${{ secrets.DOZZLE_USERNAME }}
DOZZLE_PASSWORD=${{ secrets.DOZZLE_PASSWORD }}
EOF

# 루트 기준 파일들만 압축
zip -r deploy-dev.zip appspec.yml docker-compose-dev.yml deploy.dev.sh .env

- name: Configure AWS credentials
run: |
aws configure set aws_access_key_id ${{ secrets.AWS_ACCESS_KEY_ID }}
aws configure set aws_secret_access_key ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws configure set region ${{ secrets.AWS_REGION }}
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}

- name: Upload Deployment Package to S3
run: |
aws s3 cp deploy.zip s3://${{ secrets.AWS_S3_BUCKET }}/deploy-dev.zip
run: aws s3 cp deploy-dev.zip s3://${{ secrets.AWS_S3_BUCKET }}/deploy-dev.zip

- name: Deploy to AWS CodeDeploy
run: |
aws deploy create-deployment \
--application-name ${{ secrets.AWS_CODEDEPLOY_APP }} \
--deployment-group-name ${{ secrets.AWS_CODEDEPLOY_GROUP_DEV }} \
--application-name "${{ secrets.AWS_CODEDEPLOY_APP }}" \
--deployment-group-name "${{ secrets.AWS_CODEDEPLOY_GROUP_DEV }}" \
--s3-location bucket=${{ secrets.AWS_S3_BUCKET }},bundleType=zip,key=deploy-dev.zip
79 changes: 41 additions & 38 deletions .github/workflows/deploy-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,54 +21,57 @@ jobs:

- name: Build and Push Docker Image
run: |
docker build -t ${{ secrets.DOCKER_HUB_USERNAME }}/gdgoc-be-app:latest .
docker push ${{ secrets.DOCKER_HUB_USERNAME }}/gdgoc-be-app:latest
IMAGE=${{ secrets.DOCKER_HUB_USERNAME }}/gdgoc-be-app
TAG=${{ github.sha }}
docker build -t $IMAGE:latest -t $IMAGE:$TAG .
docker push $IMAGE:latest
docker push $IMAGE:$TAG

- name: move files to Root
run: |
cp gdgoc/docker-compose-prod.yml ./docker-compose-prod.yml
cp gdgoc/deploy.prod.sh ./deploy.prod.sh
cp gdgoc/appspec.prod.yml ./appspec.yml
- name: Prepare appspec.yml (prod)
run: cp appspec.prod.yml appspec.yml

- name: Create Deployment Package
run: |
echo "DOCKER_HUB_USERNAME=${{ secrets.DOCKER_HUB_USERNAME }}" > .env
echo "DB_HOST=${{ secrets.DB_HOST }}" >> .env
echo "DB_PORT=${{ secrets.DB_PORT }}" >> .env
echo "DB_NAME=${{ secrets.DB_NAME }}" >> .env
echo "DB_USERNAME=${{ secrets.DB_USERNAME }}" >> .env
echo "DB_PASSWORD=${{ secrets.DB_PASSWORD }}" >> .env
echo "GOOGLE_CLIENT_ID=${{ secrets.GOOGLE_CLIENT_ID }}" >> .env
echo "GOOGLE_CLIENT_SECRET=${{ secrets.GOOGLE_CLIENT_SECRET }}" >> .env
echo "GOOGLE_REDIRECT_URI=${{ secrets.GOOGLE_REDIRECT_URI }}" >> .env
echo "GOOGLE_ISSUER=${{secrets.GOOGLE_ISSUER}}" >> .env
echo "SELF_ISSUER=${{secrets.SELF_ISSUER}}" >> .env
echo "SECRET_KEY=${{secrets.SECRET_KEY}}" >> .env
echo "AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }}" >> .env
echo "AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }}" >> .env
echo "AWS_REGION=${{ secrets.AWS_REGION }}" >> .env
echo "AWS_RESOURCE_BUCKET=${{secrets.AWS_RESOURCE_BUCKET}}" >> .env
echo "AWS_TEST_RESOURCE_BUCKET=${{secrets.AWS_TEST_RESOURCE_BUCKET}}" >> .env
echo "GMAIL=${{secrets.GMAIL}}" >> .env
echo "GMAIL_PASSWORD=${{secrets.GMAIL_PASSWORD}}" >> .env
echo "DOZZLE_USERNAME=${{ secrets.DOZZLE_USERNAME }}" >> .env
echo "DOZZLE_PASSWORD=${{ secrets.DOZZLE_PASSWORD }}" >> .env
cat > .env <<EOF
DOCKER_HUB_USERNAME=${{ secrets.DOCKER_HUB_USERNAME }}
DB_HOST=${{ secrets.DB_HOST }}
DB_PORT=${{ secrets.DB_PORT }}
DB_NAME=${{ secrets.DB_NAME }}
DB_USERNAME=${{ secrets.DB_USERNAME }}
DB_PASSWORD=${{ secrets.DB_PASSWORD }}
GOOGLE_CLIENT_ID=${{ secrets.GOOGLE_CLIENT_ID }}
GOOGLE_CLIENT_SECRET=${{ secrets.GOOGLE_CLIENT_SECRET }}
GOOGLE_REDIRECT_URI=${{ secrets.GOOGLE_REDIRECT_URI }}
GOOGLE_ISSUER=${{ secrets.GOOGLE_ISSUER }}
SELF_ISSUER=${{ secrets.SELF_ISSUER }}
SECRET_KEY=${{ secrets.SECRET_KEY }}
AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION=${{ secrets.AWS_REGION }}
AWS_RESOURCE_BUCKET=${{ secrets.AWS_RESOURCE_BUCKET }}
AWS_TEST_RESOURCE_BUCKET=${{ secrets.AWS_TEST_RESOURCE_BUCKET }}
GMAIL=${{ secrets.GMAIL }}
GMAIL_PASSWORD=${{ secrets.GMAIL_PASSWORD }}
DOZZLE_USERNAME=${{ secrets.DOZZLE_USERNAME }}
DOZZLE_PASSWORD=${{ secrets.DOZZLE_PASSWORD }}
EOF

zip -r deploy.zip .env docker-compose-prod.yml deploy.prod.sh appspec.yml
# 루트 기준 파일만 압축
zip -r deploy-prod.zip appspec.yml docker-compose-prod.yml deploy.prod.sh .env

- name: Configure AWS credentials
run: |
aws configure set aws_access_key_id ${{ secrets.AWS_ACCESS_KEY_ID }}
aws configure set aws_secret_access_key ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws configure set region ${{ secrets.AWS_REGION }}
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}

- name: Upload Deployment Package to S3
run: |
aws s3 cp deploy.zip s3://${{ secrets.AWS_S3_BUCKET }}/deploy.zip
run: aws s3 cp deploy-prod.zip s3://${{ secrets.AWS_S3_BUCKET }}/deploy-prod.zip

- name: Deploy to AWS CodeDeploy
run: |
aws deploy create-deployment \
--application-name ${{ secrets.AWS_CODEDEPLOY_APP }} \
--deployment-group-name ${{ secrets.AWS_CODEDEPLOY_GROUP }} \
--s3-location bucket=${{ secrets.AWS_S3_BUCKET }},bundleType=zip,key=deploy.zip
--application-name "${{ secrets.AWS_CODEDEPLOY_APP }}" \
--deployment-group-name "${{ secrets.AWS_CODEDEPLOY_GROUP }}" \
--s3-location bucket=${{ secrets.AWS_S3_BUCKET }},bundleType=zip,key=deploy-prod.zip
10 changes: 7 additions & 3 deletions gdgoc/.gitignore → .gitignore
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
HELP.md
.gradle
../.env
**/.env
**/.env.*
*.env
.env
!.env.example
**/.env.example
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
!src/main/**/build/
!src/test/**/build/

### STS ###
.apt_generated
Expand Down
31 changes: 21 additions & 10 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
FROM gradle:8.0.2-jdk17 AS build
WORKDIR /app/gdgoc
# syntax=docker/dockerfile:1

COPY gdgoc/ .
RUN ls -l
RUN chmod +x gradlew
RUN ./gradlew build -x test
# --- Build stage ---
FROM gradle:8.11.1-jdk17 AS build
WORKDIR /app

# 루트 프로젝트 전체 복사
COPY . .

# wrapper가 있다면 wrapper 사용 권장
# 권한 부여는 로컬에서 이미 되어 있을 수도 있음
RUN chmod +x ./gradlew || true

# 테스트는 컨테이너 빌드에서 보통 스킵 (CI에서 이미 수행)
RUN ./gradlew clean bootJar -x test --no-daemon

RUN cp $(ls /app/gdgoc/build/libs/*.jar | head -n 1) /app/gdgoc/build/libs/app.jar
# 산출물 이름이 가변적이면 가장 최신 jar를 app.jar로 복사
RUN cp "$(ls build/libs/*.jar | head -n 1)" build/libs/app.jar

FROM openjdk:17-jdk-slim
# --- Runtime stage ---
FROM eclipse-temurin:17-jre
WORKDIR /app

COPY --from=build /app/gdgoc/build/libs/app.jar app.jar
COPY --from=build /app/build/libs/app.jar app.jar

ENTRYPOINT ["java", "-jar", "app.jar"]
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app/app.jar"]
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 0 additions & 1 deletion gdgoc/settings.gradle

This file was deleted.

File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rootProject.name = '24-2_GDGoC_Server'
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ spring:
enabled: true
locations: classpath:db/migration
schemas: public
baseline-on-migrate: true # ★ 기존 스키마를 기준선으로 등록
baseline-version: 1 # 기준선 버전(임의, 보통 1)
baseline-on-migrate: true
baseline-version: 1
baseline-description: "Baseline existing schema"

mail:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package inha.gdgoc.domain.recruit.service;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.*;

import com.fasterxml.jackson.databind.ObjectMapper;
import inha.gdgoc.domain.recruit.dto.request.ApplicationRequest;
import inha.gdgoc.domain.recruit.dto.request.RecruitMemberRequest;
import inha.gdgoc.domain.recruit.entity.RecruitMember;
import inha.gdgoc.domain.recruit.enums.EnrolledClassification;
import inha.gdgoc.domain.recruit.enums.Gender;
import inha.gdgoc.domain.recruit.repository.AnswerRepository;
import inha.gdgoc.domain.recruit.repository.RecruitMemberRepository;
import java.time.LocalDate;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.List;
import java.util.Map;

class RecruitMemberServiceTest {

@Test
void addMember_ShouldSaveRecruitMemberAndAnswers() {
// given
RecruitMemberRequest recruitMemberRequest = RecruitMemberRequest.builder()
.name("김소연")
.grade("4")
.studentId("122123388")
.enrolledClassification("정등록")
.phoneNumber("010-1111-2332")
.nationality("대한민국")
.email("[email protected]")
.gender("여자")
.birth(LocalDate.of(2002, 8, 18))
.major("컴퓨터공학과")
.doubleMajor("복수전공 인공지능공학과")
.isPayed(true)
.build();

Map<String, Object> answers = Map.of(
"gdgUserMotive", "그냥",
"gdgUserStory", "삶",
"gdgInterest", List.of("FrontEnd", "BackEnd"),
"gdgPeriod", List.of("23-1", "24-1"),
"gdgRoute", "에타",
"gdgExpect", List.of("djqt"),
"gdgWish", List.of("a", "b", "c"),
"gdgFeedback", "asdfsdf"
);


RecruitMember savedMember = RecruitMember.builder()
.id(1L) // 저장될 ID
.name("김소연")
.grade("4")
.studentId("122123388")
.enrolledClassification(EnrolledClassification.FULL_REGISTRATION)
.phoneNumber("010-1111-2332")
.nationality("대한민국")
.email("[email protected]")
.gender(Gender.FEMALE)
.birth(LocalDate.of(2002, 8, 18))
.major("컴퓨터공학과")
.doubleMajor("복수전공 인공지능공학과")
.isPayed(true)
.build();

}
}
Loading