Skip to content

memberActivity 내부 lazy initialization exception 에러 해결 #357

memberActivity 내부 lazy initialization exception 에러 해결

memberActivity 내부 lazy initialization exception 에러 해결 #357

Workflow file for this run

name: Backend CI/CD
on:
pull_request:
types: [ opened, synchronize, closed ]
branches: [ dev, main ]
paths:
- 'src/**'
- '.github/**'
- 'k6/**'
jobs:
test:
if: github.event.action == 'opened' || github.event.action == 'synchronize'
runs-on: ubuntu-latest
environment: test
steps:
- name: Checkout the code
uses: actions/checkout@v4
- name: Set up jdk
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'corretto'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
- name: Grant execute permission for gradlew
run: chmod +x gradlew\
- name: Setup Firebase service key
run: |
mkdir -p src/main/resources/firebase
echo ${{ secrets.FIREBASE_SERVICE_KEY_BASE64_ENCODE }} | base64 -d > src/main/resources/firebase/dogether-firebase-key.json
- name: Execute test
# test 패키지 하위 application.yml 민감 정보 추가
env:
DB_DRIVER: "org.h2.Driver"
DB_URL: "jdbc:h2:mem:dogether;MODE=MYSQL"
DB_USERNAME: "sa"
JWT_SECRET_KEY: ${{ secrets.JWT_SECRET_KEY }}
JWT_EXPIRE_TIME: ${{ secrets.JWT_EXPIRE_TIME }}
APPLE_KEY_ID: ${{ secrets.APPLE_KEY_ID }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_CLIENT_ID: ${{ secrets.APPLE_CLIENT_ID }}
APPLE_PRIVATE_KEY: ${{ secrets.APPLE_PRIVATE_KEY }}
AWS_S3_BUCKET_NAME: ${{ secrets.AWS_S3_BUCKET_NAME }}
AWS_REGION: ${{ secrets.AWS_REGION }}
AWS_ACCESS_KEY: ${{ secrets.AWS_ACCESS_KEY }}
AWS_SECRET_KEY: ${{ secrets.AWS_SECRET_KEY }}
run: ./gradlew test --info
check-deploy-condition:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
outputs:
should_deploy: ${{ steps.check-deploy-label.outputs.should_deploy }}
steps:
- name: Check deploy label
id: check-deploy-label
uses: actions/github-script@v7
with:
script: |
const pr = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.pull_request.number
});
const hasDeployLabel = pr.data.labels.map(label => label.name).includes("deploy");
core.setOutput("should_deploy", hasDeployLabel ? "true" : "false");
- name: Explain deploy decision
run: |
if [[ "${{ steps.check-deploy-label.outputs.should_deploy }}" == "true" ]]; then
echo "🚚 deploy label이 존재하므로 배포 작업을 진행합니다."
else
echo "✋ deploy label이 없으므로 배포 작업을 수행하지 않고 종료합니다."
fi
setup-deploy:
needs: [ check-deploy-condition ]
if: needs.check-deploy-condition.outputs.should_deploy == 'true'
runs-on: ubuntu-latest
outputs:
environment: ${{ steps.set-environment.outputs.environment }}
assignees: ${{ steps.set-assignees.outputs.assignees }}
steps:
- name: Set environment
id: set-environment
env:
GITHUB_BASE_REF: ${{ github.base_ref }}
run: |
echo "Target Branch -> $GITHUB_BASE_REF"
echo "environment=dev" >> $GITHUB_OUTPUT
if [[ "$GITHUB_BASE_REF" == "main" ]]; then
echo "environment=prod" >> $GITHUB_OUTPUT
fi
- name: Set assignees
id: set-assignees
uses: actions/github-script@v7
with:
script: |
const pr = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.pull_request.number
});
let assignees = pr.data.assignees.map(user => user.login);
if (assignees.length > 0) {
assignees = assignees.join(', ');
} else {
assignees = context.payload.pull_request.user.login;
}
core.setOutput("assignees", assignees);
- name: Send deploy start notification
uses: slackapi/slack-github-action@v1.24.0
with:
payload: |
{
"text": "🙏 BE 배포 시작 알림 (${{ steps.set-environment.outputs.environment }})",
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "🙏 BE 배포 시작 알림 (${{ steps.set-environment.outputs.environment }})",
"emoji": true
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "집에 가자... 집에 가자... 제발... 😣\n- 작업자 : `${{ steps.set-assignees.outputs.assignees }}`\n- PR : ${{ github.event.pull_request.html_url }}\n- Actions: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
image-build:
needs: [ setup-deploy ]
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
strategy:
matrix:
environment: [ "${{ needs.setup-deploy.outputs.environment }}" ]
environment: ${{ matrix.environment }}
outputs:
springboot_app_profile: ${{ steps.set-springboot-app-profile.outputs.springboot_app_profile }}
image_build_result: ${{ steps.image-build-result.outputs.image_build_result }}
continue-on-error: true
steps:
- name: Set spring boot app profile
id: set-springboot-app-profile
uses: actions/github-script@v7
with:
script: |
const pr = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.pull_request.number
});
const hasPerformanceTestLabel = pr.data.labels.map(label => label.name).includes("performance-test");
const environment = '${{ matrix.environment }}';
let profile = '';
if (environment === 'prod') {
profile = 'prod';
} else if (environment === 'dev') {
profile = hasPerformanceTestLabel ? 'performance-test' : 'dev';
} else {
core.setFailed(`Unexpected environment: ${environment}`);
}
console.log(`🔧profile=${profile}`);
core.setOutput("springboot_app_profile", profile);
- name: Checkout the code
uses: actions/checkout@v4
- name: Set up jdk
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'corretto'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
- name: Grant execute permission for gradlew
run: chmod +x gradlew\
- name: Setup Firebase service key
run: |
mkdir -p src/main/resources/firebase
echo ${{ secrets.FIREBASE_SERVICE_KEY_BASE64_ENCODE }} | base64 -d > src/main/resources/firebase/dogether-firebase-key.json
- name: Build with gradle
run: ./gradlew bootJar -Pspring.profiles.active=${{ steps.set-springboot-app-profile.outputs.springboot_app_profile }} --info
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ secrets.AWS_REGION }}
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
- name: Login to Amazon ECR
uses: aws-actions/amazon-ecr-login@v2
with:
mask-password: 'true'
- name: Docker build & push
id: docker-build-and-push
run: |
docker build --build-arg SPRINGBOOT_APP_PROFILE=${{ steps.set-springboot-app-profile.outputs.springboot_app_profile }} --platform linux/arm64 -f docker/Dockerfile --tag ${{ secrets.ECR_REGISTRY }}/${{ secrets.ECR_REPOSITORY }}:${{ github.sha }} .
docker push ${{ secrets.ECR_REGISTRY }}/${{ secrets.ECR_REPOSITORY }}:${{ github.sha }}
- name: Set image build result
if: always()
id: image-build-result
run: |
echo "image_build_result=fail" >> $GITHUB_OUTPUT
if [[ ${{ steps.docker-build-and-push.outcome }} == "success" ]]; then
echo "image_build_result=success" >> $GITHUB_OUTPUT
fi
deploy-dev:
needs: [ setup-deploy, image-build ]
if: needs.setup-deploy.outputs.environment == 'dev' && needs.image-build.outputs.image_build_result == 'success'
runs-on: dogether-app-dev-runner
strategy:
matrix:
environment: [ "${{ needs.setup-deploy.outputs.environment }}" ]
environment: ${{ matrix.environment }}
outputs:
deploy_result: ${{ steps.deploy-result.outputs.deploy_result }}
continue-on-error: true
steps:
- name: Checkout the code
uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v3
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Create .env file
run: |
cd ~/project
cat <<EOF > .env
# springboot-app environment
SPRINGBOOT_APP_IMAGE_REPOSITORY=${{ secrets.ECR_REGISTRY }}/${{ secrets.ECR_REPOSITORY }}
SPRINGBOOT_APP_IMAGE_TAG=${{ github.sha }}
# mysql environment
DB_NAME=${{ secrets.DB_NAME }}
DB_USERNAME=${{ secrets.DB_USERNAME }}
DB_PASSWORD=${{ secrets.DB_PASSWORD }}
DB_URL=${{ secrets.DB_URL }}
# jwt environment
JWT_SECRET_KEY=${{ secrets.JWT_SECRET_KEY }}
JWT_EXPIRE_TIME=${{ secrets.JWT_EXPIRE_TIME }}
# apple oauth environment
APPLE_KEY_ID=${{ secrets.APPLE_KEY_ID }}
APPLE_TEAM_ID=${{ secrets.APPLE_TEAM_ID }}
APPLE_CLIENT_ID=${{ secrets.APPLE_CLIENT_ID }}
APPLE_PRIVATE_KEY=${{ secrets.APPLE_PRIVATE_KEY }}
# AWS
AWS_S3_BUCKET_NAME=${{ secrets.AWS_S3_BUCKET_NAME }}
AWS_REGION=${{ secrets.AWS_REGION }}
AWS_ACCESS_KEY=${{ secrets.AWS_ACCESS_KEY }}
AWS_SECRET_KEY=${{ secrets.AWS_SECRET_KEY }}
EOF
- name: Start new server application
id: start-new-server-application
run: |
cd ~/project
aws ecr get-login-password --region ${{ secrets.AWS_REGION }} | sudo docker login --username AWS --password-stdin ${{ secrets.ECR_REGISTRY }}
sudo docker-compose stop springboot-app
sudo docker-compose rm -f springboot-app
sudo docker images --filter=reference="*/springboot-app-${{ matrix.environment }}:*" -q | xargs -r sudo docker rmi -f
sudo docker-compose up -d springboot-app
sudo rm -rf .env
echo "🔍 서버 애플리케이션 정상 실행 확인중..."
for i in {1..30}; do
response=$(curl -sf http://localhost:8080/api/health-check || true)
if [[ "$response" == *"OK"* ]]; then
echo "🍺 서버 애플리케이션 정상 실행 확인!"
exit 0
else
echo "⏳ 서버 애플리케이션 실행 대기... ($i/30)"
sleep 1
fi
done
echo "❌ 서버 애플리케이션이 정상 실행되지 않음..."
exit 1
- name: Set deploy result
if: always()
id: deploy-result
run: |
echo "deploy_result=fail" >> $GITHUB_OUTPUT
if [[ ${{ steps.start-new-server-application.outcome }} == "success" ]]; then
echo "deploy_result=success" >> $GITHUB_OUTPUT
fi
deploy-prod:
needs: [ setup-deploy, image-build ]
if: needs.setup-deploy.outputs.environment == 'prod' && needs.image-build.outputs.image_build_result == 'success'
runs-on: dogether-app-prod-runner
strategy:
matrix:
environment: [ "${{ needs.setup-deploy.outputs.environment }}" ]
environment: ${{ matrix.environment }}
outputs:
deploy_result: ${{ steps.deploy-result.outputs.deploy_result }}
continue-on-error: true
steps:
- name: Checkout the code
uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v3
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Create .env file
run: |
cd ~/project
cat <<EOF > .env
# springboot-app environment
SPRINGBOOT_APP_IMAGE_REPOSITORY=${{ secrets.ECR_REGISTRY }}/${{ secrets.ECR_REPOSITORY }}
SPRINGBOOT_APP_IMAGE_TAG=${{ github.sha }}
# mysql environment
DB_NAME=${{ secrets.DB_NAME }}
DB_USERNAME=${{ secrets.DB_USERNAME }}
DB_PASSWORD=${{ secrets.DB_PASSWORD }}
DB_URL=${{ secrets.DB_URL }}
# jwt environment
JWT_SECRET_KEY=${{ secrets.JWT_SECRET_KEY }}
JWT_EXPIRE_TIME=${{ secrets.JWT_EXPIRE_TIME }}
# apple oauth environment
APPLE_KEY_ID=${{ secrets.APPLE_KEY_ID }}
APPLE_TEAM_ID=${{ secrets.APPLE_TEAM_ID }}
APPLE_CLIENT_ID=${{ secrets.APPLE_CLIENT_ID }}
APPLE_PRIVATE_KEY=${{ secrets.APPLE_PRIVATE_KEY }}
# AWS
AWS_S3_BUCKET_NAME=${{ secrets.AWS_S3_BUCKET_NAME }}
AWS_REGION=${{ secrets.AWS_REGION }}
AWS_ACCESS_KEY=${{ secrets.AWS_ACCESS_KEY }}
AWS_SECRET_KEY=${{ secrets.AWS_SECRET_KEY }}
EOF
- name: Start new server application
id: start-new-server-application
run: |
cd ~/project
aws ecr get-login-password --region ${{ secrets.AWS_REGION }} | sudo docker login --username AWS --password-stdin ${{ secrets.ECR_REGISTRY }}
./deploy.sh
- name: Set deploy result
if: always()
id: deploy-result
run: |
echo "deploy_result=fail" >> $GITHUB_OUTPUT
if [[ ${{ steps.start-new-server-application.outcome }} == "success" ]]; then
echo "deploy_result=success" >> $GITHUB_OUTPUT
fi
notify:
needs: [ check-deploy-condition, setup-deploy, image-build, deploy-dev, deploy-prod ]
if: always()
runs-on: ubuntu-latest
steps:
- name: Send deploy success notification
if: needs.check-deploy-condition.outputs.should_deploy == 'true' &&
needs.image-build.outputs.image_build_result == 'success' &&
(needs.deploy-dev.outputs.deploy_result == 'success' || needs.deploy-prod.outputs.deploy_result == 'success')
uses: slackapi/slack-github-action@v1.24.0
with:
payload: |
{
"text": "*🎉 BE 배포 성공 알림! (${{ needs.setup-deploy.outputs.environment }})*",
"attachments": [
{
"color": "#36a64f",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "오늘은 생맥 ㅎ 🍺\n- 작업자 : `${{ needs.setup-deploy.outputs.assignees }}`\n- PR : ${{ github.event.pull_request.html_url }}\n- Actions: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}
}
]
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
- name: Send deploy fail notification
if: needs.check-deploy-condition.outputs.should_deploy == 'true' &&
(needs.image-build.outputs.image_build_result != 'success' ||
(needs.deploy-dev.outputs.deploy_result != 'success' &&
needs.deploy-prod.outputs.deploy_result != 'success'))
uses: slackapi/slack-github-action@v1.24.0
with:
payload: |
{
"text": "*❌ BE 배포 실패 알림ㅜ (${{ needs.setup-deploy.outputs.environment }})*",
"attachments": [
{
"color": "#ff0000",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "뭐해요? 야근해야죠... 🌝\n- 작업자 : `${{ needs.setup-deploy.outputs.assignees }}`\n- PR : ${{ github.event.pull_request.html_url }}\n- Actions: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}
}
]
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK