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

chore: 개발 서버를 추가하고, 워크플로우를 개선한다 #126

Merged
merged 8 commits into from
Apr 4, 2024
57 changes: 36 additions & 21 deletions .github/workflows/cd.yml → .github/workflows/dev-deploy.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
name: Production CD

name: 변경사항을 개발 서버에 배포한다
on:
workflow_dispatch:
push:
branches: [ "dev" ]
permissions:
contents: read

Expand All @@ -11,7 +12,9 @@ env:

jobs:
deploy:
runs-on: production
runs-on: dev
environment:
name: dev
steps:
- name: Get token from Submodule Reader
uses: actions/create-github-app-token@v1
Expand All @@ -27,56 +30,68 @@ jobs:
submodules: true
token: ${{ steps.app_token.outputs.token }}

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3

- name: Create bootjar
run: |
chmod +x ./gradlew
./gradlew bootjar
uses: gradle/gradle-build-action@v3
with:
arguments: bootjar

- name: Copy jar
shell: bash {0}
run: |
mkdir $JAR_DIRECTORY
cp ./build/libs/$JAR_NAME $JAR_DIRECTORY/$JAR_NAME

- name: Download Datadog Java Agent
working-directory: ${{ env.JAR_DIRECTORY }}
run: |
wget -O dd-java-agent.jar 'https://dtdg.co/latest-java-tracer'

- name: 현재 사용중인 어플리케이션 포트 확인
shell: bash {0}
run: |
if [ -n "$(lsof -ti:${{ vars.APPLICATION_PORT_A }})" ]; then
PORT_A_PID=$(lsof -ti:${{ vars.APPLICATION_PORT_A }})
PORT_B_PID=$(lsof -ti:${{ vars.APPLICATION_PORT_B }})
if [ -n $PORT_A_PID -a -n $PORT_B_PID ]; then
echo "::error title=배포 실패::$PORT_A_PID, $PORT_B_PID 두 포트가 모두 사용중입니다";
exit 1;
fi

if [ -n $PORT_A_PID ]; then
Comment on lines +50 to +56
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

포트를 둘다 쓰고 있을 경우가 있나요??

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오류가 난 적 있었어요. (짧은 시간에 여러번 배포시도한 경우)
스크립트가 서버 잘 실행된줄 알고 계속 접속 시도하더라구요.

echo "BLUE_PORT=${{ vars.APPLICATION_PORT_A }}" >> "$GITHUB_ENV"
echo "GREEN_PORT=${{ vars.APPLICATION_PORT_B }}" >> "$GITHUB_ENV"
else
fi
if [ -n $PORT_B_PID ]; then
echo "BLUE_PORT=${{ vars.APPLICATION_PORT_B }}" >> "$GITHUB_ENV"
echo "GREEN_PORT=${{ vars.APPLICATION_PORT_A }}" >> "$GITHUB_ENV"
fi

- name: Download Datadog Java Agent
working-directory: ${{ env.JAR_DIRECTORY }}
run: |
wget -O dd-java-agent.jar 'https://dtdg.co/latest-java-tracer'

- name: 그린 어플리케이션 실행
env:
RUNNER_TRACKING_ID: ""
shell: bash
working-directory: ${{ env.JAR_DIRECTORY }}
run: |
nohup java -javaagent:dd-java-agent.jar \
-Dspring.profiles.active=production \
nohup java \
-Dserver.port=$GREEN_PORT \
-Dspring.profiles.active=${{ vars.ENVIRONMENT_NAME }} \
-DACCESS_TOKEN_SECRET_KEY=${{ secrets.ACCESS_TOKEN_SECRET_KEY }} \
-DACCESS_TOKEN_EXPIRY_DAYS=${{ secrets.ACCESS_TOKEN_EXPIRY_DAYS }} \
-DREFRESH_TOKEN_SECRET_KEY=${{ secrets.REFRESH_TOKEN_SECRET_KEY }} \
-DREFRESH_TOKEN_EXPIRY_DAYS=${{ secrets.REFRESH_TOKEN_EXPIRY_DAYS }} \
-Dserver.port=$GREEN_PORT \
-DPRODUCTION_DB_URL=${{ secrets.PRODUCTION_DB_URL }} \
-DPRODUCTION_DB_USERNAME=${{ secrets.PRODUCTION_DB_USERNAME }} \
-DPRODUCTION_DB_PASSWORD=${{ secrets.PRODUCTION_DB_PASSWORD }} \
-DDB_URL=${{ secrets.DB_URL }} \
-DDB_USERNAME=${{ secrets.DB_USERNAME }} \
-DDB_PASSWORD=${{ secrets.DB_PASSWORD }} \
-javaagent:dd-java-agent.jar \
-Ddd.profiling.enabled=true \
-XX:FlightRecorderOptions=stackdepth=256 \
-Ddd.logs.injection=true \
-Ddd.appsec.enabled=true \
-Ddd.iast.enabled=true \
-Ddd.service=snackgame \
-Ddd.env=production \
-Ddd.env=${{ vars.ENVIRONMENT_NAME }} \
-jar $JAR_NAME > ~/snackgame-server.log &

