Skip to content

ci: add Dependabot for GitHub Actions updates#17

Open
reuvenharrison wants to merge 110 commits into
masterfrom
ci-dependabot-actions
Open

ci: add Dependabot for GitHub Actions updates#17
reuvenharrison wants to merge 110 commits into
masterfrom
ci-dependabot-actions

Conversation

@reuvenharrison

Copy link
Copy Markdown

Adds a github-actions Dependabot ecosystem (weekly, grouped) so action versions bump automatically. The repo had no Dependabot config; e.g. actions/checkout@v2 and actions/cache@v3 had drifted behind latest.

fenollp and others added 30 commits April 19, 2026 12:06
Signed-off-by: Pierre Fenoll <pierrefenoll@gmail.com>
Signed-off-by: Pierre Fenoll <pierrefenoll@gmail.com>
Signed-off-by: Pierre Fenoll <pierrefenoll@gmail.com>
Signed-off-by: Pierre Fenoll <pierrefenoll@gmail.com>
Signed-off-by: Pierre Fenoll <pierrefenoll@gmail.com>
…ed refs

Signed-off-by: Pierre Fenoll <pierrefenoll@gmail.com>
Signed-off-by: Pierre Fenoll <pierrefenoll@gmail.com>
Signed-off-by: Pierre Fenoll <pierrefenoll@gmail.com>
Signed-off-by: Pierre Fenoll <pierrefenoll@gmail.com>
Signed-off-by: Pierre Fenoll <pierrefenoll@gmail.com>
Add comprehensive OpenAPI 3.1 / JSON Schema 2020-12 support:

- Type arrays with null support (e.g., ["string", "null"])
- JSON Schema 2020-12 keywords: const, examples, prefixItems, contains,
  minContains, maxContains, patternProperties, dependentSchemas,
  propertyNames, unevaluatedItems, unevaluatedProperties
- Conditional keywords: if/then/else, dependentRequired
- ExclusiveBound union type for 3.0 (boolean) and 3.1 (numeric) exclusive bounds
- Webhooks support with $ref resolution
- Version detection helpers: IsOpenAPI3_0(), IsOpenAPI3_1()
- Info.Summary and License.Identifier fields
- JSON Schema 2020-12 validator via EnableJSONSchema2020()
- Document-level validation option: EnableJSONSchema2020Validation()
- Allow $ref alongside other keywords in 3.1 schemas
- Handle "null" type in schema validation
- Auto-detect 3.1 in cmd/validate

Co-Authored-By: Chance Kirsch <>
Co-Authored-By: RobbertDM <>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…, etc.)

The loader's resolveSchemaRef only resolved $ref in pre-3.1 fields (items,
properties, additionalProperties, not, allOf, anyOf, oneOf). References
inside the new OpenAPI 3.1 / JSON Schema 2020-12 fields were silently
left unresolved, causing nil Value pointers.

This adds ref resolution for: prefixItems, contains, patternProperties,
dependentSchemas, propertyNames, unevaluatedItems, unevaluatedProperties.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The OpenAPI-to-JSON-Schema transformation only recursed into pre-3.1
fields (properties, additionalProperties, items, not, oneOf, anyOf,
allOf). Nested schemas inside 3.1 fields with OpenAPI 3.0-isms like
nullable:true were not converted, causing incorrect validation.

This adds recursion into: prefixItems, contains, patternProperties,
dependentSchemas, propertyNames, unevaluatedItems,
unevaluatedProperties.

Also consolidates the properties/patternProperties/dependentSchemas
map iteration into a single loop.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Schema.Validate() (used by doc.Validate()) recursively validates
sub-schemas in Items, Properties, AdditionalProperties, etc. but did
not recurse into the new OpenAPI 3.1 / JSON Schema 2020-12 fields.
Invalid sub-schemas nested inside these fields went undetected.

