[skip release] docs(qa): Round 7 index entry #199
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: fc-pdfimporter-ci | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - master | |
| pull_request: | |
| workflow_dispatch: | |
| concurrency: | |
| group: fc-pdfimporter-ci-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| sketchup-harness-syntax: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v7 | |
| - name: Set up Ruby | |
| uses: ruby/setup-ruby@v1 | |
| with: | |
| ruby-version: "3.2" | |
| bundler-cache: false | |
| - name: Check Ruby harness syntax | |
| run: ruby -c PDFVectorImporter/adapters/sketchup_harness.rb | |
| version-check: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v7 | |
| - name: Check package/readme/pyproject version consistency | |
| run: | | |
| PKG_VER=$(grep -oP '(?<=<version>)[^<]+' PDFVectorImporter/package.xml | head -n1) | |
| ROOT_README_VER=$(grep -oP 'Version-\K[0-9.]+' README.md | head -n1) | |
| MOD_README_VER=$(grep -oP 'Version-\K[0-9.]+' PDFVectorImporter/README.md | head -n1) | |
| PYPROJECT_VER=$(grep -oP '(?<=^version = ")[^"]+' pyproject.toml | head -n1) | |
| echo "package=$PKG_VER root=$ROOT_README_VER module=$MOD_README_VER pyproject=$PYPROJECT_VER" | |
| if [ -z "$PKG_VER" ] || [ -z "$ROOT_README_VER" ] || [ -z "$MOD_README_VER" ] || [ -z "$PYPROJECT_VER" ]; then | |
| echo "ERROR: Could not read version(s): package=$PKG_VER root=$ROOT_README_VER module=$MOD_README_VER pyproject=$PYPROJECT_VER" | |
| exit 1 | |
| fi | |
| if [ "$PKG_VER" != "$ROOT_README_VER" ] || [ "$PKG_VER" != "$MOD_README_VER" ] || [ "$PKG_VER" != "$PYPROJECT_VER" ]; then | |
| echo "ERROR: Version mismatch package=$PKG_VER root=$ROOT_README_VER module=$MOD_README_VER pyproject=$PYPROJECT_VER" | |
| exit 1 | |
| fi | |
| # Source-compat guard for FreeCAD 0.19/0.20 hosts (Python 3.8/3.9). | |
| # Syntax-only: the vendored PyMuPDF wheel is cp310-abi3, so the full | |
| # dependency suite runs on >=3.10 (D5 ABI floor). | |
| legacy-syntax: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python-version: ["3.8", "3.9"] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v7 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Compile all Python modules (legacy floor) | |
| run: python -m compileall PDFVectorImporter | |
| syntax-check: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python-version: ["3.10", "3.11", "3.12"] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v7 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Compile all Python modules | |
| run: python -m compileall PDFVectorImporter | |
| - name: Install ruff | |
| run: pip install ruff | |
| - name: Lint (functional + bugbear) | |
| run: ruff check --select F,B PDFVectorImporter | |
| - name: Install dependencies | |
| run: pip install "PyMuPDF>=1.24,<2.0" pytest | |
| - name: Verify pdfcadcore sync manifest | |
| run: python pdfcadcore_sync_check.py --skip-cross-repo | |
| - name: Run pdfcadcore unit tests | |
| run: python -m pytest tests/ -v | |
| - name: Validate corpus contract schemas | |
| env: | |
| BCS_CORPUS_ROOT: ${{ github.workspace }}/pdf-test-corpus | |
| CORPUS_READ_TOKEN: ${{ secrets.CORPUS_READ_TOKEN }} | |
| run: | | |
| # Corpus repo is private: authenticated clone when the owner adds a | |
| # CORPUS_READ_TOKEN secret (fine-grained PAT, corpus read-only); | |
| # anonymous clone if the repo ever goes public; otherwise skip with | |
| # a visible warning instead of failing CI (run 28710907631 failed | |
| # exit 128 on the anonymous clone of the private repo). | |
| if [ -n "$CORPUS_READ_TOKEN" ]; then | |
| git clone --depth 1 "https://x-access-token:${CORPUS_READ_TOKEN}@github.com/BlueCollar-Systems/pdf-test-corpus.git" pdf-test-corpus | |
| elif ! git clone --depth 1 https://github.com/BlueCollar-Systems/pdf-test-corpus.git pdf-test-corpus; then | |
| echo "::warning::corpus not readable (private repo, no CORPUS_READ_TOKEN secret) - schema gate skipped" | |
| exit 0 | |
| fi | |
| python pdf-test-corpus/tools/validate_contract_schemas.py | |
| - name: BCS-ARCH-001 mode smoke test | |
| run: | | |
| python -c " | |
| import sys, math | |
| sys.path.insert(0, 'PDFVectorImporter') | |
| from pdfcadcore.primitive_extractor import extract_page | |
| from pdfcadcore.auto_mode import classify_page_content | |
| from pdfcadcore.import_config import ImportConfig | |
| import fitz, tempfile, os | |
| # Build a mixed-content sample PDF (geometry + text + arcs) | |
| tmp = tempfile.NamedTemporaryFile(suffix='.pdf', delete=False) | |
| doc = fitz.open() | |
| p = doc.new_page(width=612, height=792) | |
| p.draw_line((50,50),(300,50), color=(0,0,0), width=1) | |
| p.draw_circle((200,400), 30, color=(1,0,0), width=0.5) | |
| for i in range(8): | |
| a = 2*math.pi*i/8 | |
| x, y = 400+25*math.cos(a), 300+25*math.sin(a) | |
| p.draw_line((400,300),(x,y), color=(0,0,1), width=0.3) | |
| tw = fitz.TextWriter(p.rect) | |
| tw.append((100,700), 'BOLT 3/4\" DIA', fontsize=12) | |
| tw.write_text(p) | |
| p2 = doc.new_page(width=612, height=792) | |
| p2.draw_rect((50,50,560,740), color=(0,0,0), width=0.5) | |
| doc.save(tmp.name) | |
| doc.close() | |
| mode_builders = [ | |
| ('auto', ImportConfig.auto), | |
| ('vector', ImportConfig.vector), | |
| ('raster', ImportConfig.raster), | |
| ('hybrid', ImportConfig.hybrid), | |
| ] | |
| errors = [] | |
| doc = fitz.open(tmp.name) | |
| for mode_name, builder in mode_builders: | |
| try: | |
| cfg = builder() | |
| assert cfg.import_mode in ('auto', 'vector', 'raster', 'hybrid') | |
| for pg in range(len(doc)): | |
| page_data = extract_page(doc[pg], pg + 1) | |
| assert len(page_data.primitives) >= 0 | |
| except Exception as e: | |
| errors.append(f'{mode_name}: {e}') | |
| drawings = doc[0].get_drawings() | |
| cls = classify_page_content(drawings) | |
| assert cls['type'] == 'vectors', f'Expected vectors, got {cls[\"type\"]}' | |
| doc.close() | |
| os.unlink(tmp.name) | |
| if errors: | |
| for e in errors: print(f'FAIL: {e}') | |
| sys.exit(1) | |
| print(f'PASS: {len(mode_builders)} BCS-ARCH-001 modes x 2 pages + auto-mode verified') | |
| " |