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

build : core ci/cd prod 추가 #582 #588

Merged
merged 5 commits into from
Jul 30, 2024
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
149 changes: 149 additions & 0 deletions .github/workflows/core-application-prod-ci-cd-flow.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
name: core-prod-ci/cd

on:
push:
branches:
- prod_back_core
- 'hotfix/[0-9a-zA-z]+-B-prod-core-#[0-9a-zA-z]+'
pull_request:
branches:
- prod_back_core

jobs:
build_and_test:
name: build and test
if: ${{github.event_name == 'pull_request' }}
runs-on: ubuntu-latest

defaults:
run:
working-directory: ./backend/core

steps:
- name: set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'liberica'

- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
token: ${{ secrets.CI_PAT }}

- name: formatting
uses: axel-op/googlejavaformat-action@v3
with:
args: "--replace"
skip-commit: true

- name: grant execute permission for gradlew
run: chmod +x ./gradlew

- name: test
run: ./gradlew clean test

deploy-core:
name: core application deploy
if: ${{ github.event_name == 'push' }}
runs-on: ubuntu-latest

defaults:
run:
working-directory: ./backend/core

permissions:
id-token: write
contents: read

steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
token: ${{ secrets.CI_PAT }}

- name: set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'liberica'
cache: gradle

- name: grant execute permission for gradlew
run: chmod +x ./gradlew

- name: build gradle
run: ./gradlew clean build

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: ${{ secrets.AWS_REGION }}

- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ steps.login-ecr.outputs.registry }}/${{ secrets.AWS_PROD_ECR_CORE_REPOSITORY_NAME }}
tags: |
type=raw,value={{date 'YYYYMMDD-HHmmss'}}

- name: Build and push
uses: docker/build-push-action@v5
with:
context: ./backend/core
push: true
tags: ${{ steps.meta.outputs.tags }}
provenance: false

- name: Get Github action IP
id: ip
uses: haythem/[email protected]

- name: Add Github Actions IP to Security group
run: |
aws ec2 authorize-security-group-ingress --group-id ${{ secrets.AWS_PROD_CORE_NOTI_SG_ID }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32

- name: Connect ec2 and Run Docker Container
uses: appleboy/[email protected]
env:
AWS_ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
with:
host: ${{ secrets.SSH_PROD_CORE_NOTI_HOST }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_PROD_CORE_NOTI_PRIVATE_KEY }}
port: ${{ secrets.SSH_PORT }}
script: |
docker ps -q --filter "name=core" | xargs -r docker stop
docker ps -aq --filter "name=core" | xargs -r docker rm
aws ecr get-login-password --region ${{ secrets.AWS_REGION }} | docker login --username ${{ secrets.AWS_DOCKER_USER }} --password-stdin ${{ secrets.AWS_USER_ID }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com
docker image prune -f
docker pull ${{ steps.meta.outputs.tags }}
docker run -d -p 8080:8080 -e ENVIRONMENT=prod --name core --network ec2-user_backend ${{ steps.meta.outputs.tags }}

- name: Remove Github Actions IP from security group
if: always()
run: |
aws ec2 revoke-security-group-ingress --group-id ${{ secrets.AWS_PROD_CORE_NOTI_SG_ID }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32

- uses: sarisia/actions-status-discord@v1
if: success()
with:
webhook: ${{ secrets.DISCORD_WEBHOOK }}
status: ${{ job.status }}
content: "여러분 <@384742716933668867> <@1084774841460215839> <@545902166842408960> <@1081452554149449748>\n 배포 완료했습니다!!"
title: "코어 운영 서버 배포 완료 알림"
description: "백엔드 개발 브랜치에서 운영 환경으로 깃허브 액션으로 배포 완료"
image: ${{ secrets.EMBED_IMAGE }}
color: 0x0000ff
url: "https://github.com/tukcomCD2024/DroidBlossom/actions"
username: GitHub Actions Bot
avatar_url: ${{ secrets.AVATAR_URL }}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package site.timecapsulearchive.core.global.config.rabbitmq;

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import lombok.RequiredArgsConstructor;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
Expand All @@ -11,6 +13,7 @@
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import site.timecapsulearchive.core.global.error.exception.InternalServerException;

@Configuration
@RequiredArgsConstructor
Expand All @@ -19,6 +22,8 @@ public class RabbitmqConfig {
private static final int MAX_RETRY_COUNT = 3;
private static final String RETRY_HEADER = "x-retry-count";

private final RabbitmqProperties rabbitmqProperties;

@Bean
public Queue capsuleSkinQueue() {
return new Queue(RabbitmqComponentConstants.CAPSULE_SKIN_QUEUE.getSuccessComponent(), true);
Expand Down Expand Up @@ -153,7 +158,21 @@ public RabbitTemplate publisherConfirmsRabbitTemplate() {
public CachingConnectionFactory publisherConfirmsConnectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();

connectionFactory.afterPropertiesSet();
connectionFactory.setHost(rabbitmqProperties.host());
connectionFactory.setPort(rabbitmqProperties.port());
connectionFactory.setUsername(rabbitmqProperties.userName());
connectionFactory.setPassword(rabbitmqProperties.password());
connectionFactory.setVirtualHost(rabbitmqProperties.virtualHost());
connectionFactory.setPublisherConfirmType(rabbitmqProperties.publisherConfirmType());
connectionFactory.setPublisherReturns(rabbitmqProperties.publisherReturns());

if (rabbitmqProperties.isSslEnabled()) {
try {
connectionFactory.getRabbitConnectionFactory().useSslProtocol();
} catch (NoSuchAlgorithmException | KeyManagementException e) {
throw new InternalServerException(e);
}
}

return connectionFactory;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package site.timecapsulearchive.core.global.config.rabbitmq;

import org.springframework.amqp.rabbit.connection.CachingConnectionFactory.ConfirmType;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;

@ConfigurationProperties(prefix = "spring.rabbitmq")
public record RabbitmqProperties(
String host,
int port,
String userName,
String password,
String virtualHost,
ConfirmType publisherConfirmType,
boolean publisherReturns,
@NestedConfigurationProperty
SSL ssl
) {
protected record SSL(
boolean enabled
) {

}

public boolean isSslEnabled() {
return ssl != null && ssl.enabled;
}
}
4 changes: 2 additions & 2 deletions backend/core/src/main/resources/logback-spring.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
</encoder>
</appender>

<springProfile name="prod | container">
<springProfile name="prod">
<logger name="org.hibernate" level="error" additivity="false">
<appender-ref ref="STDOUT"/>
<appender-ref ref="LOKI"/>
Expand All @@ -43,7 +43,7 @@
</root>
</springProfile>

<springProfile name="local | dev | test">
<springProfile name="local | dev | test | container">
<logger name="org.hibernate" level="error" additivity="false">
<appender-ref ref="STDOUT"/>
</logger>
Expand Down
Loading