This adds validation for: prefixItems, contains, patternProperties,
dependentSchemas, propertyNames, unevaluatedItems,
unevaluatedProperties.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Make paths optional in 3.1 (required only in 3.0)
- Add mutualTLS security scheme type validation
- Validate license url/identifier mutual exclusivity
- Enable JSON Schema 2020-12 validation in openapi3filter for 3.1 docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add $id, $anchor, $dynamicRef, $dynamicAnchor identity keywords
- Add contentMediaType, contentEncoding, contentSchema vocabulary
- Add discriminator support for anyOf (was only oneOf)
- Validate jsonSchemaDialect as valid URI

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- IsEmpty(): add missing checks for PrefixItems, Contains, MinContains,
  MaxContains, PatternProperties, DependentSchemas, PropertyNames,
  UnevaluatedItems, UnevaluatedProperties, Examples
- JSONLookup(): add all 23 missing JSON Schema 2020-12 field cases
- validate(): relax items requirement for arrays when in 3.1 mode or
  when prefixItems is present
- transformOpenAPIToJSONSchema: clean up exclusiveMinimum/Maximum false,
  handle nullable:true without type field
- MarshalYAML: only emit paths when non-nil (valid in 3.1)
- visitConstOperation: use reflect.DeepEqual for json.Number comparison
- Webhooks validation: use componentNames() for deterministic ordering

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rephrase text to not contain literal json struct tag syntax that
triggers the json/yaml tag consistency check.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Open issues are tracked in the PR getkin#1125 description instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add $comment keyword to Schema struct (MarshalYAML, UnmarshalJSON,
  IsEmpty, JSONLookup)
- Fix PrefixItems type from []*SchemaRef to SchemaRefs for consistency
  with OneOf/AnyOf/AllOf and JSON Pointer support
- Fix exclusiveBoundToBool data loss: preserve numeric bound value
  when converting OAS 3.1 exclusive bounds to OAS 2.0
- Auto-enable JSON Schema 2020-12 validation for OpenAPI 3.1 documents
  in doc.Validate() so library users don't need explicit opt-in
- Add ref resolution tests for if/then/else and contentSchema
- Add transform test for contentSchema with nullable nested schema
- Add validate test for contentSchema with invalid sub-schema
- Document breaking API changes in README (ExclusiveBound, PrefixItems)
- Regenerate docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add $schema keyword to Schema struct for per-schema dialect declaration
- Add $defs keyword (Schemas map) for local reusable schema definitions,
  with full support: struct, marshal, unmarshal, IsEmpty, JSONLookup,
  validate (recurse), loader (resolve refs), transform (recurse)
- Fix jsonSchemaDialect URI validation to require a scheme
- Refactor discriminator resolution into shared helper to eliminate
  code duplication between oneOf and anyOf paths
- Regenerate docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
OpenAPI 3.1 adds Const (any) and Examples ([]any) fields to Schema.
Like Enum/Default/Example, these can contain arbitrary JSON/YAML values
that pick up __origin__ metadata from the YAML loader. Strip it on
unmarshal to prevent false diffs and unexpected metadata in parsed values.

Adds TestOrigin_ConstAndExamplesStripped regression test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The origin-tracking YAML loader injects __origin__ as a key inside
any map-valued field to record source location. However, typed Go maps
(map[string]*Encoding, map[string]*ServerVariable, map[string]*PathItem)
treat __origin__ as a real entry, causing false positive diffs when the
same spec is loaded from two different file paths.

Fix by deleting originKey from these three maps after JSON unmarshaling,
mirroring the existing pattern used for Extensions and the unmarshalStringMapP
helper already used by Content, Schemas, Headers, etc.

Affected:
- MediaType.Encoding (map[string]*Encoding)
- Server.Variables (map[string]*ServerVariable)
- T.Webhooks (map[string]*PathItem)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
In OpenAPI 3.0 / JSON Schema draft-07, $ref replaces its entire object
so sibling keywords are silently ignored. In OpenAPI 3.1 / JSON Schema
2020-12, $ref and sibling keywords are both applied.

Changes:
- SchemaRef gains a `sibling *Schema` field (generated via refs.tmpl)
- UnmarshalJSON populates sibling when non-extension fields appear
  alongside $ref
