일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- GitHub Pages
- 무선랜카드 교체
- webpack
- javascript
- AX210
- web component
- browserslist
- 우테코
- typescript
- react-dom
- Prometheus
- 유한 상태 머신
- react
- live share
- Grafana
- custom element
- Shadow DOM
- CSS
- HTML
- docker-compose
- RTL8852BE
- 우아한테크코스 레벨3
- 데모데이
- Docker
- scroll-snap
- github Actions
- swiper
- 터치 스와이프
- 우아한테크코스
- fastify
- Today
- Total
IT일상
GitHub Actions: CRA(Create React App) 빌드 + GitHub Pages 배포 자동화하기 본문
리뉴얼 된 블로그로 보기: https://solo5star.dev/posts/36/
GitHub Actions
GitHub에서 제공하는 CI/CD 도구입니다. CI/CD는 간단하게 말하자면 빌드, 테스트, 배포를 자동화하는 것을 뜻합니다.
이 글을 통해 하고자 하는 것은 다음과 같습니다.
* 커밋을 GitHub에 push할 때 마다 자동으로 빌드
* 빌드된 결과를 GitHub Pages로 자동 배포
이걸 한 번 쯤은 보신 적 있지 않습니까?
어떤 레포지토리에서는 커밋 아래에 보면 ✔체크 표시(혹은 ❌실패 표시)가 나타납니다. GitHub Actions 실행 결과를 표시하는 것인데요,
이 글에서 GitHub Actions 설정을 마치면 동일한 표시를 확인할 수 있을 것입니다.
GitHub Actions workflow 추가하기
하고자 하는 작업(배포, 테스트) 단위를 workflow라고 합니다. workflow에서는 세부적으로 또 여러 개의 job이 있습니다.
가장 먼저, workflow를 추가해봅시다.
.github/workflows 폴더를 만들고, deploy.yml 파일을 만들어주세요. yml파일의 이름은 임의로 정해도 좋습니다.
workflow 이름과 실행 조건 설정
deploy.yml 파일을 열고 workflow 설정을 진행하겠습니다.
name: Deploy
on:
push:
branches: ['step1']
workflow_dispatch:
name: 에는 workflow의 이름이 됩니다.
on: 은 workflow가 실행될 조건입니다. 위의 예시에선 step1 이라는 브랜치에 push가 될 때 마다 실행되도록 설정되어 있습니다.
workflow_dispatch: 는 workflow를 수동으로도 실행이 가능하게끔 해주는 옵션입니다.
workflow jobs 구성하기
jobs:
build-prepare-1:
name: Build Prepare 1
build-prepare-2:
name: Build Prepare 2
deploy:
name: Deploy
needs: [build-prepare-1, build-prepare-2]
하나의 workflow는 여러 개의 job으로 구성되어 있습니다. 기본적으로 병렬로 수행되지만 needs를 추가하면 특정 job이 끝난 후에 수행하도록 할 수도 있습니다.
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: write
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: true
복잡한 workflow는 아니기 때문에, job을 하나만 추가하겠습니다.
runs-on: 은 실행할 환경을 설정합니다. 우분투, 윈도우 서버, macOS가 있습니다. 어떤 환경을 지원하는지는 아래 링크에 들어가시면 자세히 나와있습니다.
permissions: 는 workflow에 권한을 추가합니다. peaceiris/actions-gh-pages 에서 요구하는 설정이기 때문에, 적어주도록 합시다.
concurrency: 는 동시성과 관련한 옵션입니다. group: 은 키 값이 되며, 동시에 한 번만 실행되도록 해줍니다. 위의 예시에선 deploy.yml workflow가 동시에 한 번만 실행되도록 합니다.
cancel-in-progress: 는 똑같은 group에서 이전에 실행중인 작업이 있을 때 취소할 지 여부를 설정합니다. 빌드는 최신을 기준으로만 진행하면 되기에 취소하도록 설정하였습니다.
위의 옵션과 관련하여 참고할 만한 문서 링크를 첨부합니다.
* runs-on에서 사용 가능한 환경: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idruns-on
* concurrency에 대한 공식 문서: https://docs.github.com/en/actions/using-jobs/using-concurrency
steps 구성하기
하나의 job은 여러 개의 step으로 구성되며, 순차적으로 실행됩니다.
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: write
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: true
steps:
# 레포지토리의 소스 코드를 사용하는 step입니다. 이게 없으면 빈 폴더가 됩니다.
- name: Use repository source
uses: actions/checkout@v3
# node.js 런타임을 사용합니다.
- name: Use node.js
uses: actions/setup-node@v3
with:
node-version: 18 # 프로젝트에서 사용하는 node.js 버전을 사용하세요.
# node_modules 폴더를 캐싱합니다.
# 이게 없으면 workflow를 실행할 때 마다 node_modules를 다시 생성합니다.
- name: Cache node_modules
id: cache
uses: actions/cache@v3
with:
# 캐싱할 폴더를 지정합니다.
path: '**/node_modules'
# package-lock.json 파일의 변경이 발생했을 경우 새로 캐싱될 수 있도록 해줍니다.
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
# cache hit이 발생하지 않았을 경우, restore-keys 에 있는 것을 꺼냅니다.
# 단, npm ci 명령은 실행됩니다. 기존의 node_modules 캐시를 기반으로
# 추가된 패키지만 설치할테니, 아예 처음부터 node_modules 폴더를 생성하는 것보다
# 시간이 적게 걸릴 겁니다.
restore-keys: |
${{ runner.os }}-node-
- name: Install dependencies
run: npm ci
# cache hit이 발생한 경우 (즉 package-lock.json이 변경되지 않은 경우)
# npm ci 실행은 skip 됩니다.
if: steps.cache.outputs.cache-hit != 'true'
# $GITHUB_REPOSITORY 환경 변수는 solo5star/react-payments 형태의
# owner과 repository 값입니다. 이를 .env에 PUBLIC_URL=/react-payments/ 형태로
# 저장하기 위한 명령입니다.
- name: Set PUBLIC_URL
run: |
PUBLIC_URL=$(echo $GITHUB_REPOSITORY | sed -r 's/^.+\/(.+)$/\/\1\//')
echo PUBLIC_URL=$PUBLIC_URL > .env
# 빌드를 수행합니다.
# react-router-dom의 BrowserRouter를 지원하기 위해
# index.html 을 복사하여 404.html에서도 사용하도록 합니다.
- name: Build
run: |
npm run build
cp ./build/index.html ./build/404.html
# 빌드된 파일들(./build)을 gh-pages 브랜치로 배포합니다.
- uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./build
코드가 길어져서 주석으로 설명을 적어두었으니 참고해주세요.
전체 코드(.github/workflows/deploy.yml)
name: Deploy
on:
push:
branches: ['step1']
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: write
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: true
steps:
- name: Use repository source
uses: actions/checkout@v3
- name: Use node.js
uses: actions/setup-node@v3
with:
node-version: 18
- name: Cache node_modules
id: cache
uses: actions/cache@v3
with:
path: '**/node_modules'
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install dependencies
run: npm ci
if: steps.cache.outputs.cache-hit != 'true'
- name: Set PUBLIC_URL
run: |
PUBLIC_URL=$(echo $GITHUB_REPOSITORY | sed -r 's/^.+\/(.+)$/\/\1\//')
echo PUBLIC_URL=$PUBLIC_URL > .env
- name: Build
run: |
npm run build
cp ./build/index.html ./build/404.html
- name: Deploy to gh-pages branch
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./build
workflow 실행 확인
.github/workflows/deploy.yml 파일을 생성하고 커밋하여 푸시하면 커밋 옆에 아이콘이 생길 겁니다.
workflow가 성공적으로 인식되고 실행중이라는 뜻입니다!
아이콘을 클릭하고 Details를 누르면 workflow 실행을 자세히 볼 수 있습니다.
deploy.yml 에서 정의한 대로 workflow가 잘 실행되는 모습을 볼 수 있습니다!
gh-pages 라는 브랜치가 생성되었을 겁니다. 이 브랜치가 GitHub Pages 배포 브랜치로 사용되도록 설정을 진행해주면 됩니다.
GitHub Pages 배포 브랜치 설정
gh-pages 브랜치에 있는 파일들이 GitHub Pages에서 배포되도록 설정할 겁니다.
Settings > Pages 에 들어가서 위와 같이 설정해주세요.
배포 확인
https://<본인 아이디>.github.io/<레포지토리 이름> 주소로 들어가면 배포를 확인할 수 있습니다.
잘 모르겠다면 Environments > github-pages 를 클릭한 뒤 View Deployment를 클릭하세요.
React 앱이 잘 동작하는지도 확인해보세요!
심화: react-router-dom의 BrowserRouter
이미 위의 글에서 진행하며 코드에 포함했지만, 추가적으로 다루어보겠습니다.
BrowserRouter는 History API를 사용하여 라우팅을 구현합니다. SPA(Single Page App)이지만 URL이 실제 페이지가 이동한 것처럼 보이는 장점이 있는데, 문제는 새로고침을 했을 때 입니다.
1: https://solo5star.github.io/react-payments/
2: https://solo5star.github.io/react-payments/register
/register 에서 새로고침을 하면, /register 파일이 존재하지 않기 때문에 404 Not Found 페이지가 나타날 겁니다.
GitHub는 404.html 파일을 추가하여 404 페이지를 커스텀할 수 있는 방법을 제공하는데, 이를 사용하면 위의 문제를 해결할 수 있습니다.
index.html 파일을 그대로 404.html에서 사용하면 됩니다. 그러면 /register로 접속해도, /users/100 으로 접속해도 index.html이 사용되면서 문제가 해결됩니다.
이 방식의 한계점은, 페이지는 정상적으로 뜨지만 응답 코드는 여전히 404로 나타난다는 점입니다.
맺음말
SPA 환경 + History API 라우팅을 하는 프로젝트의 GitHub Actions 자동 빌드 배포를 해보았는데요. 404.html을 사용한 방법으로, 사실 우회적으로 설정한 것이긴 합니다. Hash를 사용하여 라우팅하는 HashRouter를 고려해보아도 좋을 것 같습니다.
'프론트엔드' 카테고리의 다른 글
React FC vs SFC vs VFC (0) | 2023.04.23 |
---|---|
GitHub Actions: storybook 배포하기 (4) | 2023.04.23 |
CSS로 별점 기능 만들기 (2) | 2023.03.27 |
타입스크립트 Discriminated Unions (0) | 2023.03.27 |
타입스크립트 템플릿 리터럴 타입 (0) | 2023.03.27 |