Skip to content

Add GitHub Actions workflow for NPM package publishing #36

Add GitHub Actions workflow for NPM package publishing

Add GitHub Actions workflow for NPM package publishing #36

name: workflow-name # 워크플로 이름
on:
push:
branches: # 워크플로 대상 브랜치
# - main
# - test
paths-ignore: # 제외 경로
# - 'CHANGELOG.md'
# - 'package.json'
# - 'package-lock.json'
env:
PROJECT_NAME: my-project # 프로젝트 명
DOCKERHUB_REPO: ${{ secrets.DOCKERHUB_USERNAME }}
APP_IMAGE_SUFFIX: "-web"
MAIN_PORT: "3000"
TEST_PORT: "3001"
APP_EXPOSE_PORT: "3000"
jobs:
build:
if: ${{ !startsWith(github.event.head_commit.message, 'version(') }} # 특정 커밋 메시지 워크플로 실행 제외
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
# 브랜치별 .env.production 생성
- name: Create .env.production file
run: |
if [ "${{ github.ref_name }}" = "main" ]; then
echo -e "${{ secrets.ENV_MAIN }}" > .env.production
elif [ "${{ github.ref_name }}" = "test" ]; then
echo -e "${{ secrets.ENV_TEST }}" > .env.production
else
echo -e "${{ secrets.ENV_MAIN }}" > .env.production
fi
- name: Docker setup
uses: docker/setup-buildx-action@v3
- name: Docker login
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.PROJECT_NAME }}${{ env.APP_IMAGE_SUFFIX }}:${{ github.ref_name }}
cache-from: type=gha
cache-to: type=gha,mode=max
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- name: Deploy
uses: appleboy/ssh-action@v1.0.3
env:
PROJECT_NAME: ${{ env.PROJECT_NAME }}
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
password: ${{ secrets.SERVER_PASSWORD }}
port: ${{ secrets.SERVER_PORT }}
envs: PROJECT_NAME
script: |
set -e
export PATH=$PATH:/usr/local/bin
echo "환경변수 설정.."
PW="${{ secrets.SERVER_PASSWORD }}"
BRANCH="${{ github.ref_name }}"
REPO="${{ env.DOCKERHUB_REPO }}"
PROJECT="${{ env.PROJECT_NAME }}"
IMG_SUFFIX="${{ env.APP_IMAGE_SUFFIX }}"
IMAGE="${REPO}/${PROJECT}${IMG_SUFFIX}:${BRANCH}"
CONTAINER_NAME="${PROJECT_NAME}${IMG_SUFFIX}"
APP_PORT="${{ env.APP_EXPOSE_PORT }}"
MAIN_PORT="${{ env.MAIN_PORT }}"
TEST_PORT="${{ env.TEST_PORT }}"
echo "브랜치=${BRANCH}"
echo "이미지=${IMAGE}"
echo "MAIN_PORT=${MAIN_PORT} | TEST_PORT=${TEST_PORT}"
if [ "$BRANCH" = "main" ]; then
PORT="${MAIN_PORT}"
elif [ "$BRANCH" = "test" ]; then
CONTAINER_NAME="${CONTAINER_NAME}-test"
PORT="${TEST_PORT}"
else
echo "지원하지 않는 브랜치: ${BRANCH}"
exit 1
fi
echo "브랜치: ${BRANCH}"
echo "컨테이너 이름: ${CONTAINER_NAME}"
echo "포트: ${PORT}"
echo "도커 이미지 풀 : ${IMAGE}"
echo $PW | sudo -S docker pull "${IMAGE}"
echo "컨테이너 ${CONTAINER_NAME} 존재 여부 확인 중..."
if sudo docker ps -a --format '{{.Names}}' | grep -Eq "^${CONTAINER_NAME}\$"; then
echo "컨테이너 ${CONTAINER_NAME} 이(가) 존재합니다. 중지 및 삭제 중..."
echo $PW | sudo -S docker rm -f "${CONTAINER_NAME}"
echo "컨테이너 ${CONTAINER_NAME} 이(가) 삭제되었습니다."
else
echo "존재하는 컨테이너 ${CONTAINER_NAME} 이(가) 없습니다."
fi
echo "브랜치별 .env.production 생성..."
if [ "$BRANCH" = "main" ]; then
echo "${{ secrets.ENV_MAIN }}" > .env.production
elif [ "$BRANCH" = "test" ]; then
echo "${{ secrets.ENV_TEST }}" > .env.production
else
echo "${{ secrets.ENV_MAIN }}" > .env.production
fi
echo "새로운 컨테이너 ${CONTAINER_NAME} 실행 중..."
echo $PW | sudo -S docker run -d -p "${PORT}":"${APP_PORT}" --name "${CONTAINER_NAME}" \
--restart unless-stopped \
--env-file .env.production \
"${IMAGE}"
# <none> 태그로 남은 이미지 정리
echo "불필요한 dangling(<none>) 이미지 정리..."
echo $PW | sudo -S docker image prune -af
echo "배포가 성공적으로 완료되었습니다."