Repository navigation
Decide the openapi-generator relationship and 0.2 maintenance plan before merging the pure-Julia rewrite (#103) #104
Description
Activity
This all sounds like a good plan + reasonable things to do pre-1.0 release.
- added a commit that references this issue
on Aug 26, 2026 Status update (2026-08-27)
The runtime-contract and docstring blockers were addressed on the #103 branch (details). I verified the claims against the PR head (
8124eec) directly — regenerated a sample client/server pair, loaded them, and exercised the failure paths — rather than taking the summary at face value. Everything checked out.Blocker-by-blocker
1. Compat breakage for existing generated code — OPEN. Untouched by the PR, deliberately: the 0.2 compat pin for
samples-julia.yaml, the upstreamProject.tomlemission, and cuttingrelease-0.2are decisions for this repo and openapi-generator, not for #103. Therelease-0.2branch cut is the most time-sensitive item on this whole list — it gets harder with every commit tomain.2. Generated-module ↔ runtime contract — RESOLVED, via the "private by policy, guarded" route:
Runtime.CONTRACT_VERSION(currently 3) plusRuntime.require_contract(version, generator); both documented as permanently frozen names.- Every generated module (client, server, and the
server_module_sourceextension path) stamps the producing OpenAPI.jl version in its banner and calls the guard at load time, before the privateimport OpenAPI.Runtime:list — verified live: a stale module fails with an actionable "regenerate" error naming both versions and both contract numbers. - The silent-failure hazard is gone at the source: generated code no longer bakes positional
Dialectliterals (standard dialects emit asSchemaEngine.dialect(:draft202012)lookups; custom ones use a keyword-only constructor),Runtime.Speckeywords are required, and a tripwire test pinsCONTRACT_VERSIONso shape changes without a bump fail CI. - Policy consequence, now locked in: generated modules are fully version-pinned baked artifacts (documented in README and MIGRATION.md). The optional softener this issue floated — a small public surface like
decode(Module, T, json)— was not built, so every future contract bump forces downstream regeneration. Coherent, but worth stating explicitly since 1.0 freezes it.
3. Documentation generation — MINIMUM MET. Spec
descriptions now flow into generated model docstrings (schema description plus a bullet per documented field) and operation docstrings (summary,METHOD /path, parameter/request-body bullets), for both client and server output. Hostile-content tests cover quotes,$,""", backslashes, and unicode, and generated output remains byte-deterministic. Verified live on a sample spec.The second ask — a markdown-docs emitter over
ClientPlan(thedocs/*.mdequivalent of the openapi-generator lane) — was not built. It should either get its own post-1.0 issue or be consciously dropped into the MIGRATION.md dropped-capabilities list; otherwise it silently freezes into "what the native path doesn't do", which is exactly what this issue warned about.4. Dropped capabilities stated — RESOLVED.
MIGRATION.mdnow covers the 0.2.x → 1.0 transition: the openapi-generator lane, client/server API mapping, dropped capabilities, and generated-artifact compatibility.Remaining before tag, in suggested order
- Cut
release-0.2from currentmain(time-sensitive, zero cost). - Decide the compat-pin approach for legacy generated code /
samples-julia.yaml. - Live server smoke test against a production-shaped spec (per the caveat in this issue's description).
- The package's own docs site: the PR removes
docs/and the docdeploy workflow entirely, sogh-pageswill keep serving 0.2 documentation for an API that no longer exists. Needs either a Documenter setup for the new API or a deliberate teardown/redirect. - Decide the markdown-docs emitter's fate (post-1.0 issue vs. documented as dropped).
- The upstream openapi-generator housekeeping PR (docs pointer, stale
julia.md,exportOperationsfix).
Cut
release-0.2frommainatd4471f3(== v0.2.8): https://github.com/JuliaComputing/OpenAPI.jl/tree/release-0.2. The branch runs CI on push, and its README/CONTRIBUTING now state that 0.2.x fixes target it whilemainhosts the 1.x rewrite. Item 1 of the proposal is done; remaining on the compat blocker is thesamples-julia.yamlpin / upstreamProject.tomlemission decision.Upstream housekeeping PR opened: OpenAPITools/openapi-generator#24789 — emits a compat'd
Project.tomlfrom both Julia generators (resolving the compat-breakage blocker at the source, per the decision above), repointssamples-julia.yamlfrom thev0.2.0tag torelease-0.2, fixes theexportOperationsconfig bug, documents the 0.2.x runtime boundary in generated READMEs, and deletes the staledocs/generators/julia.md. That completes item 2 of the proposal; the compat blocker closes when it merges.Stock-take before merging #103 (2026-08-27)
All four release blockers are now resolved:
- Compat breakage — closed by [julia] Emit Project.toml, track OpenAPI.jl release-0.2, fix exportOperations OpenAPITools/openapi-generator#24789 (merged): generated code ships a
Project.tomlpinningOpenAPI = "0.2", andsamples-julia.yamltests againstrelease-0.2(green on the PR twice and on the post-merge master push). - Runtime contract — contract stamp + load guard, positional-literal elimination, tripwire test; policy documented (baked artifacts).
- Documentation generation — spec descriptions flow into model/field/operation docstrings; the markdown-docs emitter is explicitly documented as dropped in MIGRATION.md's dropped-capabilities section, so it no longer freezes in silently.
- Dropped capabilities — stated in MIGRATION.md.
Proposal items:
release-0.2cut ✔, upstream housekeeping PR merged ✔, README/CONTRIBUTING routing updated onrelease-0.2(and #103 replaces both onmain) ✔.Still recommended before tagging v1.0.0 (from this issue's own caveat + review notes):
- The live server smoke test against a production-shaped spec — the server path has a full test suite but has not been exercised against a real service the way the client was.
- gh-pages: Pure-julia OpenAPI internals rewrite #103 removes
docs/and the docdeploy job, so the site will keep serving 0.2 docs against a 1.x package; needs a redirect/teardown or a minimal Documenter site at merge time. - Minor:
SHAis in Pure-julia OpenAPI internals rewrite #103's[deps]without a[compat]entry (the other stdlibs have one) — worth adding before registration to keep AutoMerge happy.
#103 itself is mergeable, up to date with
main(includes v0.2.8), CI green (Julia 1.10, Julia 1, corpus),version = "1.0.0", same package UUID.- Compat breakage — closed by [julia] Emit Project.toml, track OpenAPI.jl release-0.2, fix exportOperations OpenAPITools/openapi-generator#24789 (merged): generated code ships a
- added a commit that references this issue
on Aug 29, 2026 Server smoke test complete — all five findings from the live validation are fixed and up for review:
- Server smoke-test fixes: typed parameters, sequential JSON, undocumented success, external security schemes #108 (→
main): typed-parameter double decode (petstorefindByStatusreturned 400 on every call), buffered sequential-JSON array-vs-item handling, undocumented-success operations now answeringnothingwith an empty 200 plus a:missing_success_responseplanning warning, and permissive-mode tolerance for externally declared security schemes (strict still rejects). Validated by the full suite plus live petstore (same-lane and cross-lane with the unmodified 0.2 client), gap fixtures, and the unmodified JuliaHub secrets document end to end. - fix(client): keep form-style CSV separators literal in query strings #107 (→
release-0.2): the 0.2 client now serializes form-style CSV query parameters with literal separator commas per the OAS Style Examples/RFC6570, restoring interop with 1.x generated servers. Full 0.2 suite green with live servers (3080 tests); suggest tagging v0.2.9 on merge.
With these merged, the caveat on the server path is discharged; remaining before the v1.0.0 tag are only the gh-pages docs cleanup and the
SHAcompat entry.- Server smoke-test fixes: typed parameters, sequential JSON, undocumented success, external security schemes #108 (→
Docs update: #109 adds the Documenter manual for the 1.0 line (option A from the docs discussion) — 12-page manual, API reference with enforced public-name coverage, build-time-executed examples, CI deploy job, and a trimmed README. Also noted while investigating:
gh-pagescurrently serves v0.1.23 asstableand has no v0.2.x versioned docs at all (tag-triggered deploys silently stopped after v0.1.23); the preview deploy on #107 just succeeded, so the deploy key itself works. Merging #109 revivesdev, and tagging v1.0.0 / v0.2.9 will publish versioned docs and movestablecorrectly.Closing (2026-09-02)
Everything this issue set out to decide is done, and all four release blockers are verified against the live repo state:
- Blockers: compat breakage closed by [julia] Emit Project.toml, track OpenAPI.jl release-0.2, fix exportOperations OpenAPITools/openapi-generator#24789 (merged); runtime contract guard + docstrings landed in Pure-julia OpenAPI internals rewrite #103; dropped capabilities (including the markdown-docs emitter) stated in
MIGRATION.md. - Proposal items:
release-0.2cut and v0.2.9 tagged from it; upstream housekeeping PR merged; README onmainroutes 0.2.x users torelease-0.2andMIGRATION.md. - Server smoke-test caveat discharged by Server smoke-test fixes: typed parameters, sequential JSON, undocumented success, external security schemes #108 and fix(client): keep form-style CSV separators literal in query strings #107.
- Docs site: Documenter manual and docs deployment for 1.0 #109 merged;
devon gh-pages serves the 1.0 manual. - v1.0.0 tagged and registered in General (New version: OpenAPI v1.0.0 JuliaRegistries/General#166872).
Two loose ends found while verifying, neither a blocker:
- Tag-triggered docs deploys never fired. TagBot creates tags through the release API, so the
push: tagstrigger in CI never ran for v1.0.0 or v0.2.9 (zero workflow runs on either ref) and gh-pagesstablestill pointed at v0.1.23. This is also the root cause of the "deploys silently stopped after v0.1.23" observation above. Fixed today by re-pushing both tags from a user account (same tag objects, same commits) and re-publishing the GitHub releases that the tag re-push had reverted to drafts. Tag CI runs are in progress for v1.0.0 and v0.2.9; their docs jobs will publish versioned docs and movestable. Future tags will hit the same problem unless TagBot's ssh push actually triggers workflows — worth checking on the next release. SHAhas no[compat]entry inProject.tomlonmain. Cosmetic (stdlib; AutoMerge passed).
Nice-to-have (openapi-generator sample corpus as conformance fixtures) was not adopted and can get its own issue if wanted.
- Blockers: compat breakage closed by [julia] Emit Project.toml, track OpenAPI.jl release-0.2, fix exportOperations OpenAPITools/openapi-generator#24789 (merged); runtime contract guard + docstrings landed in Pure-julia OpenAPI internals rewrite #103; dropped capabilities (including the markdown-docs emitter) stated in
Context
#103 replaces the 0.2.x runtime-library model with a pure-Julia pipeline:
OpenAPI.client/OpenAPI.serverparse OAS 3.0/3.1/3.2 documents and emit generated modules directly, with no involvement from the openapi-generator Java toolchain. Today, however, this package's primary consumers are modules produced by openapi-generator'sjulia-client/julia-servertargets, whose templates call the public 0.2.x runtime API (OpenAPI.Clients,OpenAPI.Servers,validate_param,property_type, …) — an API that #103 removes entirely.This issue is to decide, before merge/tag, what happens to that lane. It is not a proposal to change the direction of #103 — the rewrite has been evaluated in depth against real workloads (including a full Kubernetes-client trial across 27 group documents) and the new pipeline wins on merit for 3.x work.
Evaluation status caveat: that depth applies to the client side. Server generation is present and symmetric (
OpenAPI.server/serverplan, aregister!(router, impl)contract deliberately shaped like the 0.2.x target'sregister, HTTP.Router support viaOpenAPIHTTPExt, and aserver_sourceseam for other frameworks) and has a substantial test suite — but it has not been exercised against a live production-shaped service the way the client was. A smoke test implementing one real spec (e.g. a JuliaHub runner spec) end to end should happen before the server path is declared ready.Why we should not try to bridge the two generators
The obvious "integration" — retargeting the openapi-generator mustache templates to emit #103-style code — is structurally unworkable:
_SPECdata and compiled schema information produced by the normalize→plan pipeline and the JSON Schema engine. Mustache templates render the JavaCodegenModel; reproducing this would mean reimplementingnormalize.jl+planning.jlin Java.oneOf/anyOftovalue::Any, emits hand-picked per-constraint validation call sites, and only wires parameter styling for query parameters. Pure-julia OpenAPI internals rewrite #103 produces typed unions and full schema-driven validation.A shell-out from the Java generator to Julia is against openapi-generator's pure-JVM architecture and would not be accepted upstream.
Proposal: clean split, with the legacy lane explicitly maintained
release-0.2maintenance branch before v1 is tagged. The openapi-generator targets, and every package currently built on them, keep tracking the 0.2.x runtime; recent fixes like fix(client): discard truncated JSON document on mid-stream EOF #97–fix(client): :http streaming stalls small chunks until 8KB buffer fills #102 show this lane still needs a home for backports.julia-client/julia-servertrack OpenAPI.jl 0.2.x and point Julia-native users atOpenAPI.client/OpenAPI.server; delete the staledocs/generators/julia.md(advertises an unregisteredjuliagenerator); fix theexportOperationsconfig bug inJuliaClientCodegen.java(the flag writes throughexportModels, so the two options aren't separable).Release blockers to resolve before tagging 1.0
Project.toml, so openapi-generator'ssamples-julia.yamlCI and any fresh environment doingPkg.add("OpenAPI")against legacy generated code will resolve to 1.x and fail on the missingOpenAPI.Clients. Options: pinOpenAPI = "0.2"in that workflow and have the upstream generator emit a compat'dProject.toml; or release the rewrite under a new package name. Worth deciding deliberately rather than discovering via broken CI.OpenAPI.Runtimeinternals (_decode/_encode), so they are version-coupled to the exact OpenAPI release that generated them. That's acceptable policy for baked artifacts, but it should be documented, and a small public surface (e.g.decode(Module, T, json)) would soften it — once 1.0 tags, this contract freezes.docs/*.md) plus a usageREADME.md; Pure-julia OpenAPI internals rewrite #103 emits none of that. Generated client operations do get Julia docstrings (signature + specsummary+METHOD /path), but models get no docstrings at all — schema and propertydescriptionfields from the spec are dropped entirely, and in large specs those descriptions are most of the documentation value. Two asks, both cheap relative to the pipeline work already done: carrydescriptionthrough to model/field docstrings at emission time, and offer a markdown-docs emitter as a separate function over the sameClientPlan. At minimum the first should land before 1.0; otherwise this freezes into the "what the native path doesn't do" list.Nice-to-have