Skip to content

[skip release] docs(qa): Round 7 index entry #199

[skip release] docs(qa): Round 7 index entry

[skip release] docs(qa): Round 7 index entry #199

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')
"