diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..6aad72d --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,4 @@ +# Code ownership for openapi +# See: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners + +* @zoobzio diff --git a/.github/settings.yml b/.github/settings.yml new file mode 100644 index 0000000..e472cc2 --- /dev/null +++ b/.github/settings.yml @@ -0,0 +1,26 @@ +repository: + name: openapi + description: OpenAPI 3.1 as native Go types + homepage: https://github.com/zoobzio/openapi + has_wiki: true + has_downloads: true + default_branch: main + allow_squash_merge: true + allow_merge_commit: false + allow_rebase_merge: false + delete_branch_on_merge: true + +branches: + - name: main + protection: + required_pull_request_reviews: + required_approving_review_count: 1 + dismiss_stale_reviews: true + require_code_owner_reviews: true + required_status_checks: + strict: true + contexts: + - CI Complete + enforce_admins: true + required_linear_history: true + restrictions: null diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 47e774e..c2a0e10 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -77,3 +77,16 @@ jobs: with: name: benchmark-results path: benchmark_results.txt + + ci-complete: + name: CI Complete + runs-on: ubuntu-latest + if: always() + needs: [test, lint, benchmark] + steps: + - name: Check results + run: | + if [[ "${{ needs.test.result }}" != "success" || "${{ needs.lint.result }}" != "success" || "${{ needs.benchmark.result }}" != "success" ]]; then + echo "One or more CI jobs failed" + exit 1 + fi diff --git a/docs/3.types.md b/docs/3.types.md index d7c772c..e5c9e77 100644 --- a/docs/3.types.md +++ b/docs/3.types.md @@ -31,6 +31,8 @@ OpenAPI │ └── SecurityRequirement ├── Tags[] │ └── Tag +├── TagGroups[] (x-tagGroups) +│ └── TagGroup └── ExternalDocumentation ``` @@ -205,6 +207,10 @@ Tag ├── Description └── ExternalDocs +TagGroup (x-tagGroups vendor extension) +├── Name +└── Tags[] + ExternalDocumentation ├── URL └── Description diff --git a/openapi.go b/openapi.go index cd05d88..f483be6 100644 --- a/openapi.go +++ b/openapi.go @@ -11,6 +11,7 @@ type OpenAPI struct { Servers []Server `json:"servers,omitempty" yaml:"servers,omitempty"` Security []SecurityRequirement `json:"security,omitempty" yaml:"security,omitempty"` Tags []Tag `json:"tags,omitempty" yaml:"tags,omitempty"` + TagGroups []TagGroup `json:"x-tagGroups,omitempty" yaml:"x-tagGroups,omitempty"` } // Info provides metadata about the API. @@ -187,6 +188,12 @@ type Tag struct { Description string `json:"description,omitempty" yaml:"description,omitempty"` } +// TagGroup groups tags for documentation tools like Redoc. +type TagGroup struct { + Name string `json:"name" yaml:"name"` + Tags []string `json:"tags,omitempty" yaml:"tags,omitempty"` +} + // ExternalDocumentation allows referencing an external resource. type ExternalDocumentation struct { Description string `json:"description,omitempty" yaml:"description,omitempty"` diff --git a/openapi_test.go b/openapi_test.go index f19d83d..41241d5 100644 --- a/openapi_test.go +++ b/openapi_test.go @@ -295,6 +295,23 @@ func TestTag(t *testing.T) { } } +func TestTagGroup(t *testing.T) { + group := TagGroup{ + Name: "Account", + Tags: []string{"Authentication", "Users"}, + } + + if group.Name != "Account" { + t.Errorf("expected name 'Account', got %q", group.Name) + } + if len(group.Tags) != 2 { + t.Errorf("expected 2 tags, got %d", len(group.Tags)) + } + if group.Tags[0] != "Authentication" { + t.Errorf("expected first tag 'Authentication', got %q", group.Tags[0]) + } +} + func TestMediaType(t *testing.T) { mediaType := MediaType{ Schema: &Schema{Type: NewSchemaType("object")},