Pink Spider/github action sample with spring boot

Created Tue, 25 Mar 2025 18:01:05 +0900 Modified Mon, 08 Dec 2025 08:41:47 +0900
621 Words 3 min

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!"