- name: 그린 어플리케이션이 접속 가능할 때까지 기다린다
Expand All @@ -85,7 +100,7 @@ jobs:
PROCESS_ID="$(lsof -i:$GREEN_PORT -t)"
while [ "$(curl -o /dev/null -s -w %{http_code} localhost:$GREEN_PORT/rankings?by=BEST_SCORE)" != 200 ]
do
if [ -n "$PROCESS_ID" ]; then
if [ -e /proc/$PROCESS_ID ]; then
echo "::error title=배포 실패::블루 어플리케이션으로 롤백합니다.";
exit 1;
fi
Expand Down
126 changes: 126 additions & 0 deletions .github/workflows/production-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
name: 변경사항을 운영 서버에 배포한다
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 스크립트는 dev-deploy.yml과 발동 조건 빼고 동일합니다.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그 발동 조건이 branches: main이고 job runs-on 부분만 다른거 맞죠? 확인차 여쭙니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그 발동 조건이 branches: main이고 job runs-on 부분만 다른거 맞죠? 확인차 여쭙니다.

맞습니다!


on:
workflow_dispatch:
push:
branches: [ "main" ]
permissions:
contents: read

env:
JAR_NAME: snackgame-server.jar
JAR_DIRECTORY: /home/ubuntu/snackgame

jobs:
deploy:
runs-on: production
environment:
name: production
steps:
- name: Get token from Submodule Reader
uses: actions/create-github-app-token@v1
id: app_token
with:
app-id: ${{ secrets.SUBMODULE_APP_ID }}
private-key: ${{ secrets.SUBMODULE_APP_PEM }}
owner: ${{ github.repository_owner }}

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

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3

- name: Build
uses: gradle/gradle-build-action@v3
with:
arguments: build

- name: Copy jar
shell: bash {0}
run: |
mkdir $JAR_DIRECTORY
cp ./build/libs/$JAR_NAME $JAR_DIRECTORY/$JAR_NAME

- name: 현재 사용중인 어플리케이션 포트 확인
shell: bash {0}
run: |
PORT_A_PID=$(lsof -ti:${{ vars.APPLICATION_PORT_A }})
PORT_B_PID=$(lsof -ti:${{ vars.APPLICATION_PORT_B }})
if [ -n $PORT_A_PID -a -n $PORT_B_PID ]; then
echo "::error title=배포 실패::$PORT_A_PID, $PORT_B_PID 두 포트가 모두 사용중입니다";
exit 1;
fi

if [ -n $PORT_A_PID ]; then
echo "BLUE_PORT=${{ vars.APPLICATION_PORT_A }}" >> "$GITHUB_ENV"
echo "GREEN_PORT=${{ vars.APPLICATION_PORT_B }}" >> "$GITHUB_ENV"
fi
if [ -n $PORT_B_PID ]; then
echo "BLUE_PORT=${{ vars.APPLICATION_PORT_B }}" >> "$GITHUB_ENV"
echo "GREEN_PORT=${{ vars.APPLICATION_PORT_A }}" >> "$GITHUB_ENV"
fi

- name: Download Datadog Java Agent
working-directory: ${{ env.JAR_DIRECTORY }}
run: |
wget -O dd-java-agent.jar 'https://dtdg.co/latest-java-tracer'

- name: 그린 어플리케이션 실행
env:
RUNNER_TRACKING_ID: ""
shell: bash
working-directory: ${{ env.JAR_DIRECTORY }}
run: |
nohup java \
-Dserver.port=$GREEN_PORT \
-Dspring.profiles.active=${{ vars.ENVIRONMENT_NAME }} \
-DACCESS_TOKEN_SECRET_KEY=${{ secrets.ACCESS_TOKEN_SECRET_KEY }} \
-DACCESS_TOKEN_EXPIRY_DAYS=${{ secrets.ACCESS_TOKEN_EXPIRY_DAYS }} \
-DREFRESH_TOKEN_SECRET_KEY=${{ secrets.REFRESH_TOKEN_SECRET_KEY }} \
-DREFRESH_TOKEN_EXPIRY_DAYS=${{ secrets.REFRESH_TOKEN_EXPIRY_DAYS }} \
-DDB_URL=${{ secrets.DB_URL }} \
-DDB_USERNAME=${{ secrets.DB_USERNAME }} \
-DDB_PASSWORD=${{ secrets.DB_PASSWORD }} \
-javaagent:dd-java-agent.jar \
-Ddd.profiling.enabled=true \
-XX:FlightRecorderOptions=stackdepth=256 \
-Ddd.logs.injection=true \
-Ddd.appsec.enabled=true \
-Ddd.iast.enabled=true \
-Ddd.service=snackgame \
-Ddd.env=${{ vars.ENVIRONMENT_NAME }} \
-jar $JAR_NAME > ~/snackgame-server.log &

