An automated pipeline that discovers, generates, validates, and publishes SDK-style C# examples for Aspose .NET plugin APIs (LowCode and Plugins namespaces) — from NuGet package to live GitHub PR, with no hand-written code.
This repository is the source pipeline for producing published C# example projects for Aspose .NET product families. It does not contain the examples themselves — it contains the machinery that creates, validates, and publishes them to separate family-specific repositories on GitHub.
Each published example is a self-contained C# console project that demonstrates a single LowCode or Plugins API use case. Examples are discovered from NuGet packages by reflecting their DLLs, generated by an LLM constrained to reflected API symbols, compiled and executed by dotnet, and published via pull request.
Given a family config (e.g. cells, pdf, words), the pipeline:
- Fetches the NuGet package and resolves its dependencies.
- Reflects the package DLLs to build a catalog of all available API types, methods, and properties.
- Detects which namespaces qualify as LowCode or Plugins entry points (source-of-truth proof).
- Plans scenarios — one example per qualifying API entry point, cross-referenced against fixtures and existing published examples.
- Generates C# code using an LLM constrained to the reflected API catalog, using structured prompt templates.
- Validates every generated project through
dotnet restore→dotnet build→dotnet run→ output assertion. Failures are blocked with explicit reasons; none are silently dropped. - Reviews generated code through an optional external
example-reviewergate. - Publishes validated examples to a family-specific GitHub repository via a pull request, gated by an approval token.
The pipeline is a gate-driven Python orchestrator (src/plugin_examples/runner.py) that calls a .NET 8 reflection helper (tools/DllReflector/) for API discovery. Each stage writes structured evidence (JSON manifests, scenario catalogs, validation results) to workspace/ before the next stage is allowed to proceed.
LLM generation is the only non-deterministic stage. All other stages — fetch, extract, reflect, plan, validate, gate, publish — are fully deterministic. LLM output is constrained before generation (only reflected symbols are injected into prompts), and rejected after generation if it fails dotnet compilation, runtime execution, or output validation.
Hard-stop stages abort the run if they fail. Soft-stop stages record verdicts and preserve blocked scenarios for future runs. Nothing is silently skipped.
┌─────────────────────────────────────────────────────────────────────────────┐
│ INPUTS │
│ │
│ pipeline/configs/families/*.yaml pipeline/prompts/ pipeline/schemas/ │
│ (family config) (LLM templates) (JSON schemas) │
└────────────────────────────┬────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ PIPELINE (src/plugin_examples/) │
│ │
│ nuget_fetch ──► dependency_resolution ──► extraction │
│ │ │ │
│ ▼ ▼ │
│ [NuGet package + DLLs] tools/DllReflector/ (.NET 8) │
│ │ │
│ ▼ │
│ reflection ──► plugin_detection │
│ │ │
│ ▼ │
│ api_delta / impact_mapping │
│ │ │
│ ▼ │
│ fixture_registry / example_mining │
│ │ │
│ ▼ │
│ scenario_planning │
│ (one scenario per API) │
│ │ │
│ ┌─────────────┴─────────────┐ │
│ ▼ ▼ │
│ llm_preflight [blocked scenarios] │
│ │ (preserved with reason) │
│ ▼ │
│ generation ◄──── LLM endpoint (GPT_OSS_ENDPOINT) │
│ (C# console projects, constrained to reflected symbols) │
│ │ │
│ ▼ │
│ validation (dotnet restore → build → run → output check) │
│ │ │
│ ▼ │
│ reviewer (optional: example-reviewer subprocess gate) │
│ │ │
│ ▼ │
│ publisher ◄──── GITHUB_TOKEN + approval env var │
└────────────────────────┬────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ OUTPUTS │
│ │
│ workspace/ (gitignored runtime artifacts — manifests, evidence, ZIPs) │
│ │
│ GitHub target repos (one per family) │
│ └── PR → review → merge → live published examples │
└─────────────────────────────────────────────────────────────────────────────┘
Key design properties:
- Every stage writes structured evidence before the next stage starts.
- LLM generation is the only non-deterministic step; all validation is deterministic.
- Blocked examples are never dropped — they are preserved with explicit reasons.
- PR creation and PR merge are gated by separate approval environment variables.
- The pipeline can run in
--dry-runor--template-modewithout touching GitHub or the LLM.
Pipeline repository for generating, validating, and publishing SDK-style C# examples for Aspose .NET plugin APIs, including LowCode and Plugins namespaces.
Published examples live in separate family-specific example repositories. This repository contains the pipeline, configuration, schemas, tests, prompts, and operational tooling.
The pipeline is fully implemented and operational. Six product families have live published examples in their target repositories on GitHub. Additional family configs exist in pipeline/configs/families/ (barcode, cad, drawing, epub, finance, font, gis, html, imaging, note, ocr, omr, page, psd, svg, tasks, tex, threed, zip) but have not yet been run to evidence.
Examples are published to separate family-specific repositories. The table below reflects the current state of each target repository, verified directly from GitHub.
| Family | NuGet Package | Published Examples | Example Types | Target Repository |
|---|---|---|---|---|
| Cells | Aspose.Cells |
9 | html-converter, image-converter, json-converter, pdf-converter, spreadsheet-converter, spreadsheet-locker, spreadsheet-merger, spreadsheet-splitter, text-converter | Aspose.Cells.LowCode-for-.NET-Examples |
Aspose.PDF |
19 | doc-converter, form-editor, form-exporter, form-flattener, html, image-extractor, jpeg, merger, optimizer, pdfa-converter, png, security, signature, splitter, table-generator, text-extractor, tiff, toc-generator, xls-converter | Aspose.PDF.LowCode-for-.NET-Examples | |
| Words | Aspose.Words |
8 | comparer, converter, mail-merger, merger, replacer, report-builder, splitter, watermarker | Aspose.Words.LowCode-for-.NET-Examples |
| Slides | Aspose.Slides.NET |
3 | compress, convert, merger | Aspose.Slides.LowCode-for-.NET-Examples |
Aspose.Email |
1 | converter | Aspose.Email.LowCode-for-.NET-Examples | |
| Diagram | Aspose.Diagram |
2 | diagram-diagram-converter, diagram-pdf-converter | Aspose.Diagram.LowCode-for-.NET-Examples |
Total published: 42 examples across 6 families.
Each example is a self-contained C# console project under examples/{family}/lowcode/{type}/ in the target repository. All examples passed dotnet restore, build, run, and output validation gates before publication.
Start with the docs landing page:
The pipeline integrates with example-reviewer as an optional post-generation gate. The reviewer validates generated C# examples before they are allowed to proceed to PR publishing.
Integration is via subprocess (python -m src.cli.main). The bridge code resolves the reviewer location in priority order:
EXAMPLE_REVIEWER_PATHenvironment variable.- Sibling directory convention — a checkout named
example-reviewerin the parent of this repo.
The reviewer is optional unless --require-reviewer is passed or the family config sets validation.require_example_reviewer: true. If the reviewer is unavailable and not required, the pipeline marks the reviewer stage as degraded rather than failing the run.
To wire it in:
# Clone the reviewer alongside this repo
git clone https://github.com/babar-raza/example-reviewer ../example-reviewer
cd ../example-reviewer && pip install -e .
# Or point to an existing checkout
$env:EXAMPLE_REVIEWER_PATH = "C:\path\to\example-reviewer"# bash / Linux / macOS
git clone https://github.com/babar-raza/example-reviewer ../example-reviewer
cd ../example-reviewer && pip install -e .
# Or point to an existing checkout
export EXAMPLE_REVIEWER_PATH="/path/to/example-reviewer"See src/plugin_examples/verifier_bridge/ and Validation and Reviewer.
Note: The repository code references https://github.com/babar-raza/example-reviewer. No other reviewer URL appears in the codebase. If you are using a different host for the reviewer, set EXAMPLE_REVIEWER_PATH to point to your local checkout.
Prerequisites:
- Python 3.12 or newer.
- .NET SDK 8.0 (for DllReflector and generated project validation).
Install:
python -m pip install --upgrade pip
pip install -e ".[dev]"# bash / Linux / macOS
python3 -m pip install --upgrade pip
pip install -e ".[dev]"GitHub token (live operations only):
# Store once (Windows system env)
[Environment]::SetEnvironmentVariable("GH_TOKEN", "ghp_YOUR_TOKEN", "User")
# Map before each live command
$env:GITHUB_TOKEN = [Environment]::GetEnvironmentVariable("GH_TOKEN", "User")# bash / Linux / macOS
# Store once (add to ~/.bashrc or ~/.zshrc)
export GH_TOKEN="ghp_YOUR_TOKEN"
# Map before each live command
export GITHUB_TOKEN="$GH_TOKEN"LLM endpoint (generation only):
$env:GPT_OSS_ENDPOINT = "https://llm.professionalize.com/v1/"
$env:GPT_OSS_MODEL = "<model-name>"
$env:GPT_OSS_API_KEY = "<api-key>"# bash / Linux / macOS
export GPT_OSS_ENDPOINT="https://llm.professionalize.com/v1/"
export GPT_OSS_MODEL="<model-name>"
export GPT_OSS_API_KEY="<api-key>"The pipeline aborts before generation if GPT_OSS_ENDPOINT is unset or does not point to https://llm.professionalize.com/v1/. No other LLM provider is permitted.
Check pipeline status:
python -m plugin_examples status# bash / Linux / macOS
python3 -m plugin_examples statusRun a dry-run pipeline:
$env:PYTHONPATH = "src"
python -m plugin_examples run --family cells --dry-run --template-mode --promote-latest# bash / Linux / macOS
PYTHONPATH=src python3 -m plugin_examples run --family cells --dry-run --template-mode --promote-latestRun source-of-truth discovery:
python -m plugin_examples run --family cells --dry-run --promote-latest# bash / Linux / macOS
python3 -m plugin_examples run --family cells --dry-run --promote-latestRun with LLM generation:
python -m plugin_examples run --family cells --promote-latest# bash / Linux / macOS
python3 -m plugin_examples run --family cells --promote-latestRun local tests:
$env:PYTHONPATH = "src"
# Unit tests with coverage (CI requires >= 70%)
python -m pytest tests/unit -v --timeout=60 --cov=src/plugin_examples --cov-report=term-missing --cov-fail-under=70
# Integration tests
python -m pytest tests/integration -v --timeout=120
python -m compileall src
dotnet build tools/DllReflector/DllReflector.csproj -c Release# bash / Linux / macOS
# Unit tests with coverage (CI requires >= 70%)
PYTHONPATH=src python3 -m pytest tests/unit -v --timeout=60 --cov=src/plugin_examples --cov-report=term-missing --cov-fail-under=70
# Integration tests
PYTHONPATH=src python3 -m pytest tests/integration -v --timeout=120
python3 -m compileall src
dotnet build tools/DllReflector/DllReflector.csproj -c ReleaseDoctor health check:
PYTHONPATH=src python3 -m plugin_examples doctorThe pipeline is a gate-driven Python orchestrator with a .NET reflection helper.
NuGet package
-> dependency resolution
-> extraction (DLL/XML assets)
-> reflection catalog (API symbols)
-> plugin detection (LowCode/Plugins namespace proof)
-> API delta and impact mapping
-> fixture discovery and example mining
-> scenario planning
-> LLM preflight
-> LLM/template generation (C# console projects)
-> dotnet restore / build / run / output validation
-> external example-reviewer (optional)
-> gates and verdicts
-> PR publishing
Deterministic stages: NuGet fetch, extraction, reflection, plugin detection, API delta, fixture registry, scenario planning, dotnet validation, gates, evidence writing, PR publish/merge.
LLM-driven stage: generation (llm_router calls https://llm.professionalize.com/v1/). LLM output is constrained to reflected API symbols and validated by compiler, runtime, output validator, and optional external reviewer before a PR is created.
Safeguards against bad LLM output:
- Generated code may only use API symbols from the reflected NuGet catalog.
- All examples undergo dotnet restore/build/run before they are gated as publishable.
- Output validators check stdout/stderr and semantic file content.
- An external example-reviewer can be wired in as an additional gate.
- Blocked examples are preserved with explicit reasons; they are never silently dropped.
Pipeline stages (defined in src/plugin_examples/runner.py):
| Stage | Output |
|---|---|
nuget_fetch |
Download manifest |
dependency_resolution |
Package lock |
extraction |
DLL/XML assets |
reflection |
API catalog |
plugin_detection |
Source-of-truth proof |
api_delta / impact_mapping |
Delta and impact reports |
fixture_registry / example_mining |
Fixture registry, existing examples index |
scenario_planning |
Scenario catalog, blocked scenarios |
llm_preflight |
Provider readiness result |
generation |
Generated C# projects and example index |
validation |
restore/build/run/output validation results |
reviewer |
External reviewer results |
publisher |
Publishing report |
Hard-stop stages: load_config, nuget_fetch, dependency_resolution, extraction, reflection, plugin_detection, scenario_planning.
See Pipeline Stages and Gates and Verdicts.
| Path | Purpose |
|---|---|
src/plugin_examples/ |
Python package (CLI, runner, all pipeline modules) |
pipeline/configs/families/ |
Active family YAML configs (one per product) |
pipeline/configs/families/disabled/ |
Disabled family configs (loader rejects these) |
pipeline/schemas/ |
JSON schemas for configs, catalogs, scenarios, packets, and manifests |
pipeline/contracts/ |
Per-family scenario contracts |
pipeline/prompts/ |
LLM prompt templates |
pipeline/format-authority/ |
Format authority manifest and contracts |
templates/root-readme/ |
Jinja2 README rendering templates |
tools/DllReflector/ |
.NET 8 reflection helper (called from reflection_catalog) |
tests/unit/ |
Unit tests (100+ test files) |
tests/integration/ |
Integration tests |
tests/fixtures/ |
Test fixture data |
scripts/ |
Operational helper scripts |
workspace/ |
Runtime output directory (gitignored). Holds per-run artifacts, evidence, manifests, and dry-run packages. |
docs/ |
Documentation |
.github/workflows/build-and-test.yml runs on every push and PR to main:
- Python 3.12 and 3.13 unit tests.
python -m compileall src.- DllReflector build with .NET 8.0.
.github/workflows/monthly-package-refresh.yml runs on the 1st of each month:
- Full or tier-based pipeline run (default family:
cells). - Evidence integrity checks.
- Published example build regression.
- CLI Reference
- Configuration Reference
- Environment Variables
- File Contracts
- Gates and Verdicts
- Validation and Reviewer
- Publishing and GitHub
- Schemas and Contracts
- Metrics
- Code and schemas are the source of truth.
- Official NuGet packages are authoritative for API symbols.
- Generation must not proceed without source-of-truth proof.
- Publishing is pull-request based; no direct push to
main. - Live PR creation and merge require separate approval tokens.
- Evidence must be recorded for successful, partial, and failed runs.
- The LLM router code retains legacy branches for generic/OpenAI/Ollama-style providers. Only
https://llm.professionalize.com/v1/is governance-approved; the legacy branches should be treated as inactive. - One code path in target-repo health has a fallback read of
GH_TOKENdirectly; operators should always map it toGITHUB_TOKENbefore live commands regardless. - Fine-grained GitHub PATs owned by personal accounts can fail against org-owned repos via the Git Data API. Use a classic PAT with
reposcope stored inGH_TOKEN. - The
wordsfamily has fewer published examples than other families; some scenarios are blocked and preserved with explicit reasons in the run evidence underworkspace/(gitignored).
See docs/_audit/ for the current system audit and traceability records.