20년치 콘텐츠, 3개 저장소를 모노레포로 통합!

by DD
2시간 전
조회수 0

20년 이상의 블로그 게시물(2,630개)과 발표 자료(106개)를 개인 소유의 Astro 사이트로 통합하며 데이터 영속성(Data Durability) 확보

URL 보존 원칙을 최우선으로 하여 기존 링크 호환성을 유지하고, 레거시 아카이브(Legacy Archive)의 무결성을 보장함

dev.to 초안 동기화 도구와 발표 사이트 자료를 모노레포(Monorepo)로 통합하여 관리 효율성을 높이고 버전 관리 히스토리(Version Control History)를 보존

URL 보존을 위한 Astro 설정

개인 웹사이트 마이그레이션의 핵심 원칙은 기존 URL 구조의 완벽한 보존이었음. 이를 위해 Astro 5 설정에서 `trailingSlash: 'always'` 옵션을 적용하고, Hugo에서 사용하던 디렉토리 구조를 그대로 재현하여 이전 링크와의 호환성을 확보함. 이는 2009년 블로그 롤이나 2014년 컨퍼런스 사이트에서 걸린 인바운드 링크(Inbound Link)의 깨짐 현상 방지를 목표로 함. 결과적으로 사용자는 프레임워크 변경에도 불구하고 기존 링크를 통해 문제없이 콘텐츠에 접근할 수 있게 됨.

콘텐츠 통합을 위한 스키마 설계

개인 블로그의 `/writing/` 섹션은 다양한 출처의 콘텐츠를 통합하기 위해 유연한 스키마 설계를 채택함. Astro 콘텐츠 컬렉션은 자체 작성된 글과 외부 링크(Tiger Data 기고문)를 구분하기 위해 `content.config.ts`의 스키마와 `field-guide.ts`의 인터페이스를 활용함. `writing.ts`에서는 두 형식을 `GuideItem`으로 정규화하여 템플릿에서 동일하게 렌더링되도록 함. 외부 링크에는 'tigerdata.com ↗' 배지를 추가하여 출처를 명확히 표시하고, 네이티브 항목과 외부 링크를 날짜 순서가 아닌 파트별로 구분하여 제공함.

발표 자료 관리의 자산 소유권 강화

기존 발표 사이트(speaking.mattstratton.com)는 Notist CDN에 의존하여 비디오 임베드 깨짐 및 계정 만료 시 자료 유실 위험이 있었음. 이를 해결하기 위해 모든 슬라이드 덱(PDF)과 비디오 임베드 정보를 로컬 저장소로 이전하고, 자산 소유권(Asset Ownership)과 영속성(Durability)을 확보함. 특히 PDF 최적화 및 웹P(WebP) 변환 파이프라인은 로컬에서만 실행하여 정적 호스팅 환경의 제약을 극복하고, 비디오는 클릭 시 로드되는 경량 임베드 페이서드로 대체하여 서드파티 의존성을 제거함.

클라이언트 측 검색을 위한 데이터 구조

발표 사이트의 텍스트 검색 기능은 YouTube 자동 생성 자막을 활용하여 구현됨. `yt-dlp`로 추출한 원본 자막은 Claude Code 스킬을 통해 구두점, 대문자, 고유명사 수정 및 불필요한 구어체 제거 등 정제 과정을 거침. 검색은 서버 없이 클라이언트 측에서 두 개의 JSON 페이로드(`search-index.json`, `deep-index.json`)를 기반으로 동작함. `Fuse.js` 라이브러리를 사용하여 퍼지 매칭(Fuzzy Matching) 기반의 검색 인덱스를 구축하고, 사용자가 입력하는 쿼리에 따라 관련 토크를 정확하게 찾아줌.

모노레포 전환 시 CI/CD 설정의 함정

세 개의 저장소를 모노레포로 통합하는 과정에서 GitHub Actions와 Netlify의 CI/CD 설정 관련 문제에 직면함. GitHub Actions 워크플로우는 저장소 루트의 `.github/workflows/`에서만 인식되므로 하위 디렉토리의 워크플로우는 자동으로 실행되지 않음. Netlify는 기본적으로 서브디렉토리별 빌드 스코핑을 지원하지 않아, `netlify.toml`에 명시적인 변경 사항 감지 로직을 추가해야 했음. 또한, Astro의 `astro check` 명령어가 서브프로젝트 경계를 인식하지 못해 잘못된 타입 에러가 다수 발생하는 문제도 경험함.

dev.to 콘텐츠 동기화 전략

dev.to 초안과 Git 저장소 간의 동기화는 '소유권 이전(Ownership Transfer)' 모델을 기반으로 함. 초기 초안 상태에서는 dev.to가 소유권을 가지며 Git은 이를 무시함. 사용자가 PR을 통해 Git으로 가져온 후에는 `id` 필드를 추가하여 Git 소유권으로 영구 전환됨. 이 방식은 양방향 동기화 시 발생하는 무한 팬텀 diff 루프를 방지함. 게시물 발행 시에는 원자적 커밋(Atomic Commit)으로 mattstratton.com의 `/writing/` 컬렉션 생성과 dev.to의 `canonical_url` 업데이트를 동시에 처리하여 일관성을 유지함.

I Contain Multitudes (and Also Three Git Repos)