단순했던 첫 배포 파이프라인
Kampus 프로젝트는 초기 Git Flow 를 따르자고 정했다.

feature 브랜치에서 develop 으로 PR 을 올렸을 때 → Squash and merge → merge 후 remote branch 삭제
기능 단위로 개발한 브랜치이기 때문에, 개발서버에도 기능 단위 커밋을 관리할 수 있다. 브랜치를 삭제하므로 merge commit 을 남길 필요가 없다.
develop 브랜치에서 main 브랜치로 배포 돌릴 때 → Rebase and merge
모든 기능을 배포할때 병합한다. 특정 기능에서 문제가 발생했을 경우 롤백이 필요하다. merge commit 을 남길 필요가 없다.
Git Flow : 초기에는 지키려고 노력했지만, 데모데이가 다가오며 많아지는 merge 와 배포에 흐름이 깨졌다. 🥲
🚨 MVP 가 많아지면서 단순 기능구현이 많아졌고, merge 과정에서 작업한 코드가 사라지는 문제가 발생했다. QA, 진행사항 검증 시에 동료가 작업한 부분이 업데이트 되지 않아 다른 파트에서 혼란을 주기도 했다.

코드리뷰를 필수로 두었기 때문에 동료들끼리 부담도 조금 있었던 것 같다. open 되어있는 기간이 길어지면서 프로젝트 작업사항이 늘어지는 경향도 있었다.
또한 develop 브랜치를 merge + 배포 브랜치로 사용해서 push 할때마다 배포서버가 돌아가고, 불필요한 비용과 불안정성 문제가 발생했다. 결국 최근까지는 배포 서버를 잠시 꺼두었다.
🙏 코드는 계속 합치되, 배포는 필요할 때만 하고 싶다
AWS 계정이 나의 것이 아니기 때문에, IAM 역할(Role)이나 키(Key)를 자유롭게 생성하거나 수정할 수 없는 상황이었다.
그래서 develop 브랜치만을 사용해서 위 배포전략을 도입할 수 있는지 확인해 보았다.
배포되는 코드에 버전을 붙여서 명시적으로 참조할 수 있도록 git tag based deployment 전략도 함께 사용할 것이다. 위 문제점을 함께 해결할 수 있는 방법으로 판단했다.
👀 CI 와 CD 의 역할의 구분
기존 배포 서비스는 하나의 main.yml 에서 필요한 작업만을 수행했다.
name: Deploy
on:
push:
branches: ['develop']
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up Node
uses: actions/setup-node@v3
with:
node-version: 20
cache: 'npm'
- name: Prepare Environment
run: rm -f .env.production && touch .env.production
- name: Set ENV Variables
run: |
echo "VITE_GOOGLE_CLIENT_ID=${{ secrets.VITE_GOOGLE_CLIENT_ID }}" >> .env.production
echo "VITE_KAKAO_JS_KEY=${{ secrets.VITE_KAKAO_JS_KEY }}" >> .env.production
echo "VITE_KAKAO_REDIRECT_URI=${{ secrets.VITE_KAKAO_REDIRECT_URI }}" >> .env.production
echo "VITE_API_BASE_URL=${{ secrets.VITE_API_BASE_URL }}" >> .env.production
echo "VITE_API_SOCKET_URL=${{ secrets.VITE_API_SOCKET_URL }}" >> .env.production
- name: Install Dependencies
run: npm install --force
- name: Build Production
run: CI=false npm run build --if-present
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-2
- name: Deploy to S3
env:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: aws s3 sync --region ap-northeast-2 dist s3://kampus-bucket --delete
- name: Invalidate CloudFront Cache
run: aws cloudfront create-invalidation --distribution-id ${{secrets.AWS_DISTRIBUTION_ID}} --paths "/*"
develop 브랜치에 코드가 푸시될 때마다 빌드부터 배포까지 모든 과정을 한 번에 자동으로 실행한다.
- `on: push: branches: ['develop']` : develop 브랜치에 푸시될때 아래 워크플로우 전체를 실행한다.
- `Checkout` : 워크플로우가 실행될 가상 환경에 해당 저장소의 코드를 내려받는다.
- `Set up Node` : Node.js 환경 설정. `cache: 'npm'` 설정으로 의존성 설치 속도를 향상시킬 수 있다.
- `Prepare Environment & Set ENV Variables` : 빌드 시 필요한 환경 변수(API 키 등)를 .env.production 파일에 기록한다. 이 변수들은 GitHub Secrets에서 안전하게 가져온다. 즉 git actions 를 배포시스템으로 사용한다면, github secrets 에 개발 env 와 동일한 환경변수를 등록해야 한다.
- `Install Dependencies` : npm install --force 명령으로 package.json에 명시된 모든 의존성을 설치.
--force 옵션은 충돌을 무시하고 강제로 설치한다.문제가 발생할 수 있기 때문에, 사용을 지양해야 한다. - `Build Production` : npm run build 명령으로 실제 서비스될 웹사이트 파일들을 생성하여 dist 폴더에 담는다. 즉 빌드한다.
- `Deploy to S3` : 빌드된 dist 폴더의 내용을 S3 버킷에 동기화한다. --delete 옵션은 기존 파일 중 불필요한 것을 삭제한다.
- `Invalidate CloudFront Cache` : CloudFront CDN에 저장된 이전 버전의 캐시를 모두 무효화하여, 모든 사용자가 즉시 최신 버전의 웹사이트를 볼 수 있도록 한다. (과거 프로젝트에서 버전 업데이트에 일주일 이상이 걸려 난감함을 겪은 적이 있다. 기간은 예상할 수 없었다.)
하나의 파일에서 의존성 설치, 빌드, 동기화 모든 작업을 진행한다. 코드품질, 테스트 등에 대한 검증은 없었다. 기존 작업을 ci.yml, cd.yml 두개의 파일로 구분하고, 역할 또한 분류하기로 결정했다.
CI : 코드 품질 검사, 빌드 가능성 확인
`.github/workflows/ci.yml` 파일에 정의된 역할은 develop 브랜치로 들어오는 모든 코드 변경을 Push, Pull Request 할 때에 꼼꼼히 검증하는 것이었다.
코드 스타일 `Prettier`과 문법 `ESLint`을 확인한 뒤, 최종적으로 프로젝트를 빌드`npm run build`하여 배포 가능한 상태인지를 테스트했다.
이 워크플로우는 절대 배포를 실행하지 않는다.
name: CI
on:
push:
branches: ['develop']
pull_request:
branches: ['develop']
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up Node
uses: actions/setup-node@v3
with:
node-version: 20
cache: 'npm'
- name: Install Dependencies
run: npm ci
- name: Run Code Quality Check
run: npm run prettier:check && npm run lint
- name: Prepare Environment
run: rm -f .env.production && touch .env.production
- name: Set ENV Variables
run: |
echo "VITE_GOOGLE_CLIENT_ID=${{ secrets.VITE_GOOGLE_CLIENT_ID }}" >> .env.production
echo "VITE_KAKAO_JS_KEY=${{ secrets.VITE_KAKAO_JS_KEY }}" >> .env.production
echo "VITE_KAKAO_REDIRECT_URI=${{ secrets.VITE_KAKAO_REDIRECT_URI }}" >> .env.production
echo "VITE_API_BASE_URL=${{ secrets.VITE_API_BASE_URL }}" >> .env.production
echo "VITE_API_SOCKET_URL=${{ secrets.VITE_API_SOCKET_URL }}" >> .env.production
- name: Build Production
run: CI=false npm run build --if-present
- name: Upload Build Artifact
if: github.event_name == 'push' && github.ref == 'refs/heads/develop'
uses: actions/upload-artifact@v4
with:
name: dist-${{ github.sha }}
path: dist/
retention-days: 30
- `on: push || pull_request` : 기존에는 push 일때 main을 실행했다. 코드 품질 검사는 pr 시에도 검사하도록 하고, 실패가 발생하면 pr 단계에서 수정할 수 있다.
- `Install Dependencies` : ci 단계에서는 package-lock.json 을 사용해서 의존성을 설치하는 `npm ci` 방식을 권장하고 있다.
- `Run Code Quality Check` : prettier 와 eslint 를 검사하는 단계이다. run 에 적힌 명령어들을은 package.json script 에 등록되어 있어야 한다. write 수정하는 단계가 아닌, check 검사를 실행한다.
- build (환경변수 이후 단계) :
- PR : develop에 합치기 전에 코드가 문제없는지 검증하는 것이 주 목적이다. 빌드가 성공하는지 확인이 필요하다.
- push : 빌드된 파일이 함께 담겨서 merge 되어야 한다. Artifact 아티팩트와 함께 설명
🧐 CI 는 코드품질 검사라면서? 빌드를 꼭 해야하나?
위같은 의문이 들 수 있다. 무결성, 안정성 을 위한 최종 관문과 같은 역할을 한다.
push 할때 빌드파일을 함께 보낸다면, develop 브랜치에 있는 코드는 언제나 빌드가 성공하는 상태 임을 보장하게 된다.
만약 PR에서 빌드를 해보지 않으면, 코드 리뷰까지 마친 코드가 develop에 머지된 후에야 빌드 실패를 발견하게 될 수 있다. 결국, 다른 팀원의 작업에 영향을 줄 수 있는 불안정한 상태를 만들 수 있다.
PR 단계에서 미리 빌드를 해봄으로써, 다음과 같은 문제들을 사전에 차단할 수 있다.
- 환경 변수 설정 오류로 인한 빌드 실패
- 라이브러리 간 충돌로 인한 문제
- 타입스크립트 컴파일 에러 (Kampus 는 해당사항 없음)
ci 에서 빌드한 파일을 cd 에서 다운받아서 S3 에 배포하는 방법? `Artifact`
ci 에서 사용한 코드와 cd 에서 사용한 코드가 100% 동일하다고 보장할 수 있다.
cd 에서 프로젝트 빌드 시간을 단축할 수 있다.
🏚️ Artifact 아티팩트
워크플로 아티팩트 다운로드 - GitHub Docs
기본적으로 GitHub는 90일 동안 빌드 로그와 아티팩트를 저장하며 리포지토리 유형에 따라 이 보존 기간을 사용자 지정할 수 있습니다. 자세한 내용은 리포지토리에 대한 GitHub Actions 설정 관리을(
docs.github.com
파이프라인의 각 단계에서 생성되는 결과물
프론트엔드 프로젝트의 경우, npm run build를 실행했을 때 생성되는 dist 또는 build 폴더를 빌드 아티팩트라고 한다. 이 외에도 테스트 결과 리포트, Docker 이미지 등도 아티팩트가 될 수 있다.
일반적으로 권장되는 CI/CD 파이프라인에서는 CI 단계에서 코드 품질 검사, 테스트, 빌드까지 모두 수행한다.
즉 CI에서 빌드까지 마친 후, 이 아티팩트를 CD 단계에 넘겨주어 배포만 진행하게 하는 것!
장점
- 신뢰성 및 일관성 보장: "테스트를 통과한 바로 그 결과물" 배포
- CI에서 빌드를 마친 아티팩트는 검증이 완료된 상태
- 만약 CD에서 다시 소스 코드를 받아와 빌드하면, 그 사이에 의존성이 미세하게 변경되는 등 예측 불가능한 변수가 생길 수 있다. 아티팩트 방식은 이러한 위험을 차단한다.
- 배포 속도 증가
- CD 파이프라인에서는 무거운 npm install이나 시간이 오래 걸리는 npm run build 과정을 생략한다.
- 이미 만들어진 아티팩트를 내려받아 배포만 하면 되므로, 배포 단계가 매우 빠르고 가벼워진다.
단점
- 초기 설정의 복잡도
- actions/upload-artifact, actions/download-artifact
- 아티팩트를 업로드하고 다운로드하는 과정이 워크플로우에 추가되어야 한다.
- 아티팩트 저장 비용
- 아티팩트를 저장할 공간이 필요하다.
- GitHub Actions의 경우 기본 제공 용량이 있지만, 초과 시 비용 발생한다.
즉 CI에서 `코드 검사 → 테스트 → 빌드 → 아티팩트 업로드`를 수행하고, CD에서는 `아티팩트 다운로드 → 배포`만 담당하도록 역할을 구분하는 것이다.
ci, cd 로 트리거가 독립된 워크플로우로 구분되어 있어도, 동일 커밋 기반이기 때문에 파일을 공유할 수 있다.
CI `Upload Build Artifact` 단계에서 빌드된 파일을 아티팩트에 업로드 하도록 했다.
💡if 조건을 통해 pr 생성시에는 아티팩트에 업로드하지 않고, push 할때에만 배포용 아티팩트를 생성하고 업로드 하도록 설정했다.
github.event_name == 'push' && github.ref == 'refs/heads/develop'
또한, 아티팩트 이름을 커밋 해시와 연결하여 고유하게 만들었다.
CD : v *태그 기반의 실제 서버 배포
`github/workflows/cd.yml`에서는 develop 브랜치에서 push 작업을 하다가, 코드가 안정화 되었거나 런칭해도 괜찮다고 판단할때 실행되도록 설계했다.
이는 배포를 명시적인 태그와 동일시하고, 통제하려는 전략이었다.
CI가 만들어둔 아티팩트를 정확히 찾아 다운로드한 뒤, AWS S3에 업로드하고 CloudFront 캐시를 무효화한다.
name: Manual Release and Deploy
on:
workflow_dispatch:
jobs:
release-and-deploy:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout develop branch
uses: actions/checkout@v4
with:
ref: 'develop'
fetch-depth: 0
- name: Get latest commit SHA
id: get_sha
run: echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
- name: Get next version
id: version
run: |
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
VERSION_PARTS=(${LATEST_TAG//./ })
MAJOR=${VERSION_PARTS[0]#v}
MINOR=${VERSION_PARTS[1]}
PATCH=${VERSION_PARTS[2]}
NEW_PATCH=$((PATCH + 1))
NEW_TAG="v${MAJOR}.${MINOR}.${NEW_PATCH}"
echo "new_tag=$NEW_TAG" >> $GITHUB_OUTPUT
- name: Download Build Artifact
uses: actions/download-artifact@v4
with:
name: dist-${{ steps.get_sha.outputs.sha }}
path: dist/
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-2
- name: Deploy to S3
run: aws s3 sync ./dist s3://kampus-bucket --delete
- name: Invalidate CloudFront Cache
run: aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_DISTRIBUTION_ID }} --paths "/*"
- name: Create Release and Tag
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.version.outputs.new_tag }}
name: 'Release ${{ steps.version.outputs.new_tag }}'
generate_release_notes: true
- `on: workflow_dispatch` : 수동 배포 버튼 역할
- 개발자가 직접 GitHub 저장소의 Actions 탭에서 'Run workflow' 버튼을 눌러야 시작된다.
- `permissions: contents: write` : Git 태그를 생성하고 GitHub Release를 발행하는 등, 저장소의 내용에 쓰기 작업을 할 수 있도록 권한을 부여한다.
- 이 권한이 없으면 Create Release and Tag 단계에서 실패
- `Checkout develop branch` : develop 브랜치의 최신 소스 코드를 가져옴
- `fetch-depth: 0` : Git의 전체 히스토리를 가져와, 나중에 버전 태그를 찾고 릴리즈 노트를 생성할 때 사용한다.
- `Get latest commit SHA` : 체크아웃한 develop 브랜치의 가장 최신 커밋 해시(고유 ID)를 찾아 저장한다. 이 값은 나중에 정확한 빌드 아티팩트를 찾는 데 사용된다.
- `id: get_sha` : 이 단계의 ID를 get_sha로 지정하여, 나중에 steps.get_sha.outputs.sha 형태로 결과를 참조할 수 있다.
- `echo "sha=..." >> $GITHUB_OUTPUT: git rev-parse HEAD` : sha라는 이름의 출력 변수로 만듬
- `Get next version`: 저장소의 마지막 태그를 기준으로 다음 패치 버전을 자동으로 계산한다. (예: v1.0.0 → v1.0.1)
- `LATEST_TAG=$(git describe ... || echo "v0.0.0"): git describe` : 마지막 태그를 찾되, 태그가 하나도 없으면 v0.0.0에서 시작하도록 처리한다.
- `NEW_PATCH=$((PATCH + 1))` : 셸 스크립트를 이용해 마지막 버전 숫자를 1 증가시킨다.
- `Download Build Artifact` : CI 워크플로우가 이전에 만들어 둔 빌드 결과물인 아티팩트를 다운로드한다.
- `name: dist-${{ steps.get_sha.outputs.sha }}` : `Get latest commit SHA` 단계에서 찾은 커밋 해시를 이용해, 정확히 일치하는 아티팩트의 이름을 지정하여 다운로드한다. 🔗 CI와 CD를 연결하는 핵심 고리
- main.yml 의 환경변수, S3 버킷 업로드, 캐시무효화 동일
- `Create Release and Tag` : releas 태그, 릴리즈 노트 통제
- 배포가 완료된 후, 계산된 새 버전으로 Git 태그를 생성
- 해당 버전의 릴리즈 노트를 GitHub에 자동으로 발행
- `uses: softprops/action-gh-release@v2` : 릴리즈 발행을 쉽게 처리해 주는 인기 있는 커뮤니티 액션
- `generate_release_notes: true` : 마지막 릴리즈 이후의 모든 커밋 메시지를 자동으로 취합하여 릴리즈 노트 본문을 만들어 준다.
🚨 release 태그 & 릴리즈노트 자동화 배포 ❌ 트리거 통제 ⭕️
create-release:
runs-on: ubuntu-latest
permissions:
contents: write
needs: ci
if: needs.ci.result == 'success' && github.event_name == 'push' && github.ref == 'refs/heads/develop'
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get next version
id: version
run: |
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
VERSION_PARTS=(${LATEST_TAG//./ })
MAJOR=${VERSION_PARTS[0]#v}
MINOR=${VERSION_PARTS[1]}
PATCH=${VERSION_PARTS[2]}
NEW_PATCH=$((PATCH + 1))
NEW_TAG="v${MAJOR}.${MINOR}.${NEW_PATCH}"
echo "new_tag=$NEW_TAG" >> $GITHUB_OUTPUT
- name: Create Release Notes and Tag
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.version.outputs.new_tag }}
name: "Release ${{ steps.version.outputs.new_tag }}"
generate_release_notes: true
위 코드처럼 ci 가 돌아가고, cd 이전에 태그와 릴리즈 노트를 자동화 시킨다. 그리고 release 생성과 문서를 기반으로 cd 를 돌아가게 할 수 있다.
그러나 이 과정까지 자동화 할 경우, 배포 전략에 문제가 발생한다.
💡 배포와 머지 모두 develop 브랜치를 사용한다. 머지는 배포되지 않는다. 태그가 있는 머지는 배포된다.
태그&릴리즈 노트 자동화 할 경우, 모든 머지는 배포 프로세스를 진행하게 된다.
이 전략은 브랜치 배포 플로우가` features → develop 개발서버 → main 배포서버` 개발서버와 배포서버가 구분되어있을때, 개발서버에서 배포서버로 넘길때 모든 스텝을 자동화 할 수 있다.
그러나 Kampus 프로젝트는 코드 혼란의 비용을 줄이기 위해 develop 브랜치 하나만 사용하기로 결정했었다. 하나의 브랜치를 사용해서 워크플로우를 생성할 경우, push 와 배포는 구분되어야 한다.
workflow_dispatch
이것을 구분할 수 있는 것이 워크플로우를 트리거하는 이벤트 workflow_dispatch 이다.
자동화의 주체를 ⭕️이벤트 중심⭕️으로 실행한다!
❌ 사람, 코드, 브랜치 ❌
Github 브라우저의 Actions 에서 GUI 로 간편하게 배포할 수 있다.

gh workflow run cd.yml
스크립트로도 배포 트리거를 실행할 수 있다.
공식문서에는 기재되어있는 inputs 은 실행 시점에 선택하거나 변경할 옵션이 없고, tags 은 테스트할 시나리오가 없어서, environment 는 단일 production 배포 환경을 사용하기 때문에 필요없는 옵션이다.
다만 inputs 옵션을 사용해서 배포의 롤백 기능을 극대화 할 수 있다고 한다.
여기에서 cd.yml 워크플로우를 실행할 수 있는 트리거를 사용하는 것!
그리고 배포 이후, 해당 커밋에 `v* 버전`을 태그와 릴리즈노트를 자동화하여 부여하고, 기록한다.
👍 최종 배포 아키텍처 시나리오


최종적으로 수립된 배포 파이프라인은 CI(지속적 통합)와 CD(지속적 배포)의 역할을 명확히 분리하여, 코드 통합은 자동화하되 실제 배포는 개발자의 통제하에 두는 것을 목표로 했다.
- 개발 통합, 코드품질 검사 (CI 자동 실행)
- develop 브랜치로 코드를 push하거나 Pull Request를 merge
- 해당 이벤트를 감지한 ci.yml 워크플로우가 자동으로 실행
- PR : ci.yml은 코드 품질 검사 `Lint` `Prettier` 의존성 설치 `npm ci` 프로젝트 빌드 순서로 작업
- Push : PR 시에 작업했던 코드품질검사, 의존성 설치, 프로젝트 빌드를 작업한다. 그 결과물인 `아티팩트`을 고유한 커밋 해시와 함께 저장하며 작업을 종료한다. 이 단계에서는 배포가 실행되지 않았다.
- 배포 결정과 수동 트리거 실행 (CD 수동 실행)
- 팀의 결정에 따라 배포가 필요한 시점에 CD 를 진행한다. 코드가 안정화 되거나, 기능 업데이트가 필요한 경우에 해당한다.
- 담당자는 GitHub 저장소의 Actions 탭으로 이동
- `Manual Release and Deploy` 워크플로우를 찾아 `Run workflow` 버튼을 클릭하여 수동으로 실행한다.
- 수동 트리거는 cd.yml 워크플로우를 develop 브랜치의 가장 최신 커밋을 기준으로 실행시킨다.
- 배포 및 릴리즈 자동화 (CD 작업 수행)
- cd.yml은 먼저 develop 브랜치의 최신 커밋 해시를 기준으로, CI 단계에서 생성된 빌드 아티팩트를 다운로드한다.
- 배포 플로우 : 다운로드한 아티팩트를 AWS S3에 배포하고 CloudFront 캐시를 무효화한다.
- 릴리즈 자동화 플로우 :
- 배포가 성공적으로 완료된 후, 기존의 마지막 태그를 조회하여 다음 패치 버전을 자동으로 계산한다.
(ex. v1.1.0 → v1.1.1) - 계산된 새 버전으로 Git 태그를 생성하고, 해당 버전의 변경 내역을 담은 릴리즈 노트를 GitHub에 자동으로 발행한다.
- 배포가 성공적으로 완료된 후, 기존의 마지막 태그를 조회하여 다음 패치 버전을 자동으로 계산한다.
요약
- CI (Pull Request 시)
- 트리거: develop 브랜치로의 PR 생성/업데이트
- 수행 작업: 코드 검증 → 빌드
- 결과: PR의 통합 안정성 사전 검증.
- CI (Merge 시)
- 트리거: develop 브랜치로의 Push(Merge)
- 수행 작업: 코드 검증 → 빌드 → 아티팩트 저장
- 결과: develop 브랜치의 무결성 최종 확인 및 배포용 빌드 결과물 준비.
- CD (수동 실행 시)
- 트리거: 개발자의 수동 실행 (버튼 클릭)
- 수행 작업: 최신 아티팩트 다운로드 → 배포 → 버전 태그 및 릴리즈 노트 생성
- 결과: 프로덕션 환경에 최신 버전이 배포되고, 버전 이력이 기록됨.
🤗 느낀점 & 기대효과
단순히 push 이벤트를 기반으로 동작하는 초기 파이프라인에서 시작하여, 우리 Kampus 팀의 배포 전략과 규칙을 코드로 녹여내는 과정을 거쳤다.
이 과정에서 `좋은 CI/CD`란 ❌무조건적인 자동화❌가 아니라, ⭕️팀의 작업 방식에 맞춰 필요한 제어권을 갖는 것⭕️임을 깨달았다.
파이프라인을 설계하는 것은 우리의 개발 및 배포 규칙을 명확히 정의하는 과정과 같았다.
최종적으로 도입된 아키텍처를 통해 다음과 같은 실질적인 효과를 기대한다.
- 비용 절감: 모든 머지(Merge)마다 발생했던 배포 과정을 없애고, 필요할 때만 실행함으로써 S3 및 CloudFront 사용 비용을 최소화
- 배포 안정성 확보: 오직 담당자의 명시적인 실행에 의해서만 배포가 진행되므로, 개발 중인 기능이나 불안정한 코드가 프로덕션 환경에 배포될 위험이 사라졌다.
- 개발 생산성 향상: 개발자들은 프로덕션 배포에 대한 부담 없이 develop 브랜치에 자유롭게 코드를 통합할 수 있게 되어, 개발 속도와 심리적 안정감을 높였다.
- 명확한 이력 관리: 모든 배포는 버전 태그와 릴리즈 노트 생성을 동반하므로, 언제 어떤 내용이 배포되었는지 누구나 명확하게 추적할 수 있다.
작업한 PR
[CHORE] git hooks 자동화, build 전에 Prettier와 ESLint 검사 by chae-dahee · Pull Request #194 · IT-Cotato/10th-Kampus-
개요 Resolves: #192 discussions : #184 PR 유형 어떤 변경 사항이 있나요? 새로운 기능 추가 빌드 부분 혹은 패키지 매니저 수정 작업 내용 커밋 add 된 파일만 검사합니다 (lint-staged 역할) 커밋을 실행했을
github.com
Vercel 무료 배포에서도 develop 가능한 작업이어서 함께 소개하면 좋을듯 합니다
😈 Vercel 무료 자동 배포, Github Action으로 CICD 구축
Vercel 무료 배포firebase로 로그인, 이메일전송 등의 서비스를 구축하고 있다. 미리 배포한 후 연동하려고 하는데 멘토님께서 firebase 배포가 아닌 vercel 배포를 추천하셨다.Git Organization 에서 FE, BE 레
datdaradanadat.tistory.com