깃허브 페이지(GitHub Pages)는 리파지토리에서 정적 웹사이트를 호스팅할 수 있는 서비스입니다. 공개 리파지토리는 무료입니다.

단점이라고 하면, 한 리파지토리당 하나의 브랜치만 배포할 수 있는 건데, dev - prod 환경 각각 배포하려고 하면 다른 배포 서비스와 연결해야 합니다 (ex. Netlify, Vercel, ...)

깃허브 자원만 써서 PR을 포함한 여러 스테이지를 배포할 수 없을까? 찾아봤는데.. 어찌저찌 가능은 합니다.

 

How?

개념은 간단합니다.

한 리파지토리당 한 브랜치만 Github Pages로 배포할 수 있습니다

그렇다면 여러 페이지를 배포해야 한다면 리파지토리를 그만큼 만들면 되는 겁니다!

PR이 올라오면 리파지토리를 추가한 뒤 gh-pages 브랜치로 푸시하고, pr이 머지되거나 닫히면 리파지토리를 지우면 끝!

참 쉽죠?

 

따라하기

 

GitHub - vince-test-org/multiple-env-test: Deploy multiple environment on github pages

Deploy multiple environment on github pages. Contribute to vince-test-org/multiple-env-test development by creating an account on GitHub.

github.com

(참고: 결과물입니다)

 

먼저 personal access token을 만들어 줍니다

권한은 delete_repo와 org, repo, workflow를 넣어줍니다

그리고 organization을 하나 만들어줍니다 (pr 하나당 리파지토리 하나 찍어내야돼서.. 개인계정엔 비추)

 

name: Deploy React Application

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 16
          cache: 'yarn'

      - run: yarn install --frozen-lockfile
      - run: yarn build
        env:
          CI: false

      - name: deploy to gh-pages
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./build

(deploy-prod.yml)

적당히 리액트 프로젝트와 빌드용 액션을 만들었다고 칩시다.

 

name: Pull Request Build and Deploy

on:
  pull_request:
    branches:
      - main
    paths-ignore:
      - '.github/workflows/**'
      - '**.md'

env:
  PR_REPO_NAME: app-pr-${{ github.event.pull_request.node_id }}

jobs:
  create-page-host:
    runs-on: ubuntu-latest
    steps:
      - name: Create new repository for temporary deployment
        uses: mktcode/create-repository-action@v1
        with:
          name: ${{ env.PR_REPO_NAME }}
          org: ${{ github.repository_owner }}
          access-token: ${{ secrets.PAT }}

  pr-build-deploy:
    permissions:
      contents: write
    needs: create-page-host
    runs-on: ubuntu-latest
    environment:
      name: pr-staging
      url: https://${{ github.repository_owner }}.github.io/${{ env.PR_REPO_NAME }}

    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 16
          cache: 'yarn'

      - run: yarn install --frozen-lockfile
      - run: yarn build
        env:
          CI: false

      - name: deploy to gh-pages
        uses: peaceiris/actions-gh-pages@v3
        with:
          personal_token: ${{ secrets.PAT }}
          external_repository: ${{ github.repository_owner }}/${{ env.PR_REPO_NAME }}
          publish_dir: ./build

(deploy-pr.yml)

PR이 올라오면 리파지토리를 만들고, 해당 리파지토리의 gh-pages에 푸시해야 하는데 각각 위 액션들로 처리를 해줍니다 (mktcode/create-repository-action, peaceiris/action-gh-pages)

action-gh-pages로 다른 리파지토리에 푸시할 수 있다는건 이번에 새로 알게 됐네요

 

PR을 올리면 이렇게 리파지토리가 하나 생기면서 배포가 됩니다

 

name: Delete Pull Request Deployment
on:
  pull_request:
    branches: [ main ]
    types: [ closed ]
    paths-ignore:
      - '.github/workflows/**'
      - '**.md'

env:
  PR_REPO_NAME: app-pr-${{ github.event.pull_request.node_id }}

jobs:
  delete-page-host:
    runs-on: ubuntu-latest
    steps:
      - name: Delete repository for temporary deployment
        uses: mktcode/delete-repository-action@v1
        with:
          name: ${{ github.repository_owner }}/${{ env.PR_REPO_NAME }}
          access-token: ${{ secrets.PAT }}

(delete-pr-deploy.yml)

PR이 닫혔을 때 리파지토리 지우는 액션도 이렇게 추가해주시면 끝입니다

 

리파지토리 메인으로 가보면 이런식으로 여러 environment가 나오는 걸 확인할 수 있습니다.

 

만약 dev 스테이지가 필요하다 하면 dev용 리파지토리를 추가하고 deploy-pr.yml에서 리파지토리 만드는 job만 빼면 될 것 같네요

 

결론

여러모로 삽질을 많이 했습니다 ㅠ

가능은 하지만.. 그냥 외부 배포서비스 쓰는게 속편할 것 같습니다

pr 1개에 리파지토리 1개 추가되는게 은근 보기 안좋네요 ㅋㅋ

 

참고

- https://medium.com/geekculture/when-youre-working-on-a-static-site-and-github-pages-feels-like-the-perfect-hosting-solution-a41c37f4e326