서론

블로그를 운영하다 보면 글을 쓰는 것 외에도 반복적인 작업들이 생깁니다. README 업데이트, 추천 글 관리, 코드 포맷팅 등 손이 가는 일들이 쌓이면 글쓰기에 집중하기 어려워집니다. 이번에 Git Hooks와 GitHub Actions를 활용해 이런 작업들을 자동화하면서 겪었던 과정을 정리해보려 합니다.


자동화 이전의 문제점

수동 작업의 반복

원격 저장소 충돌

품질 관리 부재


구축한 자동화 시스템

전체 흐름

로컬 커밋
    ↓
pre-commit: 코드 품질 검사
    ↓
post-commit: 새 포스트 AI 분석
    ↓
git push
    ↓
pre-push: 원격 동기화 확인
    ↓
GitHub Actions: README 자동 업데이트

네 단계의 자동화를 통해 커밋부터 배포까지 일관된 품질을 유지할 수 있게 되었습니다.


pre-commit: 커밋 전 품질 검사

pre-commit 프레임워크를 도입해 커밋 전에 자동으로 검사를 수행합니다.

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v3.4.0
    hooks:
      - id: check-yaml
      - id: end-of-file-fixer
      - id: check-xml
      - id: detect-private-key
      - id: fix-byte-order-marker

  - repo: https://github.com/pre-commit/mirrors-prettier
    rev: v3.1.0
    hooks:
      - id: prettier
        files: 'docs/_posts/.*\.md$'
        args: ['--prose-wrap', 'always', '--print-width', '80']

각 hook의 역할은 다음과 같습니다.

기존에 작성된 170개 포스트는 .prettierignore에 등록해 불필요한 변경을 방지했습니다.


post-commit: AI 기반 추천 글 분석

새 포스트를 커밋하면 자동으로 Claude CLI를 호출해 추천 글 적합성을 분석합니다.

# .git/hooks/post-commit
NEW_POSTS=$(git diff-tree --no-commit-id --name-only -r HEAD \
    | grep -E '^docs/_posts/.*\.md$')

if [ -n "$NEW_POSTS" ]; then
    bash scripts/check_recommended.sh "$NEW_POSTS"
fi

분석 스크립트는 다음 과정을 거칩니다.

  1. 기존 추천 포스트 정보 추출 (Ruby 스크립트)
  2. 프롬프트 템플릿에 새 포스트 정보 주입
  3. Claude CLI로 분석 실행
  4. 추천 여부, 점수, 평가 이유 출력
## 평가 기준
- 독창성: 새로운 시각이나 접근법을 제시하는가
- 실용성: 독자에게 실질적인 도움을 주는가
- 구조화: 논리적으로 잘 정리되어 있는가
- 공감성: 독자가 공감할 수 있는 내용인가
- 성찰: 개인적인 통찰이 담겨 있는가
- 카테고리 균형: 기존 추천 글과의 다양성

이를 통해 추천 글 선정에 일관된 기준을 적용할 수 있게 되었습니다.


pre-push: 원격 충돌 방지

GitHub Actions가 자동으로 커밋을 생성하기 때문에, push 전에 원격 저장소와 동기화가 필요합니다.

# .githooks/pre-push
BRANCH=$(git rev-parse --abbrev-ref HEAD)

if [ "$BRANCH" = "main" ]; then
    git fetch origin $BRANCH

    LOCAL=$(git rev-parse HEAD)
    REMOTE=$(git rev-parse origin/$BRANCH)
    BASE=$(git merge-base HEAD origin/$BRANCH)

    if [ "$LOCAL" = "$REMOTE" ]; then
        echo "이미 동기화됨"
    elif [ "$REMOTE" = "$BASE" ]; then
        echo "로컬이 앞서 있음, push 진행"
    else
        echo "원격에 새 커밋 있음, rebase 실행"
        git pull --rebase origin $BRANCH
    fi
fi

핵심은 git merge-base를 활용해 로컬과 원격의 관계를 파악하는 것입니다. 원격에 새 커밋이 있으면 자동으로 rebase를 수행해 충돌을 방지합니다.

.githooks/ 디렉토리를 사용하면 hook을 버전 관리할 수 있어 다른 환경에서도 동일한 설정을 적용할 수 있습니다.

git config core.hooksPath .githooks

GitHub Actions: README 자동 업데이트

두 개의 워크플로우가 push 시 자동 실행됩니다.

최신 글 목록 업데이트

# .github/workflows/bog-post-workflow.yml
- name: Update blog posts
  uses: gautamkrishnar/blog-post-workflow@v1
  with:
    feed_list: "https://kaestro.github.io/feed.xml"

feed.xml에서 최신 포스트를 가져와 README의 지정된 영역을 업데이트합니다.

추천 글 목록 업데이트

# .github/workflows/count_recommended.yml
- name: Count recommended posts
  run: |
    ruby -ryaml -e '
      posts = Dir.glob("docs/_posts/**/*.md")
        .map { |f| [f, YAML.load_file(f, permitted_classes: [Date])] }
        .select { |_, meta| meta["recommended"] == true }
        .sort_by { |_, meta| -meta["date"].to_time.to_i }
        .first(5)
    '

recommended: true가 설정된 포스트를 스캔해 상위 5개를 README에 반영합니다.


결과

이번 자동화 구축으로 다음과 같은 효과가 있었습니다.

특히 pre-push hook 덕분에 GitHub Actions의 자동 커밋으로 인한 충돌을 신경 쓰지 않아도 되어 편해졌습니다. 글쓰기에만 집중할 수 있는 환경을 만드는 것이 목표였는데, 어느 정도 달성한 것 같습니다.


2026-02-01