github action sample
spring boot
-
gradle build를 사용하는 spring boot를 빌드하고 ssh로
-
secret 류는 setting-> security에 Secrets and variables 내 action 메뉴에서 설정
-
마지막에 slack webhook으로 배포 상황 알림
-
action 설정이나 slack webhoook url 설정하는 방법은 다른 블로그에도 많으니 생략하겠습니다.
name: Build and Deploy on: push: branches: - develop jobs: build-and-deploy: runs-on: ubuntu-latest steps: # 1. SSH 호스트 키 추가 - name: Add SSH known hosts run: | mkdir -p ~/.ssh ssh-keyscan -H github.com >> ~/.ssh/known_hosts # 2. 리포지토리 체크아웃 (서브모듈 포함) - name: Checkout repository with submodules uses: actions/checkout@v3 with: submodules: recursive ssh-key: ${{ secrets.PRIVATE_KEY_FOR_SUBMODULE }} fetch-depth: 0 # 3. 서브모듈 최신화 - name: Update submodules to the latest run: | git submodule update --init --recursive git submodule foreach git pull origin $(git rev-parse --abbrev-ref HEAD) # 4. JDK 설정 - name: Set up JDK 23 uses: actions/setup-java@v3 with: java-version: '23' distribution: 'temurin' # 5. Gradle 빌드 - name: Build with Gradle run: ./gradlew clean build -x test # 6. 서버로 파일 전송 - name: Deploy to Server env: SSH_PRIVATE_KEY: ${{ secrets.DEV_SSH_PRIVATE_KEY }} DEPLOY_SERVER_IP: ${{ secrets.DEV_SERVER_IP }} DEPLOY_SERVER_USER: ${{ secrets.DEV_SERVER_USER }} run: | echo "DEPLOY_SERVER_IP: $DEPLOY_SERVER_IP" mkdir -p ~/.ssh echo "$SSH_PRIVATE_KEY" > ~/.ssh/github_action chmod 600 ~/.ssh/github_action ssh-keyscan -H "$DEPLOY_SERVER_IP" >> ~/.ssh/known_hosts # 빌드 파일 전송 scp -i ~/.ssh/github_action build/libs/*.jar $DEPLOY_SERVER_USER@$DEPLOY_SERVER_IP:/home/$DEPLOY_SERVER_USER/backend/ # swagger rest doc json # scp -i ~/.ssh/github_action build/resources/main/restdocs/*.json $DEPLOY_SERVER_USER@$DEPLOY_SERVER_IP:/home/$DEPLOY_SERVER_USER/swagger-docs/ find build/resources/main/restdocs -name "*.json" | grep . && scp -i ~/.ssh/github_action build/resources/main/restdocs/*.json $DEPLOY_SERVER_USER@$DEPLOY_SERVER_IP:/home/$DEPLOY_SERVER_USER/swagger-docs/ || echo "No JSON files to copy, skipping..." # 7. 서버에서 애플리케이션 실행 - name: Start Application env: DEPLOY_SERVER_IP: ${{ secrets.DEV_SERVER_IP }} SERVER_USER: ${{ secrets.DEV_SERVER_USER }} REPOSITORY_NAME: ${{ github.repository }} run: | PROJECT_NAME=$(echo $REPOSITORY_NAME | cut -d'/' -f2) ssh -i ~/.ssh/github_action $SERVER_USER@$DEPLOY_SERVER_IP << EOF cd /home/$SERVER_USER/backend chmod 700 /home/$SERVER_USER/backend/${PROJECT_NAME}*-exec.jar sh /home/$SERVER_USER/bin/deploy.sh $PROJECT_NAME dev /home/$SERVER_USER 512m sh /home/$SERVER_USER/infra/swagger/swagger_script.sh restart ${PROJECT}-api.json EOF - name: action-slack uses: 8398a7/action-slack@v3 with: status: ${{ job.status }} author_name: Pink Spider - dev fields: repo,commit,message,author # action,eventName,ref,workflow,job,took 추가할 수 있음 mention: here if_mention: failure,cancelled env: SLACK_WEBHOOK_URL: ${{ secrets.DEV_SLACK_WEBHOOK_URL }} # required if: always() # Pick up events even if the job fails or is canceled. -
deploy.sh
#!/bin/sh PROJECT=$1 PROFILE=$2 HOMEDIR=$3 MEM_ALLOC=$4 APP_DIR=${HOMEDIR}/backend JAR_PREFIX=${APP_DIR}/${PROJECT} # JAR_NAME이 실제 존재하는 파일인지 확인 JAR_NAME=$(ls ${JAR_PREFIX}-*exec.jar 2>/dev/null | head -n 1) JAR_CURRENT_PID=$(ps -ef | grep ${JAR_PREFIX} | grep -v grep | awk '{print $2}') echo "APP_DIR = $APP_DIR" echo "JAR_PREFIX = $JAR_PREFIX" echo "JAR_NAME = $JAR_NAME" if [ -z "${JAR_CURRENT_PID}" ]; then echo "> no process is running" else echo "> kill project name : ${JAR_PREFIX} ${JAR_CURRENT_PID}" kill -9 ${JAR_CURRENT_PID} sleep 3 fi # JAR_NAME이 존재하는지 확인 if [ -z "$JAR_NAME" ]; then echo "❌ No JAR file found! Exiting..." exit 1 fi # 실행 명령어를 문자열로 저장 후 실행 COMMAND="nohup setsid java --add-exports=java.base/com.sun.crypto.provider=ALL-UNNAMED -jar -Xmx${MEM_ALLOC} -Dspring.profiles.active=${PROFILE} ${JAR_NAME} >> /dev/null 2>&1 &" echo "Executing: $COMMAND" eval $COMMAND echo "✅ Application started successfully!"