Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
6c51416
chore: Update golangci and fix issues it found
BlakeTheAwesome Sep 25, 2025
ee2f0a2
feat: add support for 3.2.0 openapi spec
BlakeTheAwesome Sep 26, 2025
87dc8d0
fix mise CI test
BlakeTheAwesome Sep 26, 2025
5f0f350
Update walkapi to support 3.2 additionalOperations
BlakeTheAwesome Sep 29, 2025
77282cc
Add inline/bundling tests for additional operations
BlakeTheAwesome Sep 29, 2025
79a5a47
Fixup walk example test
BlakeTheAwesome Oct 2, 2025
b79f07f
Added support for 3.2 tags
BlakeTheAwesome Sep 29, 2025
fd2a04c
Added upgrade path for 3.2 additionalOperations
BlakeTheAwesome Oct 1, 2025
f5724d6
Add x-tag-groups migration code
BlakeTheAwesome Oct 2, 2025
9581e4a
Added support for querystring operation parameters
BlakeTheAwesome Oct 3, 2025
47b5b0b
Merge branch 'main' into blake/spec-3.2
TristanSpeakEasy Dec 8, 2025
320d1fe
fix: address pr feedback
TristanSpeakEasy Dec 8, 2025
982d09a
feat: add support for itemSchema to media type
TristanSpeakEasy Dec 8, 2025
9fd73f8
fix
TristanSpeakEasy Dec 8, 2025
6c07e23
feat: add prefixEncoding and itemEncoding support for OpenAPI 3.2 mul…
TristanSpeakEasy Dec 9, 2025
5244755
docs: add git commit conventions to AGENTS.md
TristanSpeakEasy Dec 9, 2025
c6523ef
feat: add OpenAPI 3.2 security enhancements including OAuth2 device a…
TristanSpeakEasy Dec 9, 2025
a9538df
feat: add OpenAPI 3.2 discriminator defaultMapping support
TristanSpeakEasy Dec 9, 2025
3588c15
fix
TristanSpeakEasy Dec 9, 2025
0d3754e
feat: add dataValue and serializedValue support to Example Object for…
TristanSpeakEasy Dec 9, 2025
565859f
feat: add name field to Server Object for OpenAPI 3.2
TristanSpeakEasy Dec 9, 2025
456661f
feat: add field support for OpenAPI 3.2 with reference resolution
TristanSpeakEasy Dec 9, 2025
627ba02
fix
TristanSpeakEasy Dec 9, 2025
1dfde02
Merge branch 'main' into blake/spec-3.2
TristanSpeakEasy Dec 9, 2025
284590b
fix
TristanSpeakEasy Dec 9, 2025
948b2bd
docs: update documentation to reflect OpenAPI 3.2.0 support
TristanSpeakEasy Dec 9, 2025
3c38b5f
docs: update remaining version references from 3.1.x to 3.2.0
TristanSpeakEasy Dec 9, 2025
59a527f
fix: prevent file content disclosure in validation error messages
TristanSpeakEasy Dec 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ jobs:

- name: Install mise
uses: jdx/mise-action@v3
with:
experimental: true

- name: Setup Go with caching
uses: actions/setup-go@v6
Expand Down
6 changes: 3 additions & 3 deletions .mise.toml
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
[tools]
go = "1.24.3"
golangci-lint = "2.1.1"
gotestsum = "latest"

[tasks.setup-vscode-symlinks]
description = "Create VSCode symlinks for tools not automatically handled by mise-vscode"
run = [
"mkdir -p .vscode/mise-tools",
"ln -sf $(mise exec -- which golangci-lint-v2) $(dirname $(mise exec -- which golangci-lint-v2))/golangci-lint || true",
"ln -sf $(mise exec -- which golangci-lint) .vscode/mise-tools/golangci-lint",
"ln -sf $(mise exec [email protected] -- which golangci-lint) .vscode/mise-tools/golangci-lint",
]