- resolveSchemaRef applies sibling fields onto a copy of the resolved
  schema, but only for OAS 3.1+ documents (preserves 3.0 behaviour)
- applySiblingSchemaFields overlays known annotation/metadata fields
  (deprecated, description, title, readOnly, writeOnly, example,
  externalDocs, default) using the extra[] field list so only explicitly
  present siblings are applied

Test: TestOAS31_RefSiblingKeyword in loader_31_schema_refs_test.go loads
a 3.1 spec where status has deprecated:true as a $ref sibling and asserts
that the resolved Value carries Deprecated==true.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
refs.go header changed from "Code generated by go generate; DO NOT EDIT."
to "Code generated by go generate using refs.tmpl; DO NOT EDIT refs.go."
Update the committed go doc snapshot to match.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
brandonbloom and others added 30 commits May 4, 2026 21:51
Co-authored-by: Tommy Nacass <tommy.nacass@gmail.com>
…eld pairs

Converts four mutual-exclusion sites:
- example.value vs externalValue
- mediaType.example vs examples
- license.url vs identifier
- link.operationId vs operationRef
…ields

Converts four 'field MUST NOT be set in this context' sites:
- header.name (given by the headers map key)
- header.in (implicitly 'header')
- OAuth flow authorizationUrl (wrong flow type)
- OAuth flow tokenUrl (wrong flow type)
…e failures

Converts three server URL template sites:
- mismatched { and }
- undeclared variables (template/Variables count mismatch)
- undeclared variables (declared name not in URL template)
…red leaf

- example.value or externalValue
- link.operationId or operationRef
- schema.items required when type=array (RequiredFieldError leaf)
… jsonSchemaDialect URI

Three new RequiredFieldError leaves at the doc-validation root:
- info (must be an object)
- paths (must be an object — 3.0 only)
- jsonSchemaDialect (must be an absolute URI with a scheme)
…ma fields set both ways

Three sites in schema.go where a BoolSchema-typed field has both forms set:
- additionalProperties
- unevaluatedItems
- unevaluatedProperties
…rs for parameter/header content+schema

Four sites:
- parameter.go content/schema must be exactly one
- parameter.go content map must contain at most one entry
- header.go content/schema must be exactly one
- header.go content map must contain at most one entry
…k walk

Single-site cluster carrying the offending webhook key name.
Anonymous nested struct types have an empty reflect.Type.Name(), so
generateTypeName returns "". Registering them under that key produces
"#/components/schemas/" refs that violate the OpenAPI spec (component
keys must match ^[a-zA-Z0-9._-]+$) and break codegen tools like Orval.
Inline the schema instead, matching the existing behavior for generics
and time.Time.
…sableTimestamps

Bumps:
  * github.com/oasdiff/yaml         v0.0.9  -> v0.1.0
  * github.com/oasdiff/yaml3        v0.0.12 -> v0.0.13

yaml v0.1.0 consolidates three unmarshal entry points (Unmarshal,
UnmarshalWithOriginTree, UnmarshalWithDecodeOpts) into a single
Unmarshal with the signature:

    Unmarshal(y []byte, o interface{}, decode DecodeOpts, opts ...JSONOpt) (*OriginTree, error)

DecodeOpts carries Origin (tracking) and DisableTimestamps (YAML 1.1
implicit-timestamp resolution opt-out, backed by yaml3 v0.0.13).

This PR migrates every yaml.Unmarshal / yaml.UnmarshalWithOriginTree
call site (4 production sites + 8 test sites) to the new signature,
setting DisableTimestamps: true everywhere. Real-world OpenAPI specs
use date-shaped strings as map keys (e.g. revision dates like
"1344-08-22") which the YAML 1.1 default resolves to time.Time —
that resolution is the root cause of validation errors that surface
as misleading time.Time-stringified values in error messages, and
in some cases breaks string-keyed lookup entirely.

