이 문서 인프라에 대하여

발행: (2026년 1월 7일 오전 10:18 GMT+9)
7 min read
원문: Dev.to

Source: Dev.to

Source:

문서 구조

모든 문서는 GitHub 리포지토리의 ./documentation 디렉터리 안에 Markdown 파일로 저장됩니다. 이것이 유일한 진실의 원천입니다.

documentation/
├── index.md              # 진입점 / 개요
├── pitches.md            # 다양한 길이 요약
├── SRDD-part1-of-4.md    # 기사 시리즈
├── SRDD-part2-of-4.md
├── SRDD-part3-of-4.md
├── SRDD-part4-of-4.md
├── CONTRIBUTING.md       # 기여 가이드
├── about.md              # 이 파일
└── .sync-state.json      # Dev.to 동기화 상태 (자동 생성)

각 Markdown 파일은 메타데이터(제목, 설명 등)를 위한 YAML 프론트 매터와 표준 GitHub‑flavored Markdown을 사용합니다.

내부 링크 플레이스홀더

문서에서는 내부 링크를 위해 플레이스홀더 구문을 사용합니다:

See [Part 1]({{devto:SRDD-part1-of-4}}) for details.

{{devto:slug}} 패턴은 대상 플랫폼에 따라 다르게 변환됩니다.

플랫폼변환 방식
GitHub Pages{{devto:slug}} → ./slug.md
Dev.to{{devto:slug}} → 실제 Dev.to URL (예: https://dev.to/bbos/...)

이를 통해 문서들은 서로 다른 플랫폼에서 URL을 하드코딩하지 않고도 서로 연결할 수 있습니다.

게시 워크플로우

단일 워크플로우(.github/workflows/deploy-and-sync.yml)가 모든 게시 단계를 처리합니다.

# Transform devto placeholders for GitHub Pages
- name: Transform devto placeholders for GHP
  run: |
    find ./documentation -name "*.md" -exec sed -i -E \
      's/\{\{devto:([^}]+)\}\}/.\/\1.md/g' {} \;

# Build with Jekyll
- name: Build with Jekyll
  uses: actions/jekyll-build-pages@v1
  with:
    source: ./documentation
    destination: ./_site

파이프라인 개요

  1. 자산을 documentation 디렉터리로 복사합니다.
  2. {{devto:slug}} 자리표시자를 상대 .md 링크로 변환합니다.
  3. Jekyll을 사용해 사이트를 빌드합니다.
  4. GitHub Pages에 배포합니다.

GitHub Pages 배포가 완료된 후, 동기화 단계가 실행됩니다:

sync-to-devto:
  needs: deploy  # Run after deploy so canonical URLs are live
  steps:
    - name: Sync posts to Dev.to
      env:
        DEVTO_API_KEY: ${{ secrets.DEVTO_API_KEY }}
        SITE_URL: ${{ vars.SITE_URL }}

Sync Script (scripts/sync-to-devto/sync-to-devto.js)

스크립트는 두 단계 동기화를 수행합니다:

Pass 1 – URL 맵 구축

각 Markdown 파일에 대해:

  1. 프론트 매터와 본문을 파싱합니다.
  2. 정식 URL( GitHub Pages 를 가리키는)을 생성합니다.
  3. 콘텐츠를 변환합니다(이미지에 절대 URL 사용, 스타일 제거).
  4. API를 통해 Dev.to 기사 를 생성하거나 업데이트합니다.
  5. 반환된 Dev.to URL을 캡처합니다.

생성된 맵(예시):

{
  "index": "https://dev.to/bbos/srdd-is-the-best...-4k2n",
  "SRDD-part1-of-4": "https://dev.to/bbos/why-srdd-exists-2j8m"
}

Pass 2 – 플레이스홀더 해결

{{devto:slug}} 플레이스홀더가 포함된 문서를 다시 파싱하고, 맵에 있는 실제 Dev.to URL로 교체한 뒤 해당 기사들을 다시 업데이트합니다.

이를 통해 Dev.to의 동적 URL 생성에도 불구하고 모든 교차 참조가 올바르게 해결됩니다.

증분 동기화 및 상태 캐싱

변경된 게시물만 업로드되어 API 호출을 줄이고 파이프라인 속도를 높입니다.

  • 해싱: 각 게시물의 내용은 해시(SHA‑256, 32자까지 잘림)됩니다.
  • 상태 파일: documentation/.sync-state.json은 해시, 동기화 타임스탬프 및 Dev.to URL을 저장합니다.
{
  "index": {
    "hash": "a1b2c3d4e5f67890...",
    "syncedAt": "2026-01-07T10:00:00Z",
    "url": "https://dev.to/bbos/srdd-...-4k2n"
  },
  "pitches": {
    "hash": "f0e1d2c3b4a59687...",
    "syncedAt": "2026-01-07T10:00:00Z",
    "url": "https://dev.to/bbos/pitches-...-2j8m"
  }
}

url 필드는 각 기사에 대한 Dev.to URL을 캐시하여 API 속도 제한으로 URL을 가져올 수 없을 때도 자리표시자 해석을 가능하게 합니다.

강제 전체 동기화

변경 여부와 관계없이 모든 포스트를 동기화하려면:

env:
  FORCE_SYNC: 'true'

또는 로컬에서 실행하려면:

node sync-to-devto.js --force
# With .env file
export $(grep -v '^#' .env | xargs) && node sync-to-devto.js --force

URL 캐시 새로 고침

기사 이름이 바뀌었거나 URL이 변경된 경우, 캐시된 URL을 새로 고칩니다:

env:
  REFRESH_URLS: 'true'

또는 로컬에서:

node sync-to-devto.js --refresh-urls
# With .env file
export $(grep -v '^#' .env | xargs) && node sync-to-devto.js --refresh-urls

정규 URL

Dev.to의 모든 글에는 GitHub Pages 버전을 가리키는 canonical_url이 포함됩니다. 예시:

canonical_url: https://docs-bbos.github.io/srdd/SRDD-part1-of-4/

혜택

  • SEO 통합 – 검색 순위가 단일 URL에 집중됩니다.
  • 플랫폼 유연성 – 콘텐츠가 Dev.to, Medium 또는 향후 플랫폼에 나타날 수 있습니다.
  • 단일 진실 원천 – 독자는 언제나 권위 있는 버전을 찾을 수 있는 위치를 알 수 있습니다.

새 페이지 추가

  1. 적절한 프론트 매터가 포함된 documentation/new-page.md 파일을 생성합니다.
  2. 다른 페이지에서 {{devto:new-page}} 를 사용해 링크합니다.
  3. main 브랜치에 커밋하고 푸시합니다.

파이프라인이 자동으로 GitHub Pages에 배포하고 새 글을 Dev.to와 동기화합니다.

필수 비밀 및 변수

Secret / Variable목적
DEVTO_API_KEYDev.to API 키 (dev.to → Settings → Extensions 에서 찾을 수 있음).
SITE_URLGitHub Pages 기본 URL (예: https://docs-bbos.github.io/srdd).

이 인프라스트럭처는 방법론과 함께 진화하는 살아있는 문서를 위해 “한 번 작성, 어디서든 게시” 를 가능하게 합니다.

Back to Blog

관련 글

더 보기 »