- name: 그린 어플리케이션이 접속 가능할 때까지 기다린다
shell: bash {0}
run: |
PROCESS_ID="$(lsof -i:$GREEN_PORT -t)"
while [ "$(curl -o /dev/null -s -w %{http_code} localhost:$GREEN_PORT/rankings?by=BEST_SCORE)" != 200 ]
do
if [ -e /proc/$PROCESS_ID ]; then
echo "::error title=배포 실패::블루 어플리케이션으로 롤백합니다.";
exit 1;
fi
echo "새로운 어플리케이션을 띄우는 중입니다.";
sleep 5;
done

- name: 리버스 프록시 설정 변경
working-directory: ${{ env.JAR_DIRECTORY }}
shell: bash {0}
run: |
echo "proxy_pass http://localhost:$GREEN_PORT;" > port.inc;
sudo nginx -s reload;

- name: 블루 어플리케이션 종료
shell: bash {0}
run: |
PROCESS_ID="$(lsof -i:$BLUE_PORT -t)"
if [ -n "$PROCESS_ID" ]; then
sudo kill -15 $PROCESS_ID
echo "구동중인 애플리케이션을 종료했습니다. (pid : $PROCESS_ID)\n"
fi
49 changes: 49 additions & 0 deletions .github/workflows/production-rebase-on-approval.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: 승인된 변경사항을 운영 브랜치에 반영한다
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이건 아직 정상 동작하는지 모릅니다.. 실제 돌려봐야 알 수 있겠네요 ㅋㅋ


on:
pull_request_review:
types: [ submitted ]

jobs:
meet-conditions:
permissions:
checks: read
contents: read
runs-on: ubuntu-latest
if: ${{ github.event.pull_request.base.ref == 'main' && github.event.pull_request.head.ref == 'dev' && github.event.review.state == 'APPROVED'}}
steps:
- name: Check Admin Permission
uses: actions-cool/[email protected]
with:
require: 'admin'

- name: Check if all checks are passed
uses: wechuli/allcheckspassed@v1

rebase:
needs: meet-conditions
permissions:
contents: write
runs-on: ubuntu-latest
steps:
- name: Get token from Submodule Reader
uses: actions/create-github-app-token@v1
id: app_token
with:
app-id: ${{ secrets.SUBMODULE_APP_ID }}
private-key: ${{ secrets.SUBMODULE_APP_PEM }}
owner: ${{ github.repository_owner }}

- name: Checkout to main
uses: actions/checkout@v4
with:
ref: 'main'
submodules: true
token: ${{ steps.app_token.outputs.token }}

- name: Rebase Branch
uses: martincostello/[email protected]

- name: Push Rebased
if : ${{ steps.rebase.outputs.result == 'success' }}
run: git push
13 changes: 6 additions & 7 deletions .github/workflows/ci.yml → .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name: build and test with Gradle
name: PR을 테스트한다

on:
workflow_dispatch:
pull_request:
branches: [ "main" ]
branches: [ "main", "dev" ]

permissions:
contents: read
Expand All @@ -20,7 +20,7 @@ jobs:
app-id: ${{ secrets.SUBMODULE_APP_ID }}
private-key: ${{ secrets.SUBMODULE_APP_PEM }}
owner: ${{ github.repository_owner }}

- name: Checkout
uses: actions/checkout@v4
with:
Expand All @@ -33,12 +33,11 @@ jobs:
java-version: '17'
distribution: 'corretto'

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

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3

- name: Build with Gradle
uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
uses: gradle/gradle-build-action@v3
with:
arguments: build

Expand Down
22 changes: 22 additions & 0 deletions src/main/resources/application-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
spring:
datasource:
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
jpa:
hibernate:
ddl-auto: validate
security:
jwt:
token:
access-secret-key: ${ACCESS_TOKEN_SECRET_KEY}
access-expiry-days: ${ACCESS_TOKEN_EXPIRY_DAYS}
refresh-secret-key: ${REFRESH_TOKEN_SECRET_KEY}
refresh-expiry-days: ${REFRESH_TOKEN_EXPIRY_DAYS}
server:
port: ${APPLICATION_PORT}
forward-headers-strategy: native
servlet:
session:
cookie:
same-site: none
6 changes: 3 additions & 3 deletions src/main/resources/application-production.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
spring:
datasource:
url: ${PRODUCTION_DB_URL}
username: ${PRODUCTION_DB_USERNAME}
password: ${PRODUCTION_DB_PASSWORD}
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
jpa:
hibernate:
ddl-auto: validate
Expand Down
Loading