Testdata golden files in openapi3/testdata/apis_guru_openapi_directory/
regenerated by the existing golden helper:
  * Several previously-failing specs now validate cleanly (golden
    files removed by the helper's os.Remove path).
  * Others show updated error messages where date-shaped scalars no
    longer appear as stringified time.Time.

`go test ./...` clean across all packages.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Pierre Fenoll <pierrefenoll@gmail.com>
Signed-off-by: Pierre Fenoll <pierrefenoll@gmail.com>
Signed-off-by: Pierre Fenoll <pierrefenoll@gmail.com>
)

* feat(openapi3): typed context errors for Validate() wrapper chain

Replaces the 14 fmt.Errorf wrap sites in Validate() with three typed
error types carrying their context as structured fields:

- SectionContextError{Section, Cause}    — wraps an error inside one of
  the top-level document sections (info, paths, components, security,
  servers, tags, externalDocs, webhooks, jsonSchemaDialect)
- PathContextError{Path, Cause}          — wraps an error inside a
  specific path
- OperationContextError{Method, Cause}   — wraps an error inside a
  specific HTTP-method operation

Continues the typed-validation-error work from getkin#1166 and getkin#1180:
those PRs typed the leaf errors; this one types the wrapper layers
that carry doc-tree position around them.

Why: today, callers that want to render context separately (which
section a finding lives in, which path, which operation) have to
parse the rendered error string with regex. errors.As against typed
wrappers is the structured equivalent.

Backward compatibility: Error() strings are byte-identical to the
fmt.Errorf wrappers they replace. Existing consumers parsing the
rendered text continue to work unchanged. The typed extraction is
purely additive.

Wrap sites converted:
- openapi3.go: 9 sections (info, paths, components, security,
  servers, tags, externalDocs, webhooks, jsonSchemaDialect)
- paths.go: per-path wrapper (PathContextError)
- path_item.go: per-operation wrapper (OperationContextError)
- operation.go, tag.go, schema.go: 3 additional externalDocs sites
  (also use SectionContextError{Section: "external docs"})

Tests cover Error() format byte-stability, Unwrap chain walking,
errors.As extraction from a three-layer chain (section + path +
operation), and arbitrary non-typed inner causes. All existing
tests pass unchanged across openapi2, openapi3, openapi3conv,
openapi3filter, openapi3gen, and the routers — confirming the
rendered strings are stable.

.github/docs/openapi3.txt regenerated via docs.sh.

* refactor(openapi3): rename context errors to *ValidationError

Addresses review feedback on getkin#1183:

- SectionContextError    -> SectionValidationError
- PathContextError       -> PathValidationError
- OperationContextError  -> OperationValidationError

The new names tie these positional wrappers to the ValidationError
family they belong to (base ValidationError, cluster types, leaves).

Also renames the file to sit in that namespace:
section_context_error.go -> validation_error_context.go (+ _test.go).

No behavior change: Error() strings and Unwrap() chains are untouched.
.github/docs/openapi3.txt regenerated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Pierre Fenoll <pierrefenoll@gmail.com>
getkin#1185)

* openapi3: aggregate independent validation errors via EnableMultiError

Today Validate returns the first error it encounters and stops, so a
spec with several independent defects only reports one at a time: fix,
re-run, see the next, repeat. With the new EnableMultiError
ValidationOption, container validators aggregate independent problems
and return them together as a flat MultiError.

Aggregation happens at the container fan-out points where it is safe
to continue past an error: T, Paths, PathItem, Operation, Components,
Responses. Leaf validators (Schema, Info, Server, etc.) still fail
fast, since continuing past a leaf error can hit a nil deref.

The result shape is flat: each top-level MultiError entry is one
fully-wrapped chain (SectionValidationError -> PathValidationError ->
OperationValidationError -> typed leaf). Consumers iterating the
MultiError get one entry per problem; consumers using errors.As /
errors.Is work unchanged thanks to MultiError.As / MultiError.Is.

By default Validate returns the first error encountered, byte-identical
to today: the existing test suite passes through the same code path it
always did.

