Skip to content

Maintenance: Cursor pagination - Eliminate redundant result limiting … #184

Maintenance: Cursor pagination - Eliminate redundant result limiting …

Maintenance: Cursor pagination - Eliminate redundant result limiting … #184

Workflow file for this run

name: Container Registry CI/CD Pipeline (Watchtower Auto-Deploy)
on:
push:
branches:
- master
- dev
workflow_dispatch:
inputs:
force_infra_deploy:
description: "Force infra deploy (use when GitHub Secrets changed)"
required: false
default: "false"
type: choice
options: ["false", "true"]
reason:
description: "Reason for manual deploy"
required: false
type: string
env:
REGISTRY_URL: ${{ secrets.NCP_REGISTRY_URL }}
IMAGE_NAME: meme-wiki-be
jobs:
build-and-push:
name: Build and Push to Registry
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v3
with:
java-version: '21'
distribution: 'temurin'
cache: gradle
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew clean build -x test
- name: Get commit SHA and determine environment
id: vars
run: |
echo "SHORT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
echo "TIMESTAMP=$(date +%Y%m%d-%H%M%S)" >> $GITHUB_OUTPUT
if [ "${{ github.ref }}" == "refs/heads/master" ]; then
echo "ENV_TAG=prod" >> $GITHUB_OUTPUT
echo "DOCKERFILE=Dockerfile" >> $GITHUB_OUTPUT
elif [ "${{ github.ref }}" == "refs/heads/dev" ]; then
echo "ENV_TAG=dev" >> $GITHUB_OUTPUT
echo "DOCKERFILE=dev.Dockerfile" >> $GITHUB_OUTPUT
else
echo "ENV_TAG=dev" >> $GITHUB_OUTPUT
echo "DOCKERFILE=dev.Dockerfile" >> $GITHUB_OUTPUT
fi
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to NCP Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY_URL }}
username: ${{ secrets.NCP_ACCESS_KEY }}
password: ${{ secrets.NCP_SECRET_KEY }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./${{ steps.vars.outputs.DOCKERFILE }}
push: true
tags: |
${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ steps.vars.outputs.ENV_TAG }}
${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ steps.vars.outputs.SHORT_SHA }}
${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ steps.vars.outputs.TIMESTAMP }}
cache-from: type=gha
cache-to: type=gha,mode=max
# Infrastructure changes detection and deployment
- name: Check for infrastructure changes
uses: dorny/paths-filter@v2
id: changes
with:
filters: |
infra:
- 'docker-compose.yml'
- 'init-scripts/**'
- name: Deploy infrastructure changes
if: steps.changes.outputs.infra == 'true' || (github.event_name == 'workflow_dispatch' && inputs.force_infra_deploy == 'true')
uses: appleboy/scp-action@master
with:
host: ${{ secrets.NCP_SERVER_HOST }}
username: root
key: ${{ secrets.SSH_PRIVATE_KEY }}
source: "docker-compose.yml,init-scripts/"
target: "/home/ubuntu/app/"
overwrite: true
- name: Restart services for infrastructure changes
if: steps.changes.outputs.infra == 'true' || (github.event_name == 'workflow_dispatch' && inputs.force_infra_deploy == 'true')
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.NCP_SERVER_HOST }}
username: root
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /home/ubuntu/app
echo "🔄 Restarting services (infra_changed=${{ steps.changes.outputs.infra }}, force=${{ inputs.force_infra_deploy }})..."
# Export runtime env vars from GitHub Secrets (no .env file needed)
export MYSQL_ROOT_PASSWORD='${{ secrets.MYSQL_ROOT_PASSWORD }}'
export MYSQL_DATABASE='${{ secrets.MYSQL_DATABASE }}'
export MYSQL_DEV_DATABASE='${{ secrets.MYSQL_DEV_DATABASE }}'
export MYSQL_USER='${{ secrets.MYSQL_USER }}'
export MYSQL_PASSWORD='${{ secrets.MYSQL_PASSWORD }}'
export NCP_REGISTRY_URL='${{ secrets.NCP_REGISTRY_URL }}'
export CLOUDFLARE_R2_ACCESS_KEY_ID='${{ secrets.CLOUDFLARE_R2_ACCESS_KEY_ID }}'
export CLOUDFLARE_R2_SECRET_ACCESS_KEY='${{ secrets.CLOUDFLARE_R2_SECRET_ACCESS_KEY }}'
export CLOUDFLARE_R2_ENDPOINT='${{ secrets.CLOUDFLARE_R2_ENDPOINT }}'
export CLOUDFLARE_R2_BUCKET_NAME='${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }}'
export ADMIN_USERNAME='${{ secrets.ADMIN_USERNAME }}'
export ADMIN_PASSWORD='${{ secrets.ADMIN_PASSWORD }}'
export GOOGLE_GENAI_API_KEY='${{ secrets.GOOGLE_GENAI_API_KEY }}'
export NAVER_AI_API_KEY='${{ secrets.NAVER_AI_API_KEY }}'
export PINECONE_API_KEY='${{ secrets.PINECONE_API_KEY }}'
export PINECONE_INDEX_NAME='${{ secrets.PINECONE_INDEX_NAME }}'
export PINECONE_ENVIRONMENT='${{ secrets.PINECONE_ENVIRONMENT }}'
# FCM 서비스 계정 키 파일 생성
mkdir -p /root/config
echo '${{ secrets.FCM_SERVICE_ACCOUNT_JSON }}' > /root/config/fcm-service-account.json
chmod 600 /root/config/fcm-service-account.json
docker compose pull app app-dev
docker compose up -d app app-dev
docker compose ps
echo "✅ App service restarted"
echo "🧹 Cleaning up Docker resources..."
docker image prune -a -f
echo "✅ Docker cleanup completed"
- name: Deployment completed
run: |
echo "✅ 이미지 배포 완료: ${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ steps.vars.outputs.ENV_TAG }}"
echo "📦 Dockerfile: ${{ steps.vars.outputs.DOCKERFILE }}"
echo "event=${{ github.event_name }} infra_changed=${{ steps.changes.outputs.infra }} force=${{ inputs.force_infra_deploy }}"
if [ "${{ steps.changes.outputs.infra }}" == "true" ] || { [ "${{ github.event_name }}" == "workflow_dispatch" ] && [ "${{ inputs.force_infra_deploy }}" == "true" ]; }; then
echo "🔧 Infrastructure changes deployed via SSH"
echo "🐳 Services restarted with new configuration"
else
echo "🐳 Watchtower가 5분 내 자동 배포 시작"
fi