사이드프로젝트 시작에 앞서 개발환경 세팅하면서 배포를 먼저 시도했는데 문제가 발생했다. 오가니제이션에 있는 레포지토리는 프로 요금제로 변경해야 배포할 수 있다. 이전에 오때 사이드 프로젝트를 진행할 당시에는 조직 계정도 무료로 배포할 수 있었으나 최근에 정책이 변경된 듯 하다.. 검색해보니 다들 우회하여 무료로 배포하고 있었다. 우회하는 플로우는 대충 아래와 같다.
- 오가니제이션에 레포지토리를 생성한다.
- 개인 계정에 해당 레포지토리를 fork한다.
- vercel에는 개인 계정에 레포지토리를 연동하여 배포한다.
- 오가니제이션에 있는 레포지토리에서 Github Actions을 통해 프록시를 사용해 배포한다.
위 순서에서 마지막이 핵심이다.
즉, 깃헙액션에서 제공하는 runner(가상머신)을 이용해 직접 vercel에 소스를 배포하지 않고, 대신 이 가상머신을 프록시로 사용하여 오가니제이션 레포지토리의 코드를 개인 계정의 레포지토리로 복사한 후, vercel이 개인 레포지토리에서 배포할 수 있도록 만드는 것이다.
준비하기
- 프로젝트가 있는 오가니제이션 레포지토리
- 위 레포를 fork한 개인 레포지토리
- (없다면) 개인 토큰 생성하기. 권한은 repo만 줘도 된다.
Organization Repository에서
먼저 해당 레포지토리 설정에 들어가서 개인 계정의 토큰과 이메일을 시크릿 변수로 설정해야 한다.
Settings > Secrets and variables > Actions > New repository secret을 눌러 변수를 생성해준다.
해당 변수들은 yml파일에서 사용해줄 것이다.
EMAIL은 개인 이메일을 작성하고 MY_TOKEN에는 깃허브 계정 토큰을 넣었다.
build파일 생성
깃헙 액션을 실행하기 전에 프로젝트의 루트 경로에 build.sh파일을 생성하고 아래와 같이 작성한다.
#!/bin/sh
cd ../
mkdir output
cp -R ./your-repository-name/* ./output
cp -R ./output ./your-repository-name/
sh파일은 shell script파일로 쉘에게 어떤 명령을 할지 알려준다. 위 코드를 간략하게 이해하고 넘어가보자.
- 먼저 상위 디렉토리로 이동한다.
- mkdir은 make directory의 약어로 output폴더를 생성한다는 것이다. 이로써 해당 레포가 있는 폴더와 output은 같은 레벨에 존재하게 된다.
- cp -R명령어는 copy의 약어로 복사를 하는데, -r옵션과 /*을 통해 해당 디렉토리 하위에 있는 모든 파일을 포함해서 복사한다. 복사된 파일들은 output폴더에 들어가게 된다.
- output폴더에 있는 것을 다시 레포에 복사한다. 만약 output에서 특정 파일을 변경하거나 가공하는 작업이 있다면, 수정 후에 다시 레포에 복사를 해야 하는 작업이 필요하다.
아직까지는 왜 마지막 명령어가 필요한 지 모르겠다.
cp -r [복사 대상 디렉터리] [복사될 디렉터리]
Github Actions
그 다음 github actions를 설정해보자.
레포지토리 상단에 Actions탭에 들어가 New workflow를 클릭한다.
빌드 환경에 맞춰 여러 템플릿이 있지만 우리는 직접 작성할 것이기 때문에 파란 글씨로 쓰인 set up a workflow yourself를 클릭해 아래 코드를 복사해 파일을 생성한다.
name: git push into another repo to deploy to vercel
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
container: pandoc/latex
steps:
- uses: actions/checkout@v2
- name: Install mustache (to update the date)
run: apk add ruby && gem install mustache
- name: creates output
run: sh ./build.sh
- name: Pushes to another repository
id: push_directory
uses: cpina/github-action-push-to-another-repository@main
env:
API_TOKEN_GITHUB: ${{ secrets.MY_TOKEN }}
with:
source-directory: 'output'
destination-github-username: [your-team-official-github-name]
destination-repository-name: [your-team-official-github-repository-name]
user-email: ${{ secrets.EMAIL }}
commit-message: ${{ github.event.commits[0].message }}
target-branch: main
- name: Test get variable exported by push-to-another-repository
run: echo $DESTINATION_CLONED_DIRECTORY
상단에 설정한 name으로 깃헙액션의 워크플로우가 생성된다.
[] 표시가 된 부분은 본인의 github name과 레포명으로 변경해주면 된다.
위 과정도 간단하게 이해해보자.
- on: push: branches: [main] - main브랜치에 푸쉬 이벤트가 발생할 때, 이 워크플로우가 실행된다
- jobs: build: - build라는 이름의 작업(job)을 정의한다. 이 작업은 우분투 리눅스 환경에서 실행되며, pandoc/latex컨테이너에서 실행된다.
- step - 이 작업이 실행될 때 단계별로 수행되는 작업들이 정의된다.
- actions/checkout@v2 - 현재 저장소의 소스를 깃헙액션 실행환경으로 가져온다. 즉, 코드를 클론해서 가져오는 역할이다.
- Install mustache - apk add 명령어를 통해 루비를 설치하고, 루비 젬을 통해 mustache도구를 설치한다.
- create output - 위에서 만든 build.sh파일을 실행하여 output폴더를 생성한다.
- Pushes to another repository
- cpina/github-action-push-to-another-repository는 깃헙액션에서 사용되는 액션으로, 두 개의 저장소를 연결해 한 저장소에서 빌드된 결과물을 자동으로 다른 저장소에 푸쉬하는 기능을 제공한다.
- 따라서 여기서 깃 토큰이 필요하다
- source-directory에는 푸쉬할 파일들이 있는 곳이다.
- destination-github-username, destination-repository-name은 결과물을 푸쉬할 대상의 소유자와 저장소명이다.
- target-branch는 대상 저장소에 푸쉬할 브랜치다.
- 이 단계를 요약하자면, 저장소의 output디렉토리에서 결과물을 만들어 your-github/your-repository의 main 브랜치로 커밋하고 푸쉬한다.
- Test get variable exported... - 설정된 변수들을 테스트하기 위한 것이다. 이를 통해 파일이 푸쉬된 후 대상 저장소의 클론된 디렉토리 경로가 제대로 설정되었는지 확인할 수 있다. 빌드 로그에서 해당 단계를 클릭하면 확인 가능하다.
작성하다가 오타를 내면 빌드 에러를 만날 수 있으므로(실제로 username작성하는 곳에 오타가 났어서 한참을 헤멨다..) 오타가 났다면 꼼꼼하게 확인해보자.
vercel에서
오가니제이션 레포를 fork한 개인 레포지토리를 vercel에서 연동해주는 작업이 필요하다. 이 작업은 간단하다.
- vercel에 로그인한다.
- 우측에 New > Project를 선택한다.
- 오가니제이션 및 본인 계정이 나올텐데, 여기서 오가니제이션이 아닌 본인 계정을 선택해 fork한 레포지토리를 Import하면 끝이다
작업하기
오가니제이션 레포지토리에서 작업 후에 main브랜치로 푸쉬하면 내가 fork한 레포지토리에도 자동으로 푸쉬가 되면서 vercel이 빌드 및 배포를 진행한다.
직접 배포하는 것이 아닌 vercel을 우회하는 방법을 통해 처음으로 Github Actions와 sh파일, yml파일을 다뤄봤는데 나름 오류?도 나면서 많이 배웠던 계기가 됐다. 특히 리눅스 명령어는 정처기 덕분인지 익숙한 명령어들이 많아서 이해하기 힘든 부분은 없었다.
파일을 하나씩 읽어나가며, 직접 배포하는게 생각보다 어렵지 않을 수도 있겠다 생각했다.
현재 진행하는 프로젝트는 해커톤 형태라 시간이 없지만 끝난 후에 가능하다면 vercel이 아닌 aws를 통해 직접 배포를 해보자 !
Reference
https://vanilla-van-6e4.notion.site/vercel-47312c7c2a9c492dbdabc40c47489cfa
'개발 > 프론트엔드' 카테고리의 다른 글
[JavaScript] 코어 자바스크립트 week1 - 데이터 타입 (3) | 2024.10.22 |
---|---|
[NextJS] GIF는 Image컴포넌트의 최적화가 지원되지 않는다?! (feat. Cloudinary) (0) | 2024.10.17 |
[NextJS] NextJS와 TailwindCSS로 폰트 설정하기 (0) | 2024.09.18 |
[Typescript] 타입스크립트는 왜 쓰는걸까? (4) | 2024.09.05 |
[React] 리액트로 스톱워치 Chrome Extension 만들기 (0) | 2024.08.29 |