Skip to content

Merge pull request #1091 from JSv4/codex/rendering-fidelity-nested-table #2010

Merge pull request #1091 from JSv4/codex/rendering-fidelity-nested-table

Merge pull request #1091 from JSv4/codex/rendering-fidelity-nested-table #2010

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
# Every pull request, whatever its base: a PR stacked on another PR's branch gets the same checks
# as one into main, instead of waiting until it is retargeted to main to find a failure.
permissions:
contents: read
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup .NET
uses: actions/setup-dotnet@v6
with:
dotnet-version: '10.0.x'
- name: Test LibreOffice rendering diagnostics
run: python3 -m unittest discover -s tools/diffharness/lo -p 'test_*.py'
- name: Restore dependencies
run: |
dotnet restore Docxodus/Docxodus.csproj
dotnet restore Docxodus.Tests/Docxodus.Tests.csproj
dotnet restore tools/redline/redline.csproj
dotnet restore tools/docx2html/docx2html.csproj
dotnet restore tools/docx2oc/docx2oc.csproj
- name: Build library
run: dotnet build Docxodus/Docxodus.csproj -c Release --no-restore
- name: Build CLI tools
run: |
dotnet build tools/redline/redline.csproj -c Release --no-restore
dotnet build tools/docx2html/docx2html.csproj -c Release --no-restore
dotnet build tools/docx2oc/docx2oc.csproj -c Release --no-restore
# These projects are deliberately outside Docxodus.sln, so nothing else compiles
# them. Without this step a breaking change to the library rots them silently
# (issue #662: the benchmark harness sat un-buildable on main for a week).
- name: Build out-of-solution tools and benchmarks
run: |
dotnet build benchmarks/complex-form-doc/ComplexFormBenchmark.csproj -c Release
dotnet build benchmarks/docxdiff-stress/DocxDiffStress.csproj -c Release
dotnet build benchmarks/session-edit-cost/SessionEditCost.csproj -c Release
dotnet build tools/delivery/delivery.csproj -c Release
dotnet build tools/diffharness/diffharness.csproj -c Release
dotnet build tools/manifest-fuzz/afl/aflharness.csproj -c Release
dotnet build tools/manifest-fuzz/fuzzer/fuzzer.csproj -c Release
dotnet build tools/manifest-fuzz/replay/replay.csproj -c Release
dotnet build tools/screenshots/redline/redline-screenshot.csproj -c Release
# The epic #435 acceptance smoke is the only end-to-end exercise of the MCP
# surface — lifecycle, atomic apply, transaction replay, the refusals, save and
# reopen. It was documented as a by-hand run, so its committed assertions went
# stale on main and nobody noticed for a release (#687). Roughly a minute.
- name: Run MCP acceptance smoke
run: |
dotnet build tools/mcp-server/mcpserver.csproj -c Release
./scripts/mcp-smoke.sh
- name: Run tests
env:
DOCXODUS_EVAL_ARTIFACTS: ${{ github.workspace }}/eval-artifacts
run: dotnet test Docxodus.Tests/Docxodus.Tests.csproj -c Release --verbosity normal --logger "trx;LogFileName=test-results.trx"
# A test run executes most methods as unoptimized tier-0 code, while the ReadyToRun release CLIs
# and any long-running host run them fully optimized. Run the comparison tests once more with every
# method optimized from its first call, so a failure that only optimized code shows fails the pull
# request. Issue #925: a JIT miscompile of IrMarkupRenderer.EmitGapArranged broke the release
# redline while every test passed. About half a minute.
- name: Run comparison tests fully JIT-optimized
env:
DOTNET_TieredCompilation: '0'
run: dotnet test Docxodus.Tests/Docxodus.Tests.csproj -c Release --no-build --filter "FullyQualifiedName~DocxDiff"
- name: Run Python history binding integration tests
run: |
dotnet build tools/python-host/pyhost.csproj -c Release
python3 -m pip install -e './python[test]'
python3 -m pytest python/tests/test_history.py -q
- name: Upload test results
uses: actions/upload-artifact@v7
if: always()
with:
name: test-results
path: Docxodus.Tests/TestResults/*.trx
# A failed eval scenario is diagnosed from its preserved artifacts (both DOCX packages,
# rendered HTML, semantic diff, verification report, reversibility proof), not by re-running.
- name: Upload eval artifacts
uses: actions/upload-artifact@v7
if: failure()
with:
name: eval-artifacts
path: eval-artifacts/
if-no-files-found: ignore
build-npm:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup .NET
uses: actions/setup-dotnet@v6
with:
dotnet-version: '10.0.x'
- name: Install wasm-tools workload
run: dotnet workload install wasm-tools
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: '22'
- name: Install npm dependencies
run: cd npm && npm ci
- name: Build npm package (WASM + TypeScript)
run: cd npm && npm run build
- name: Check AOT profile cache invalidation
run: node --test scripts/aot-profile-cache.test.mjs
- name: TypeScript type check
run: cd npm && npx tsc --noEmit
# Asserts the packaging contract publish.yml relies on. Runs here so a broken
# package boundary fails a pull request instead of a release: publish.yml only
# triggers on a `v*` tag, and two bugs reached the v10.0.0 tag precisely because
# nothing exercised its steps before then. Browser-free (`npm pack --dry-run`),
# so it costs well under a minute.
- name: Release preflight (package boundaries)
run: RELEASE_PREFLIGHT_SKIP_INSTALL=1 ./scripts/release-preflight.sh
# The docx-scalpel (python/) suite is a client of the .NET core: pyhost.csproj
# project-references Docxodus.csproj, so a core change that breaks a DocxSession
# op fails here. That is the point of running it on every PR rather than
# path-filtering on python/**. python-publish.yml covers the packaged wheel per
# RID at release time; this job covers the full suite against the working tree.
python-tests:
runs-on: ubuntu-latest
strategy:
# Surface both interpreters' failures in one run.
fail-fast: false
matrix:
# Ends of the range declared by requires-python = ">=3.10" and the
# classifiers. 3.11/3.12 sit between them.
python-version: ['3.10', '3.13']
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup .NET
uses: actions/setup-dotnet@v6
with:
dotnet-version: '10.0.x'
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}
# A framework-dependent host is fine here: setup-dotnet makes .NET 10 the
# runner's primary runtime, so the apphost resolves it without DOTNET_ROOT.
# _host_locator.py's dev fallback then discovers this path by walking up to
# Docxodus.sln — no staging into _bin/ and no DOCXODUS_HOST needed.
- name: Build docxodus-pyhost
run: dotnet build tools/python-host/pyhost.csproj -c Release
- name: Install docx-scalpel (editable)
run: python -m pip install --upgrade pip && python -m pip install -e './python[test]'
- name: Run Python tests
run: python -m pytest python/tests -v
build-matrix:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup .NET
uses: actions/setup-dotnet@v6
with:
dotnet-version: '10.0.x'
- name: Restore
run: |
dotnet restore Docxodus/Docxodus.csproj
dotnet restore tools/redline/redline.csproj
dotnet restore tools/docx2html/docx2html.csproj
dotnet restore tools/docx2oc/docx2oc.csproj
- name: Build
run: dotnet build Docxodus/Docxodus.csproj -c Release --no-restore
- name: Build CLI tools
run: |
dotnet build tools/redline/redline.csproj -c Release --no-restore
dotnet build tools/docx2html/docx2html.csproj -c Release --no-restore
dotnet build tools/docx2oc/docx2oc.csproj -c Release --no-restore
# The release publishes the CLIs trimmed (issue #903), and a trim analysis warning fails
# that publish (the CLI projects build with TreatWarningsAsErrors). But publish.yml runs
# only at release time, after NuGet has shipped, so run the same trimmed publish here on
# each OS and smoke every binary: a trim break then fails the pull request, not a release.
- name: Publish trimmed CLI tools and smoke them
shell: bash
run: |
for t in redline docx2html docx2oc; do
dotnet publish tools/$t/$t.csproj -c Release --use-current-runtime --self-contained true -p:PublishSingleFile=true -p:PublishTrimmed=true -o ./trimmed/$t
done
./trimmed/redline/redline TestFiles/WC/WC001-Digits.docx TestFiles/WC/WC001-Digits-Mod.docx ./trimmed/redline.docx
./trimmed/docx2html/docx2html TestFiles/HC042-Image-Png.docx ./trimmed/out.html --extract-images
./trimmed/docx2oc/docx2oc TestFiles/HC006-Test-01.docx ./trimmed/out.json