깃허브 액션으로 커밋 로그를 블로그에 띄우기: Nuxt와 Vercel 활용법

소개: 커밋 로그를 UI에 표시하는 이유

깃허브 커밋 히스토리는 프로젝트 진행 상황을 보여주고, 작업 흐름을 공유하는 중요한 자료입니다. 블로그에 커밋 로그를 실시간으로 표시하고 싶어 깃허브 액션과 Nuxt, Vercel을 활용해 구현했습니다.

1단계: 깃허브 액션으로 커밋 데이터 수집

깃허브 액션을 사용해 매일 자정(UTC 00:00)에 최신 20개 커밋을 JSON 파일로 저장하고 자동으로 푸시합니다.

.github/workflows/update-commits.yml

name: Update Commits Log
on:
  schedule:
    - cron: "0 0 * * *"
  workflow_dispatch:
permissions:
  contents: write
jobs:
  update-commits:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - run: |
          curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
            "https://api.github.com/repos/${{ github.repository }}/commits?per_page=20" | \
          jq '[.[] | {message: .commit.message, date: .commit.author.date, sha: .sha, url: .html_url}]' > public/commits.json
      - run: |
          git config --global user.name "GitHub Action"
          git config --global user.email "action@github.com"
          git diff --quiet || (git add public/commits.json && git commit -m "Update commits log [skip ci]" && git push)

2단계: Nuxt로 UI 표시

정적 파일 방식

  • public/commits.json을 Nuxt에서 직접 불러옵니다.
  • server/api/commits.js를 사용한 API 방식은 Vercel 배포 시 ENOENT 오류 발생으로 제거했습니다.
  • useAsyncData를 활용해 프론트엔드에서 데이터를 가져옵니다.
<script setup>
const { data: commits } = useAsyncData("commits", () =>
  $fetch("/commits.json")
);
</script>

<template>
  <ul>
    <li v-for="commit in commits" :key="commit.sha">
      <a :href="commit.url" target="_blank">{{ commit.message }}</a> -
      {{ commit.date }}
    </li>
  </ul>
</template>

3단계: 캐싱 문제 해결

  • useAsyncData는 동일한 키의 데이터를 캐싱해 새로고침해도 갱신되지 않는 문제가 있었습니다.
  • 해결 방법: useAsyncData 호출 시 Math.random()을 활용해 동적으로 키를 변경하여 항상 새로운 데이터를 가져오도록 설정.
const { data: commits } = useAsyncData(`commits-${Math.random()}`, async () => {
  const response = await fetch("/commits.json");
  return response.json();
});

결론

깃허브 액션으로 자동화된 커밋 데이터 수집, Nuxt로 UI 구성, Vercel로 배포하는 과정을 정리했습니다. 초기 API 방식의 문제를 정적 파일 방식으로 해결하고, 캐싱 문제도 보완했습니다. 이를 통해 깃허브 커밋 로그를 블로그에 실시간으로 표시할 수 있습니다.