* openapi3: keep "return validateExtensions" pattern in container validators

CI greps for "return .*validateExtensions" in openapi3/ and asserts the
count equals the number of Extensions fields. The previous commit moved
those calls to "me.emit(validateExtensions(...))" + "return me.result()",
breaking the count.

Add a finalize helper on errCollector that emits its argument and returns
the accumulated result, so each container's trailing line is a single
"return me.finalize(validateExtensions(ctx, X.Extensions))" that both
reads cleanly and matches the CI fence regex.

* openapi3: address review feedback on EnableMultiError

Top-level:
 - cmd/validate: add --multi flag (mirrors --defaults / --examples / --patterns)
 - Convert simple leaves to aggregate independent errors: License, Info,
   Server (singular + plural), Tag (singular + plural), ExternalDocs.
   Each is sequential independent checks with no guard-then-deref pattern,
   structurally identical to the existing container validators. Schema,
   Parameter, MediaType have internal cross-field dependencies and are left
   for follow-up PRs after per-method analysis.
 - Rewrite EnableMultiError docstring: drop the explicit fan-out list (would
   go stale), name the transition explicitly, explain why some leaves are
   not yet converted, and replace the generic errors.As / errors.Is note
   with a concrete how-to.

Inline:
 - validate_multi_error_test.go: use require.ErrorContains for chain checks;
   tighten GreaterOrEqual to Equal where the count is exact.
 - response.go: route Responses.Validate's empty-responses error through
   me.emit for consistency with the rest of the multi-error path.
 - components.go, paths.go, openapi3.go: add comments at the error-path
   continue statements explaining why we skip descending past a malformed
   parent key (component name, path key, nil webhook).
 - error_collector.go (new): move the errCollector type and methods out of
   validation_options.go so the options file stays focused on options.
 - openapi3.go: revert to the wrap-variable reassignment pattern per
   section block; keep wrapSection as the factory.

* test: hoist err.Error() out of require.Equal to satisfy CI grep fence

* openapi3: wrap plural examples Validate errors in newSchemaValueError

Parameter.Validate and MediaType.Validate already use newSchemaValueError
for the singular `example:` field, but the plural `examples:` map loop
returned a bare fmt.Errorf wrapping the underlying *SchemaError. That
meant errors.As(err, &SchemaValueError) didn't match for plural examples,
so downstream consumers fell back to a generic catch-all instead of
recognising the example-violates-schema cluster.

Wrap the plural-loop result in newSchemaValueError("example", ...) too,
preserving the example key inside the wrap so the rendered message still
names the offending example. Aligns the plural path with the singular
path; both now surface as *SchemaValueError to errors.As consumers.

Existing example_validation_test.go assertions and the apis_guru golden
fixtures gain the "invalid example: " prefix the wrap adds.

* openapi3: point Examples Validate failures at the example's value, not the parent

For plural Examples entries on Parameter/MediaType, the Validate failure
used the parent struct's Origin, which deep-links to the parameter or
media-type start (e.g. the `in: query` line) rather than the offending
example value. Build the SchemaValueError's Origin from the Example
struct's per-field origin (`Origin.Fields["value"]`) when available,
falling back to the example's struct origin, then to the parent.

No message-format change: existing string assertions continue to hold,
only the resolved line/column tightens to the example's `value:` field.

* openapi3: keep validating extensions when responses is empty

The empty-responses path used 'return me.result()' which short-circuited
before validateExtensions could run, so extension errors would never
aggregate with the empty-responses finding under multi mode. Drop the
early return and let control fall through to the trailing finalize() call;
the for loop is a no-op on an empty Responses, so the only behaviour
change is that validateExtensions now runs.

Spotted by @fenollp in PR review.

* test: regression pin for the empty-responses + extension aggregation fix

Adds TestResponses_Validate_EmptyAndExtensionAggregate which constructs
an empty Responses with a non-x- sibling on Extensions and asserts both
findings surface under EnableMultiError. Reverting the previous commit's
fall-through edit causes this test to fail (one leaf instead of two).
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants