Merge pull request #5 from DanMeon/feature/v0.3.0 #26
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| # 트리거: PR / main 푸시 — test 계열만 (wheel 빌드 + 배포는 publish.yml) | |
| # 문서·라이선스·gitignore 전용 변경은 paths-ignore 로 스킵 (런타임·빌드 영향 없음) | |
| on: | |
| push: | |
| branches: [main] | |
| paths-ignore: | |
| - '**.md' | |
| - 'docs/**' | |
| - 'LICENSE*' | |
| - '.gitignore' | |
| pull_request: | |
| branches: [main] | |
| paths-ignore: | |
| - '**.md' | |
| - 'docs/**' | |
| - 'LICENSE*' | |
| - '.gitignore' | |
| workflow_dispatch: {} | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| jobs: | |
| # * Linux abi3 wheel 1회 빌드 → 모든 Linux 잡(test×4 / slow / core-only)이 공유 | |
| # abi3-py310 이라 py3.10/3.11/3.12/3.13 가 동일 wheel 재사용 가능. | |
| # macOS/Windows 는 단일 잡이라 빌드/테스트 분리 이득이 없어 그대로 매번 빌드. | |
| build-linux-wheel: | |
| name: Build Linux abi3 wheel | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| submodules: recursive | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| save-if: ${{ github.ref == 'refs/heads/main' }} | |
| - uses: astral-sh/setup-uv@v8.1.0 | |
| with: | |
| python-version: "3.12" | |
| - run: uv sync --no-install-project --group all | |
| - run: uv run maturin build --release --out dist | |
| - uses: actions/upload-artifact@v7 | |
| with: | |
| name: rhwp-python-linux-wheel | |
| path: dist/*.whl | |
| retention-days: 1 | |
| # * 메인 테스트 + 린트 + 타입체크 (Linux × 전 Python 버전 — wheel 공유) | |
| test: | |
| name: Test (Linux / py${{ matrix.python }}) | |
| needs: build-linux-wheel | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - { python: "3.10", lint: true } | |
| - { python: "3.11" } | |
| - { python: "3.12" } | |
| - { python: "3.13" } | |
| defaults: | |
| run: | |
| shell: bash | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| submodules: recursive | |
| - uses: astral-sh/setup-uv@v8.1.0 | |
| with: | |
| python-version: ${{ matrix.python }} | |
| - run: uv sync --no-install-project --group all | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| name: rhwp-python-linux-wheel | |
| path: dist/ | |
| - run: uv pip install --reinstall dist/*.whl | |
| - name: Run pytest (not slow) with coverage | |
| run: uv run pytest tests/ -m "not slow" --cov=rhwp --cov-report=term-missing -v | |
| - name: Run pyright (normal) | |
| if: matrix.lint | |
| run: | | |
| uv run pyright python/ \ | |
| tests/test_smoke.py tests/test_parse.py tests/test_text_extraction.py \ | |
| tests/test_errors.py tests/test_svg_rendering.py tests/test_pdf_rendering.py \ | |
| tests/test_langchain_loader.py tests/test_langchain_loader_ir.py \ | |
| tests/test_ir_schema.py tests/test_ir_roundtrip.py tests/test_ir_tables.py \ | |
| tests/test_ir_iter_blocks.py tests/test_ir_schema_export.py \ | |
| tests/test_ir_picture.py tests/test_ir_furniture.py \ | |
| tests/test_ir_formula.py tests/test_ir_footnote.py \ | |
| tests/test_ir_list.py tests/test_ir_caption.py \ | |
| tests/test_ir_toc.py tests/test_ir_field.py \ | |
| tests/test_cli.py \ | |
| tests/conftest.py tests/type_check_samples.py | |
| - name: Run pyright (intentional errors — expect 4) | |
| if: matrix.lint | |
| run: | | |
| set +e | |
| uv run pyright --outputjson tests/type_check_errors.py > pyright-errors.json | |
| count=$(uv run python -c "import json; print(json.load(open('pyright-errors.json'))['summary']['errorCount'])") | |
| echo "intentional error count: $count" | |
| if [ "$count" != "4" ]; then | |
| echo "::error::expected 4 intentional errors, got $count" | |
| exit 1 | |
| fi | |
| # * macOS / Windows 스모크 — 단일 잡이라 wheel 분리 이득 없음 → 직접 maturin develop | |
| test-other-os: | |
| name: Test (${{ matrix.os }} / py3.12) | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [macos-latest, windows-latest] | |
| defaults: | |
| run: | |
| shell: bash | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| submodules: recursive | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| save-if: ${{ github.ref == 'refs/heads/main' }} | |
| - uses: astral-sh/setup-uv@v8.1.0 | |
| with: | |
| python-version: "3.12" | |
| - run: uv sync --no-install-project --group all | |
| - run: uv run maturin develop --release | |
| - run: uv run pytest tests/ -m "not slow" -v | |
| # * PDF 렌더링 — 느려서 별도 잡, Linux wheel 재사용 | |
| test-slow: | |
| name: Test slow (Linux / py3.12 — PDF) | |
| needs: build-linux-wheel | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| shell: bash | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| submodules: recursive | |
| - uses: astral-sh/setup-uv@v8.1.0 | |
| with: | |
| python-version: "3.12" | |
| - run: uv sync --no-install-project --group testing | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| name: rhwp-python-linux-wheel | |
| path: dist/ | |
| - run: uv pip install --reinstall dist/*.whl | |
| - run: uv run pytest tests/ -m slow -v | |
| # * extras 미설치 시 langchain 테스트가 importorskip 로 auto-skip 되는지 검증 | |
| test-core-only: | |
| name: Test without extras (importorskip auto-skip) | |
| needs: build-linux-wheel | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| shell: bash | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| submodules: recursive | |
| - uses: astral-sh/setup-uv@v8.1.0 | |
| with: | |
| python-version: "3.12" | |
| - name: Install pytest only (no langchain extras — intentional) | |
| run: | | |
| uv venv | |
| uv pip install pytest | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| name: rhwp-python-linux-wheel | |
| path: dist/ | |
| - run: uv pip install dist/*.whl | |
| - name: Run pytest — extras-gated tests must auto-skip via importorskip | |
| # ^ 파일-레벨 importorskip 은 해당 파일 전체를 skip 1개로 카운트. | |
| # v0.3.0 기준 gated 파일: test_langchain_loader.py + test_langchain_loader_ir.py | |
| # (langchain-core), test_ir_schema_export.py (jsonschema), test_cli.py (typer) | |
| # → 총 4 파일. test_async.py 는 v0.3.0 부터 stdlib 만 사용 (aiofiles 의존성 제거) | |
| run: | | |
| uv run pytest tests/ -m "not slow" -v | tee pytest-output.txt | |
| if ! grep -qE '(^|[^0-9])4 skipped([^0-9]|$)' pytest-output.txt; then | |
| echo "::error::expected 4 extras-gated files to auto-skip via importorskip (langchain×2, jsonschema, typer)" | |
| exit 1 | |
| fi | |
| all-tests-passed: | |
| name: All tests passed | |
| if: always() | |
| runs-on: ubuntu-latest | |
| needs: [build-linux-wheel, test, test-other-os, test-slow, test-core-only] | |
| steps: | |
| - uses: re-actors/alls-green@release/v1 | |
| with: | |
| jobs: ${{ toJSON(needs) }} |