[hooks]
postinstall = [
"ln -sf ./AGENTS.md ./CLAUDE.md",
"git submodule update --init --recursive",
"mise exec [email protected] -- go install github.com/golangci/golangci-lint/v2/cmd/[email protected]",
"mise run setup-vscode-symlinks",
"go install go.uber.org/nilaway/cmd/nilaway@8ad05f0",
]
48 changes: 48 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,54 @@ mise test -count=1 ./...
- **Race Detection**: Automatically enables race detection to catch concurrency issues
- **Submodule Awareness**: Checks for and warns about uninitialized test submodules

## Git Commit Conventions

**Always use single-line conventional commits.** Do not create multi-line commit messages.

### Commit Message Format

```
<type>: <description>
```

### Common Types

- `feat:` - New feature
- `fix:` - Bug fix
- `docs:` - Documentation changes
- `refactor:` - Code refactoring
- `test:` - Adding or updating tests
- `chore:` - Maintenance tasks
- `perf:` - Performance improvements

### Examples

#### ✅ Good: Single-line conventional commits

```bash
git commit -m "feat: add prefixEncoding and itemEncoding support for OpenAPI 3.2 multipart media types"
git commit -m "fix: correct validation logic for encoding field mutual exclusivity"
git commit -m "test: add comprehensive tests for multipart encoding validation"
git commit -m "refactor: simplify media type context passing in validation"
```

#### ❌ Bad: Multi-line commits

```bash
git commit -m "feat: implement prefixEncoding and itemEncoding for OpenAPI 3.2

- Add PrefixEncoding and ItemEncoding fields to MediaType
- Implement validation for mutual exclusivity
- Add comprehensive tests"
```

### Why Single-Line Commits?

1. **Simplicity**: Easy to read in git log and GitHub UI
2. **Consistency**: All commits follow the same pattern
3. **Searchability**: Easier to search and filter commits
4. **Tool Compatibility**: Works better with automated tools and scripts

## Testing

Follow these testing conventions when writing Go tests in this project. Run newly added or modified test immediately after changes to make sure they work as expected before continuing with more work.
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<!-- OpenAPI Hub Badge -->
<a href="https://www.speakeasy.com/openapi"><img alt="OpenAPI Hub" src="https://www.speakeasy.com/assets/badges/openapi-hub.svg" /></a>
<!-- OpenAPI Support Badge -->
<a href="https://www.speakeasy.com/openapi"><img alt="OpenAPI Support" src="https://img.shields.io/badge/OpenAPI-3.0%20%7C%203.1-85EA2D.svg?style=for-the-badge&logo=openapiinitiative"></a>
<a href="https://www.speakeasy.com/openapi"><img alt="OpenAPI Support" src="https://img.shields.io/badge/OpenAPI-3.0%20%7C%203.1%20%7C%203.2-85EA2D.svg?style=for-the-badge&logo=openapiinitiative"></a>
<!-- Arazzo Support Badge -->
<img alt="Arazzo Support" src="https://img.shields.io/badge/Arazzo-1.0-purple.svg?style=for-the-badge">
<a href="https://pkg.go.dev/github.com/speakeasy-api/openapi?tab=doc"><img alt="Go Doc" src="https://img.shields.io/badge/godoc-reference-blue.svg?style=for-the-badge"></a>
Expand Down Expand Up @@ -68,7 +68,7 @@ The `arazzo` package provides an API for working with Arazzo documents including

### [openapi](./openapi)

The `openapi` package provides an API for working with OpenAPI documents including reading, creating, mutating, walking, validating and upgrading them. Supports both OpenAPI 3.0.x and 3.1.x specifications.
The `openapi` package provides an API for working with OpenAPI documents including reading, creating, mutating, walking, validating and upgrading them. Supports OpenAPI 3.0.x, 3.1.x, and 3.2.x specifications.

### [swagger](./swagger)

