본문으로 건너뛰기

[pydantic-ai] Depot 러너와 inline_snapshot 우회로 CI 성능 대폭 개선

PR 링크: pydantic/pydantic-ai#4346 상태: Merged | 변경: +231 / -85

들어가며

CI 파이프라인의 실행 시간은 개발 생산성에 직접적인 영향을 미칩니다. pydantic-ai 프로젝트에서 가장 느린 테스트 변형(all-extras)의 CI 속도를 개선하기 위해 두 가지 전략을 동시에 적용했습니다: Depot 4코어 러너를 선택적으로 사용하는 것과, inline_snapshot 라이브러리의 무거운 import를 경량 스텁으로 대체하는 것입니다.

핵심 코드 분석

1. Depot 러너 조건부 사용

Before:

test:
  name: test on ${{ matrix.python-version }}
  runs-on: ubuntu-latest

After:

test:
  runs-on: >-
    ${{
      !contains(github.event.pull_request.labels.*.name, 'ci:slow')
      && matrix.install.name == 'all-extras'
      && (
        github.event.pull_request.head.repo.full_name == github.repository
        || contains(github.event.pull_request.labels.*.name, 'ci:fast')
      )
      && 'depot-ubuntu-24.04-4'
      || 'ubuntu-latest'
    }}

ci:slow 라벨로 강제 표준 러너, ci:fast로 외부 기여자도 Depot 러너를 사용할 수 있게 했습니다. 가장 느린 all-extras 변형만 선택적으로 4코어 러너를 할당하여 비용 효율을 유지합니다.

2. inline_snapshot 경량 스텁

Before:

from inline_snapshot import snapshot

모든 테스트 실행 시 inline_snapshot의 무거운 AST 재작성 엔진이 import되어 pytest-xdist 워커 초기화가 느려졌습니다.

After:

# tests/_inline_snapshot.py
if any(arg.startswith('--inline-snapshot') or arg.startswith('--snap') for arg in sys.argv):
    from inline_snapshot import snapshot as snapshot
else:
    class _SnapshotProxy:
        def __init__(self, value):
            self._value = value

        def __eq__(self, other):
            result = other == self._value
            if not result:
                warnings.warn(f'Snapshot mismatch: {other!r} != {self._value!r}')
            return result

    def snapshot(value=_MISSING):
        if value is _MISSING:
            raise RuntimeError('snapshot() called without a value.')
        return _SnapshotProxy(value)

CLI 플래그가 없을 때는 값 비교만 수행하는 경량 _SnapshotProxy를 사용합니다. 스냅샷 업데이트가 필요할 때만 --inline-snapshot=fix 플래그로 실제 라이브러리를 로드합니다. 모든 테스트 파일의 import가 from ._inline_snapshot import snapshot으로 변경되었습니다.

왜 이게 좋은가

이 접근법은 두 가지 독립적인 병목을 동시에 해결합니다. Depot 러너는 하드웨어 수준의 병렬성을 높이고, inline_snapshot 스텁은 Python import 수준의 오버헤드를 제거합니다. 특히 pytest-xdist에서 여러 워커가 동시에 초기화될 때 import 비용이 워커 수만큼 곱해지므로, 경량 스텁의 효과가 극대화됩니다. 라벨 기반 러너 선택은 Depot 장애 시 ci:slow 라벨로 즉시 폴백할 수 있는 운영 유연성도 제공합니다.

정리

항목 내용
전략 1 Depot 4코어 러너로 all-extras 테스트 가속
전략 2 inline_snapshot 경량 스텁으로 워커 초기화 가속
안전장치 ci:slow/ci:fast 라벨로 러너 강제 선택

참고 자료

⚠️ 알림: 이 분석은 AI가 실제 코드 diff를 기반으로 작성했습니다.

댓글

관련 포스트

PR Analysis 의 다른글