Generate a protobuf schema artifact from ElasticGraph schemas - #1080
Conversation
2e0e4a1 to
53ea492
Compare
a3cfa5c to
9e6f39a
Compare
4325d51 to
fd8dd47
Compare
9e6f39a to
c408a50
Compare
fd8dd47 to
bdce7fb
Compare
c408a50 to
5717334
Compare
0607029 to
40815e1
Compare
6591c29 to
751db75
Compare
b2e8d34 to
6969f84
Compare
7d428d5 to
9acfed5
Compare
9acfed5 to
4fe8938
Compare
4fe8938 to
474788d
Compare
474788d to
bcc30c1
Compare
Moves `field.renamed_from`, `type.renamed_from`, `type.deleted_field`, and `schema.deleted_type` — along with the state registries and `DeprecatedElement` record they populate — from `elasticgraph-json_ingestion` back into the core schema definition gem, partially reverting the placement chosen in #1259. These declarations record serializer-neutral facts about how a schema has evolved, and we now have a second consumer: `elasticgraph-proto_ingestion` (#1080) needs rename metadata to keep protobuf field numbers stable across renames (with `reserved` field numbers for deletions as a natural follow-up). Keeping the markers inside one serializer forced other consumers to duck-type against state that may or may not be present; with the declarations in core, every consumer reads typed `State` members directly. This also addresses the concern raised in review of #1259 about `elasticgraph-json_ingestion` bolting 9 fields onto `::ElasticGraph::SchemaDefinition::State`: its `StateExtension` now adds only the 5 genuinely JSON-specific fields, and the four deprecation registries are ordinary typed `State` members that need no `State & StateExtension` casts. All JSON-specific behavior — schema version enforcement, merge reporting, pruning, and the warnings that flag no-longer-needed declarations — stays in `elasticgraph-json_ingestion`. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
98f82ce to
683be9a
Compare
myronmarston
left a comment
There was a problem hiding this comment.
Not done reviewing but wanted to submit what I have so far.
myronmarston
left a comment
There was a problem hiding this comment.
Still not done with my review but want to submit what I have so far.
One thing I haven't seen is something which verifies that the proto schema we produce is a valid proto schema--e.g. a test which parses a proto.schema file we generate using the google-protobuf gem, demonstrating that we generate valid protos. (For now, it just looks like we do but I can't say for sure that it's valid!).
One idea--maybe in a followup PR you can wire this up with the test schema (similar to the warehouse artifact) and then you can add a test to the test suite that verifies that the generated proto schema from our main test schema is valid? I'm open to other ideas here...
Fill in elasticgraph-proto_ingestion with proto schema generation for indexed types. Map built-in and custom scalars, render concrete and abstract types, preserve public field names, and generate enum defaults. Reject unrepresentable lists and unstable identifier collisions with actionable schema errors.
myronmarston
left a comment
There was a problem hiding this comment.
Finally made it through the entire PR! I'm hoping this is the last round of feedback.
There was a problem hiding this comment.
One other thing I just noticed: the tests generate a few warnings which dirty up the output. Can we change the tests that generate these warnings (so they no longer generate them) without impacting what they cover?
$ be rspec elasticgraph-proto_ingestion/spec
Randomized with seed 37739
.........WARNING: Since a `Account.count` field exists, ElasticGraph is not able to
define its typical `AccountFieldsListFilterInput.count` field, which allows clients to filter on the count
of values for a `[Account]` field. Clients will still be able to filter on the `count`
at a leaf field path. However, there are a couple ways this naming conflict can be avoided if desired:
1. Pick a different name for the `Account.count` field.
2. Change the name used by ElasticGraph for this field. To do that, pass a
`schema_element_name_overrides: {"count" => "alt_name"}` option alongside
`schema_element_name_form: ...` when defining `ElasticGraph::SchemaDefinition::RakeTasks`
(typically in the `Rakefile`).
...............Object types must have fields, but Query doesn't have any. Define a field for this type, remove it from your schema, or add `has_no_fields(true)` to its definition.
This will raise an error in a future GraphQL-Ruby version.
.......
myronmarston
left a comment
There was a problem hiding this comment.
Well done! Using the dot-prefixed FQN form to avoid naming collisions is a really nice approach. I'm really happy with how we landed on this.
Left some non-blocking feedback. Use your judgement about which things to address and feel free to address them in a followup PR. (Frankly, I'd prefer that as it would be a smaller diff to go through!).
Note
First of a four-PR stack. Supporting changes merged earlier (#1296 artifact comment prefixes, #1297 gem scaffold), so this diff is contained entirely to the
elasticgraph-proto_ingestiondirectory. Per review feedback the original PR has been split: wire-stable field/enum-value numbering, proto2 + custom headers, and enum sourcing/external references are now stacked follow-ups.Why
What
elasticgraph-proto_ingestionextension gem with core generation:schema_artifacts:dumpemits aproto3schema.protocovering the schema's indexed typest.protobuf type:for custom scalars (resolved viatype_ref.with_reverted_overrideso built-ins renamed withtype_name_overrideskeep working)*_UNSPECIFIEDentry), escaping proto reserved words and wrapping lists of lists so the output stays validschema.protoon public GraphQL field names; validate proto package namesProtoIngestionStatecontainer behind a singleproto_ingestion_statereader (matching Group JSON ingestion schema state #1281)Field and enum value numbers are assigned sequentially in definition order in this PR; the stacked follow-up adds the
proto_field_numbers.yamlsidecar that keeps them wire-stable across schema evolution.Stacked follow-ups
schema.protogenerationproto_field_numbers.yamlsidecarsyntax: :proto2support and custom file-levelheaders:Verification
script/run_gem_specs elasticgraph-proto_ingestion(100% line + branch coverage at this commit)script/type_check,script/lint,script/spellcheckscript/quick_buildgreen at the stack head (whose tree is identical to the previously reviewed single-PR revision)References
Update — 2026-07-10
Update — 2026-07-15
oneof, matching the JSON SchemaoneOfrepresentation.__typenamediscriminator.Update — 2026-07-19
protoc35.1.