Expand Down
21 changes: 12 additions & 9 deletions arazzo/arazzo.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/speakeasy-api/openapi/arazzo/core"
"github.com/speakeasy-api/openapi/extensions"
"github.com/speakeasy-api/openapi/internal/interfaces"
"github.com/speakeasy-api/openapi/internal/utils"
"github.com/speakeasy-api/openapi/internal/version"
"github.com/speakeasy-api/openapi/jsonschema/oas3"
"github.com/speakeasy-api/openapi/marshaller"
"github.com/speakeasy-api/openapi/pointer"
Expand All @@ -20,10 +20,12 @@ import (

// Version is the version of the Arazzo Specification that this package conforms to.
const (
Version = "1.0.1"
VersionMajor = 1
VersionMinor = 0
VersionPatch = 1
Version = "1.0.1"
)

var (
MinimumSupportedVersion = version.MustParse("1.0.0")
MaximumSupportedVersion = version.MustParse(Version)
)

// Arazzo is the root object for an Arazzo document.
Expand Down Expand Up @@ -105,13 +107,14 @@ func (a *Arazzo) Validate(ctx context.Context, opts ...validation.Option) []erro
core := a.GetCore()
errs := []error{}

arazzoMajor, arazzoMinor, arazzoPatch, err := utils.ParseVersion(a.Arazzo)
arazzoVersion, err := version.Parse(a.Arazzo)
if err != nil {
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("arazzo.version is invalid %s: %s", a.Arazzo, err.Error()), core, core.Arazzo))
}

if arazzoMajor != VersionMajor || arazzoMinor != VersionMinor || arazzoPatch > VersionPatch {
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("arazzo.version only %s and below is supported", Version), core, core.Arazzo))
if arazzoVersion != nil {
if arazzoVersion.GreaterThan(*MaximumSupportedVersion) {
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("arazzo.version only Arazzo versions between %s and %s are supported", MinimumSupportedVersion, MaximumSupportedVersion), core, core.Arazzo))
}
}

errs = append(errs, a.Info.Validate(ctx, opts...)...)
Expand Down
2 changes: 1 addition & 1 deletion arazzo/arazzo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ sourceDescriptions:
underlyingError error
}{
{line: 1, column: 1, underlyingError: validation.NewMissingFieldError("arazzo.workflows is missing")},
{line: 1, column: 9, underlyingError: validation.NewValueValidationError("arazzo.version only 1.0.1 and below is supported")},
{line: 1, column: 9, underlyingError: validation.NewValueValidationError("arazzo.version only Arazzo versions between 1.0.0 and 1.0.1 are supported")},
{line: 4, column: 3, underlyingError: validation.NewMissingFieldError("info.version is missing")},
{line: 6, column: 5, underlyingError: validation.NewMissingFieldError("sourceDescription.url is missing")},
{line: 7, column: 11, underlyingError: validation.NewValueValidationError("sourceDescription.type must be one of [openapi, arazzo]")},
Expand Down
7 changes: 4 additions & 3 deletions cmd/openapi/commands/openapi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ This command checks for:

### `upgrade`

Upgrade an OpenAPI specification to the latest supported version (3.1.1).
Upgrade an OpenAPI specification to the latest supported version (3.2.0).

```bash
# Upgrade to stdout
Expand All @@ -64,11 +64,12 @@ openapi spec upgrade -w ./spec.yaml

# Upgrade with specific target version
openapi spec upgrade --version 3.1.0 ./spec.yaml
openapi spec upgrade --version 3.2.0 ./spec.yaml
```

Features:

- Converts OpenAPI 3.0.x specifications to 3.1.x
- Converts OpenAPI 3.0.x and 3.1.x specifications to 3.2.0
- Maintains backward compatibility where possible
- Updates schema formats and structures
- Preserves all custom extensions and vendor-specific content
Expand Down Expand Up @@ -937,7 +938,7 @@ All commands work with both YAML and JSON input files and preserve the original
openapi spec validate ./spec.yaml

# Upgrade if needed
openapi spec upgrade ./spec.yaml ./spec-v3.1.yaml
openapi spec upgrade ./spec.yaml ./spec-v3.2.yaml

# Bundle external references
openapi spec bundle ./spec-v3.1.yaml ./spec-bundled.yaml
Expand Down
31 changes: 18 additions & 13 deletions cmd/openapi/commands/openapi/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,17 @@ import (
var upgradeCmd = &cobra.Command{
Use: "upgrade <input-file> [output-file]",
Short: "Upgrade an OpenAPI specification to the latest supported version",
Long: `Upgrade an OpenAPI specification document to the latest supported version (3.1.1).
Long: `Upgrade an OpenAPI specification document to the latest supported version (3.2.0).

This command will upgrade OpenAPI documents from:
- OpenAPI 3.0.x versions to 3.1.1 (always)
- OpenAPI 3.1.x versions to 3.1.1 (by default)
- Use --minor-only to only upgrade minor versions (3.0.x to 3.1.1, but skip 3.1.x versions)
By default, upgrades all versions including patch-level upgrades:
- 3.0.x → 3.2.0
- 3.1.x → 3.2.0
- 3.2.x (e.g., 3.2.0) → 3.2.0 (patch upgrade if newer patch exists)

With --minor-only, only performs cross-minor version upgrades:
- 3.0.x → 3.2.0 (cross-minor upgrade)
- 3.1.x → 3.2.0 (cross-minor upgrade)
- 3.2.x → no change (same minor version, skip patch upgrades)

The upgrade process includes:
- Updating the OpenAPI version field
Expand All @@ -40,7 +45,7 @@ var (
)

func init() {
upgradeCmd.Flags().BoolVar(&minorOnly, "minor-only", false, "only upgrade minor versions (3.0.x to 3.1.1, skip 3.1.x versions)")
upgradeCmd.Flags().BoolVar(&minorOnly, "minor-only", false, "only upgrade across minor versions, skip patch-level upgrades within same minor")
upgradeCmd.Flags().BoolVarP(&writeInPlace, "write", "w", false, "write result in-place to input file")
}

Expand All @@ -59,13 +64,13 @@ func runUpgrade(cmd *cobra.Command, args []string) {
os.Exit(1)
}

if err := upgradeOpenAPI(ctx, processor, minorOnly); err != nil {
if err := upgradeOpenAPI(ctx, processor, !minorOnly); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
}

func upgradeOpenAPI(ctx context.Context, processor *OpenAPIProcessor, minorOnly bool) error {
func upgradeOpenAPI(ctx context.Context, processor *OpenAPIProcessor, upgradeSameMinorVersion bool) error {
// Load the OpenAPI document
doc, validationErrors, err := processor.LoadDocument(ctx)
if err != nil {
Expand All @@ -80,12 +85,12 @@ func upgradeOpenAPI(ctx context.Context, processor *OpenAPIProcessor, minorOnly

// Prepare upgrade options
var opts []openapi.Option[openapi.UpgradeOptions]
if !minorOnly {
// By default, upgrade all versions including patch versions (3.1.x to 3.1.1)
opts = append(opts, openapi.WithUpgradeSamePatchVersion())
if upgradeSameMinorVersion {
// By default, upgrade all versions including patch upgrades (e.g., 3.2.0 → 3.2.1)
opts = append(opts, openapi.WithUpgradeSameMinorVersion())
}
// When minorOnly is true, only 3.0.x versions will be upgraded to 3.1.1
// 3.1.x versions will be skipped unless they need minor version upgrade
// When minorOnly is true, only cross-minor upgrades are performed
// Patch upgrades within the same minor version (e.g., 3.2.0 → 3.2.1) are skipped

// Perform the upgrade
originalVersion := doc.OpenAPI
Expand Down
2 changes: 1 addition & 1 deletion cmd/openapi/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ This CLI provides tools for:

OpenAPI Specifications:
- Validate OpenAPI specification documents for compliance
- Upgrade OpenAPI specs to the latest supported version (3.1.1)
- Upgrade OpenAPI specs to the latest supported version (3.2.0)
- Inline all references to create self-contained documents
- Bundle external references into components section while preserving structure

Expand Down
40 changes: 0 additions & 40 deletions internal/utils/versions.go

This file was deleted.

Loading
Loading