[PATCH v1 6/9] docs: Increment API version

Stephen Finucane stephen at that.guru
Sat Jul 13 02:12:10 AEST 2024


On Mon, 2024-06-17 at 18:18 -0400, Adam Hassick wrote:
> Update the OpenAPI specification template and the API docs to reflect
> the new minor version.
> 
> Signed-off-by: Adam Hassick <ahassick at iol.unh.edu>

As noted on [5/9], please squash the non-schema changes from here back to 4.
LGTM otherwise.

Reviewed-by: Stephen Finucane <stephen at that.guru>

> ---
>  docs/api/rest/index.rst                |   42 +-
>  docs/api/rest/schemas/v1.3.rst         |    4 +-
>  docs/api/rest/schemas/v1.4.rst         |    5 +
>  docs/api/schemas/generate-schemas.py   |    4 +-
>  docs/api/schemas/latest/patchwork.yaml |   18 +-
>  docs/api/schemas/patchwork.j2          |   18 +
>  docs/api/schemas/v1.4/patchwork.yaml   | 3242 ++++++++++++++++++++++++
>  docs/usage/overview.rst                |   12 +
>  8 files changed, 3320 insertions(+), 25 deletions(-)
>  create mode 100644 docs/api/rest/schemas/v1.4.rst
>  create mode 100644 docs/api/schemas/v1.4/patchwork.yaml
> 
> diff --git a/docs/api/rest/index.rst b/docs/api/rest/index.rst
> index 67022e6..cdf9104 100644
> --- a/docs/api/rest/index.rst
> +++ b/docs/api/rest/index.rst
> @@ -8,7 +8,7 @@ This guide provides an overview of how one can interact with the REST API. For
>  detailed information on type and response format of the various resources
>  exposed by the API, refer to the web browsable API. This can be found at:
>  
> -    https://patchwork.example.com/api/1.3/
> +    https://patchwork.example.com/api/1.4/
>  
>  where `patchwork.example.com` refers to the URL of your Patchwork instance.
>  
> @@ -57,16 +57,16 @@ Patchwork instance hosted at `patchwork.example.com`, run:
>  
>  .. code-block:: shell
>  
> -    $ curl -s 'https://patchwork.example.com/api/1.3/' | python -m json.tool
> +    $ curl -s 'https://patchwork.example.com/api/1.4/' | python -m json.tool
>      {
> -        "bundles": "https://patchwork.example.com/api/1.3/bundles/",
> -        "covers": "https://patchwork.example.com/api/1.3/covers/",
> -        "events": "https://patchwork.example.com/api/1.3/events/",
> -        "patches": "https://patchwork.example.com/api/1.3/patches/",
> -        "people": "https://patchwork.example.com/api/1.3/people/",
> -        "projects": "https://patchwork.example.com/api/1.3/projects/",
> -        "series": "https://patchwork.example.com/api/1.3/series/",
> -        "users": "https://patchwork.example.com/api/1.3/users/"
> +        "bundles": "https://patchwork.example.com/api/1.4/bundles/",
> +        "covers": "https://patchwork.example.com/api/1.4/covers/",
> +        "events": "https://patchwork.example.com/api/1.4/events/",
> +        "patches": "https://patchwork.example.com/api/1.4/patches/",
> +        "people": "https://patchwork.example.com/api/1.4/people/",
> +        "projects": "https://patchwork.example.com/api/1.4/projects/",
> +        "series": "https://patchwork.example.com/api/1.4/series/",
> +        "users": "https://patchwork.example.com/api/1.4/users/"
>      }
>  
>  
> @@ -82,14 +82,14 @@ well-supported. To repeat the above example using `requests`:, run
>      >>> r = requests.get('https://patchwork.example.com/api/1.3/')
>      >>> print(json.dumps(r.json(), indent=2))
>      {
> -        "bundles": "https://patchwork.example.com/api/1.3/bundles/",
> -        "covers": "https://patchwork.example.com/api/1.3/covers/",
> -        "events": "https://patchwork.example.com/api/1.3/events/",
> -        "patches": "https://patchwork.example.com/api/1.3/patches/",
> -        "people": "https://patchwork.example.com/api/1.3/people/",
> -        "projects": "https://patchwork.example.com/api/1.3/projects/",
> -        "series": "https://patchwork.example.com/api/1.3/series/",
> -        "users": "https://patchwork.example.com/api/1.3/users/"
> +        "bundles": "https://patchwork.example.com/api/1.4/bundles/",
> +        "covers": "https://patchwork.example.com/api/1.4/covers/",
> +        "events": "https://patchwork.example.com/api/1.4/events/",
> +        "patches": "https://patchwork.example.com/api/1.4/patches/",
> +        "people": "https://patchwork.example.com/api/1.4/people/",
> +        "projects": "https://patchwork.example.com/api/1.4/projects/",
> +        "series": "https://patchwork.example.com/api/1.4/series/",
> +        "users": "https://patchwork.example.com/api/1.4/users/"
>      }
>  
>  Tools like `curl` and libraries like `requests` can be used to build anything
> @@ -108,7 +108,7 @@ Versioning
>  ----------
>  
>  By default, all requests will receive the latest version of the API: currently
> -``1.3``:
> +``1.4``:
>  
>  .. code-block:: http
>  
> @@ -119,7 +119,7 @@ changes breaking your application:
>  
>  .. code-block:: http
>  
> -    GET /api/1.3 HTTP/1.1
> +    GET /api/1.4 HTTP/1.1
>  
>  Older API versions will be deprecated and removed over time. For more
>  information, refer to :ref:`rest-api-versions`.
> @@ -275,6 +275,7 @@ Supported Versions
>     1.1, 2.1, ✓
>     1.2, 2.2, ✓
>     1.3, 3.1, ✓
> +   1.4, unreleased, ✓
>  
>  Further information about this and more can typically be found in
>  :doc:`the release notes </releases/index>`.
> @@ -292,6 +293,7 @@ Auto-generated schema documentation is provided below.
>     /api/rest/schemas/v1.1
>     /api/rest/schemas/v1.2
>     /api/rest/schemas/v1.3
> +   /api/rest/schemas/v1.4
>  
>  .. Links
>  
> diff --git a/docs/api/rest/schemas/v1.3.rst b/docs/api/rest/schemas/v1.3.rst
> index 17a4421..6bbf1a5 100644
> --- a/docs/api/rest/schemas/v1.3.rst
> +++ b/docs/api/rest/schemas/v1.3.rst
> @@ -1,5 +1,5 @@
> -API v1.3 (latest)
> -=================
> +API v1.3
> +========
>  
>  .. openapi:: ../../schemas/v1.3/patchwork.yaml
>     :examples:
> diff --git a/docs/api/rest/schemas/v1.4.rst b/docs/api/rest/schemas/v1.4.rst
> new file mode 100644
> index 0000000..11e34f6
> --- /dev/null
> +++ b/docs/api/rest/schemas/v1.4.rst
> @@ -0,0 +1,5 @@
> +API v1.4 (latest)
> +=================
> +
> +.. openapi:: ../../schemas/v1.4/patchwork.yaml
> +   :examples:
> diff --git a/docs/api/schemas/generate-schemas.py b/docs/api/schemas/generate-schemas.py
> index 14b7414..52008df 100755
> --- a/docs/api/schemas/generate-schemas.py
> +++ b/docs/api/schemas/generate-schemas.py
> @@ -14,8 +14,8 @@ except ImportError:
>      yaml = None
>  
>  ROOT_DIR = os.path.dirname(os.path.realpath(__file__))
> -VERSIONS = [(1, 0), (1, 1), (1, 2), (1, 3), None]
> -LATEST_VERSION = (1, 3)
> +VERSIONS = [(1, 0), (1, 1), (1, 2), (1, 3), (1, 4), None]
> +LATEST_VERSION = (1, 4)
>  
>  
>  def generate_schemas():
> diff --git a/docs/api/schemas/latest/patchwork.yaml b/docs/api/schemas/latest/patchwork.yaml
> index 93e56fa..2591654 100644
> --- a/docs/api/schemas/latest/patchwork.yaml
> +++ b/docs/api/schemas/latest/patchwork.yaml
> @@ -13,7 +13,7 @@ info:
>    license:
>      name: GPL v2 License
>      url: https://www.gnu.org/licenses/gpl-2.0.html
> -  version: '1.3'
> +  version: '1.4'
>  paths:
>    /api:
>      get:
> @@ -2605,6 +2605,22 @@ components:
>              $ref: '#/components/schemas/PatchEmbedded'
>            readOnly: true
>            uniqueItems: true
> +        dependencies:
> +          title: Dependencies
> +          type: array
> +          items:
> +            type: string
> +            format: url
> +          readOnly: true
> +          uniqueItems: true
> +        dependents:
> +          title: Dependents
> +          type: array
> +          items:
> +            type: string
> +            format: url
> +          readOnly: true
> +          uniqueItems: true
>      User:
>        type: object
>        title: User
> diff --git a/docs/api/schemas/patchwork.j2 b/docs/api/schemas/patchwork.j2
> index 516fbe8..67e9253 100644
> --- a/docs/api/schemas/patchwork.j2
> +++ b/docs/api/schemas/patchwork.j2
> @@ -2699,6 +2699,24 @@ components:
>              $ref: '#/components/schemas/PatchEmbedded'
>            readOnly: true
>            uniqueItems: true
> +{% if version >= (1, 4) %}
> +        dependencies:
> +          title: Dependencies
> +          type: array
> +          items:
> +            type: string
> +            format: url
> +          readOnly: true
> +          uniqueItems: true
> +        dependents:
> +          title: Dependents
> +          type: array
> +          items:
> +            type: string
> +            format: url
> +          readOnly: true
> +          uniqueItems: true
> +{% endif %}
>      User:
>        type: object
>        title: User
> diff --git a/docs/api/schemas/v1.4/patchwork.yaml b/docs/api/schemas/v1.4/patchwork.yaml
> new file mode 100644
> index 0000000..3c9786c
> --- /dev/null
> +++ b/docs/api/schemas/v1.4/patchwork.yaml
> @@ -0,0 +1,3242 @@
> +# DO NOT EDIT THIS FILE. It is generated from a template. Changes should be
> +# proposed against the template and updated files generated using the
> +# 'generate-schemas.py' tool
> +---
> +openapi: '3.1.0'
> +info:
> +  title: Patchwork API
> +  description: |
> +    Patchwork is a web-based patch tracking system designed to facilitate the
> +    contribution and management of contributions to an open-source project.
> +  contact:
> +    email: patchwork at lists.ozlabs.org
> +  license:
> +    name: GPL v2 License
> +    url: https://www.gnu.org/licenses/gpl-2.0.html
> +  version: '1.4'
> +paths:
> +  /api/1.4/:
> +    get:
> +      summary: List API resources.
> +      description: |
> +        Show paths to all supported API resources.
> +      operationId: api_list
> +      parameters: []
> +      responses:
> +        '200':
> +          description: 'List of API resources'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Index'
> +      tags:
> +        - api
> +  /api/1.4/bundles:
> +    get:
> +      summary: List bundles.
> +      description: |
> +        List all bundles that the current user has access to.
> +        For unauthenticated requests, only public bundles can be shown.
> +      operationId: bundles_list
> +      parameters:
> +        - $ref: '#/components/parameters/Page'
> +        - $ref: '#/components/parameters/PageSize'
> +        - $ref: '#/components/parameters/Order'
> +        - $ref: '#/components/parameters/Search'
> +        - in: query
> +          name: project
> +          description: An ID or linkname of a project to filter bundles by.
> +          schema:
> +            title: ''
> +            type: string
> +        - in: query
> +          name: owner
> +          description: An ID or username of a user to filter bundles by.
> +          schema:
> +            title: ''
> +            type: string
> +        - in: query
> +          name: public
> +          description: Show only public (`true`) or private (`false`) bundles.
> +          schema:
> +            title: ''
> +            type: string
> +            enum:
> +              - 'true'
> +              - 'false'
> +      responses:
> +        '200':
> +          description: 'List of bundles'
> +          headers:
> +            Link:
> +              $ref: '#/components/headers/Link'
> +          content:
> +            application/json:
> +              schema:
> +                type: array
> +                items:
> +                  $ref: '#/components/schemas/Bundle'
> +      tags:
> +        - bundles
> +    post:
> +      summary: Create a bundle.
> +      description: |
> +        Create a new bundle.
> +      operationId: bundles_create
> +      security:
> +        - basicAuth: []
> +        - apiKeyAuth: []
> +      requestBody:
> +        $ref: '#/components/requestBodies/Bundle'
> +      responses:
> +        '201':
> +          description: 'Created bundle'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Bundle'
> +        '400':
> +          description: 'Invalid request'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/ErrorBundleCreateUpdate'
> +        '403':
> +          description: 'Forbidden'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - bundles
> +  /api/1.4/bundles/{id}:
> +    parameters:
> +      - in: path
> +        name: id
> +        required: true
> +        description: A unique integer value identifying this bundle.
> +        schema:
> +          title: ID
> +          type: integer
> +    get:
> +      summary: Show a bundle.
> +      description: |
> +        Retrieve a bundle by its ID.
> +        The bundle must be either be public or be owned by the currently authenticated user.
> +      operationId: bundles_read
> +      responses:
> +        '200':
> +          description: 'A bundle'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Bundle'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - bundles
> +    patch:
> +      summary: Update a bundle (partial).
> +      description:
> +        Partially update an existing bundle.
> +        The bundle must be owned by the currently authenticated user.
> +      operationId: bundles_partial_update
> +      security:
> +        - basicAuth: []
> +        - apiKeyAuth: []
> +      requestBody:
> +        $ref: '#/components/requestBodies/Bundle'
> +      responses:
> +        '200':
> +          description: 'Updated bundle'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Bundle'
> +        '400':
> +          description: 'Bad request'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/ErrorBundleCreateUpdate'
> +        '403':
> +          description: 'Forbidden'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - bundles
> +    put:
> +      summary: Update a bundle.
> +      description:
> +        Update an existing bundle.
> +        The bundle must be owned by the currently authenticated user.
> +      operationId: bundles_update
> +      security:
> +        - basicAuth: []
> +        - apiKeyAuth: []
> +      requestBody:
> +        $ref: '#/components/requestBodies/Bundle'
> +      responses:
> +        '200':
> +          description: 'Updated bundle'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Bundle'
> +        '400':
> +          description: 'Bad request'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/ErrorBundleCreateUpdate'
> +        '403':
> +          description: 'Forbidden'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - bundles
> +  /api/1.4/covers:
> +    get:
> +      summary: List cover letters.
> +      description: |
> +        List all cover letters.
> +      operationId: covers_list
> +      parameters:
> +        - $ref: '#/components/parameters/Page'
> +        - $ref: '#/components/parameters/PageSize'
> +        - $ref: '#/components/parameters/Order'
> +        - $ref: '#/components/parameters/Search'
> +        - $ref: '#/components/parameters/BeforeFilter'
> +        - $ref: '#/components/parameters/SinceFilter'
> +        - in: query
> +          name: project
> +          description: |
> +            An ID or linkname of a project to filter cover letters by.
> +          schema:
> +            title: ''
> +            type: string
> +        - in: query
> +          name: series
> +          description: An ID of a series to filter cover letters by.
> +          schema:
> +            title: ''
> +            type: string
> +        - in: query
> +          name: submitter
> +          description: |
> +            An ID or email address of a person to filter cover letters by.
> +          schema:
> +            title: ''
> +            type: string
> +        - in: query
> +          name: msgid
> +          description: |
> +            The cover message-id as a case-sensitive string, without leading or
> +            trailing angle brackets, to filter by.
> +          schema:
> +            title: ''
> +            type: string
> +      responses:
> +        '200':
> +          description: 'List of cover letters'
> +          headers:
> +            Link:
> +              $ref: '#/components/headers/Link'
> +          content:
> +            application/json:
> +              schema:
> +                type: array
> +                items:
> +                  $ref: '#/components/schemas/CoverList'
> +      tags:
> +        - covers
> +  /api/1.4/covers/{id}:
> +    parameters:
> +      - in: path
> +        name: id
> +        description: A unique integer value identifying this cover letter.
> +        required: true
> +        schema:
> +          title: ID
> +          type: integer
> +    get:
> +      summary: Show a cover letter.
> +      description: |
> +        Retrieve a cover letter by its ID.
> +      operationId: covers_read
> +      responses:
> +        '200':
> +          description: 'A cover letter'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/CoverDetail'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - covers
> +  /api/1.4/covers/{id}/comments:
> +    parameters:
> +      - in: path
> +        name: id
> +        description: |
> +          A unique integer value identifying the parent cover letter.
> +        required: true
> +        schema:
> +          title: ID
> +          type: integer
> +    get:
> +      summary: List cover letter comments
> +      description: |
> +        List all comments for the given cover letter.
> +      operationId: cover_comments_list
> +      parameters:
> +        - $ref: '#/components/parameters/Page'
> +        - $ref: '#/components/parameters/PageSize'
> +        - $ref: '#/components/parameters/Order'
> +        - $ref: '#/components/parameters/Search'
> +      responses:
> +        '200':
> +          description: 'List of comments'
> +          headers:
> +            Link:
> +              $ref: '#/components/headers/Link'
> +          content:
> +            application/json:
> +              schema:
> +                type: array
> +                items:
> +                  $ref: '#/components/schemas/Comment'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - comments
> +  /api/1.4/covers/{cover_id}/comments/{comment_id}:
> +    parameters:
> +      - in: path
> +        name: cover_id
> +        description: A unique integer value identifying the parent cover.
> +        required: true
> +        schema:
> +          title: Cover ID
> +          type: integer
> +      - in: path
> +        name: comment_id
> +        description: A unique integer value identifying this comment.
> +        required: true
> +        schema:
> +          title: Comment ID
> +          type: integer
> +    get:
> +      summary: Show a cover letter comment.
> +      description: |
> +        Retrieve a cover letter comment by its ID.
> +      operationId: cover_comments_read
> +      responses:
> +        '200':
> +          description: 'A cover letter comment'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Comment'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - comments
> +    patch:
> +      summary: Update a cover letter comment (partial).
> +      description:
> +        Partially update an existing cover letter comment.
> +        You must be a maintainer of the project that the cover letter comment belongs to.
> +      operationId: cover_comments_partial_update
> +      requestBody:
> +        $ref: '#/components/requestBodies/Comment'
> +      responses:
> +        '200':
> +          description: 'Updated cover letter comment'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Comment'
> +        '400':
> +          description: 'Invalid request'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/ErrorCommentUpdate'
> +        '403':
> +          description: 'Forbidden'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - comments
> +  /api/1.4/events:
> +    get:
> +      summary: List events.
> +      description: |
> +        List all events.
> +        This list can be quite large. You are encouraged to use filters to narrow it to specific categories or project(s).
> +      operationId: events_list
> +      parameters:
> +        - $ref: '#/components/parameters/Page'
> +        - $ref: '#/components/parameters/PageSize'
> +        - $ref: '#/components/parameters/Order'
> +        - $ref: '#/components/parameters/Search'
> +        - $ref: '#/components/parameters/BeforeFilter'
> +        - $ref: '#/components/parameters/SinceFilter'
> +        - in: query
> +          name: project
> +          description: An ID or linkname of a project to filter events by.
> +          schema:
> +            title: ''
> +            type: string
> +        - in: query
> +          name: category
> +          description: |
> +            An event category to filter events by. These categories are subject
> +            to change depending on the version of Patchwork deployed and are
> +            not subject to the versionining constraints present across the rest
> +            of the API.
> +          schema:
> +            title: ''
> +            type: string
> +            enum:
> +              - cover-created
> +              - patch-created
> +              - patch-completed
> +              - patch-state-changed
> +              - patch-relation-changed
> +              - patch-delegated
> +              - check-created
> +              - series-created
> +              - series-completed
> +              - cover-comment-created
> +              - patch-comment-created
> +        - in: query
> +          name: series
> +          description: An ID of a series to filter events by.
> +          schema:
> +            title: ''
> +            type: integer
> +        - in: query
> +          name: patch
> +          description: An ID of a patch to filter events by.
> +          schema:
> +            title: ''
> +            type: integer
> +        - in: query
> +          name: cover
> +          description: An ID of a cover letter to filter events by.
> +          schema:
> +            title: ''
> +            type: integer
> +      responses:
> +        '200':
> +          description: 'List of events'
> +          headers:
> +            Link:
> +              $ref: '#/components/headers/Link'
> +          content:
> +            application/json:
> +              schema:
> +                type: array
> +                items:
> +                  anyOf:
> +                    - $ref: '#/components/schemas/EventCoverCreated'
> +                    - $ref: '#/components/schemas/EventPatchCreated'
> +                    - $ref: '#/components/schemas/EventPatchCompleted'
> +                    - $ref: '#/components/schemas/EventPatchStateChanged'
> +                    - $ref: '#/components/schemas/EventPatchRelationChanged'
> +                    - $ref: '#/components/schemas/EventPatchDelegated'
> +                    - $ref: '#/components/schemas/EventCheckCreated'
> +                    - $ref: '#/components/schemas/EventSeriesCreated'
> +                    - $ref: '#/components/schemas/EventSeriesCompleted'
> +                    - $ref: '#/components/schemas/EventCoverCommentCreated'
> +                    - $ref: '#/components/schemas/EventPatchCommentCreated'
> +                  discriminator:
> +                    propertyName: category
> +                    mapping:
> +                      cover-created: '#/components/schemas/EventCoverCreated'
> +                      patch-created: '#/components/schemas/EventPatchCreated'
> +                      patch-completed: '#/components/schemas/EventPatchCompleted'
> +                      patch-state-changed: '#/components/schemas/EventPatchStateChanged'
> +                      patch-relation-changed: '#/components/schemas/EventPatchRelationChanged'
> +                      patch-delegated: '#/components/schemas/EventPatchDelegated'
> +                      check-created: '#/components/schemas/EventCheckCreated'
> +                      series-created: '#/components/schemas/EventSeriesCreated'
> +                      series-completed: '#/components/schemas/EventSeriesCompleted'
> +                      cover-comment-created: '#/components/schemas/EventCoverCommentCreated'
> +                      patch-comment-created: '#/components/schemas/EventPatchCommentCreated'
> +      tags:
> +        - events
> +  /api/1.4/patches:
> +    get:
> +      summary: List patches.
> +      description: |
> +        List all patches.
> +      operationId: patches_list
> +      parameters:
> +        - $ref: '#/components/parameters/Page'
> +        - $ref: '#/components/parameters/PageSize'
> +        - $ref: '#/components/parameters/Order'
> +        - $ref: '#/components/parameters/Search'
> +        - $ref: '#/components/parameters/BeforeFilter'
> +        - $ref: '#/components/parameters/SinceFilter'
> +        - in: query
> +          name: project
> +          description: An ID or linkname of a project to filter patches by.
> +          schema:
> +            title: ''
> +            type: string
> +        - in: query
> +          name: series
> +          description: An ID of a series to filter patches by.
> +          schema:
> +            title: ''
> +            type: integer
> +        - in: query
> +          name: submitter
> +          description: |
> +            An ID or email address of a person to filter patches by.
> +          schema:
> +            title: ''
> +            type: string
> +        - in: query
> +          name: delegate
> +          description: An ID or username of a user to filter patches by.
> +          schema:
> +            title: ''
> +            type: string
> +        - in: query
> +          name: state
> +          description: A slug representation of a state to filter patches by.
> +          schema:
> +            title: ''
> +            type: string
> +        - in: query
> +          name: archived
> +          description: |
> +            Show only archived (`true`) or non-archived (`false`) patches.
> +          schema:
> +            title: ''
> +            type: string
> +            enum:
> +              - 'true'
> +              - 'false'
> +        - in: query
> +          name: hash
> +          description: |
> +            The patch hash as a case-insensitive hexadecimal string, to filter by.
> +          schema:
> +            title: ''
> +            type: string
> +        - in: query
> +          name: msgid
> +          description: |
> +            The patch message-id as a case-sensitive string, without leading or
> +            trailing angle brackets, to filter by.
> +          schema:
> +            title: ''
> +            type: string
> +      responses:
> +        '200':
> +          description: 'List of patches'
> +          headers:
> +            Link:
> +              $ref: '#/components/headers/Link'
> +          content:
> +            application/json:
> +              schema:
> +                type: array
> +                items:
> +                  $ref: '#/components/schemas/PatchList'
> +      tags:
> +        - patches
> +  /api/1.4/patches/{id}:
> +    parameters:
> +      - in: path
> +        name: id
> +        description: A unique integer value identifying this patch.
> +        required: true
> +        schema:
> +          title: ID
> +          type: integer
> +    get:
> +      summary: Show a patch.
> +      description: |
> +        Retrieve a patch by its ID.
> +      operationId: patches_read
> +      responses:
> +        '200':
> +          description: 'A patch'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/PatchDetail'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - patches
> +    patch:
> +      summary: Update a patch (partial).
> +      description:
> +        Partially update an existing patch.
> +        You must be a maintainer of the project that the patch belongs to.
> +      operationId: patches_partial_update
> +      security:
> +        - basicAuth: []
> +        - apiKeyAuth: []
> +      requestBody:
> +        $ref: '#/components/requestBodies/Patch'
> +      responses:
> +        '200':
> +          description: 'An updated patch'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/PatchDetail'
> +        '400':
> +          description: 'Invalid request'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/ErrorPatchUpdate'
> +        '403':
> +          description: 'Forbidden'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +        '409':
> +          description: 'Conflict'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - patches
> +    put:
> +      description: Update a patch.
> +      operationId: patches_update
> +      security:
> +        - basicAuth: []
> +        - apiKeyAuth: []
> +      requestBody:
> +        $ref: '#/components/requestBodies/Patch'
> +      responses:
> +        '200':
> +          description: 'An updated patch'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/PatchDetail'
> +        '400':
> +          description: 'Invalid request'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/ErrorPatchUpdate'
> +        '403':
> +          description: 'Forbidden'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +        '409':
> +          description: 'Conflict'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - patches
> +  /api/1.4/patches/{id}/comments:
> +    parameters:
> +      - in: path
> +        name: id
> +        description: A unique integer value identifying the parent patch.
> +        required: true
> +        schema:
> +          title: ID
> +          type: integer
> +    get:
> +      summary: List patch comments
> +      description: |
> +        List all comments for the given patch.
> +      operationId: patch_comments_list
> +      parameters:
> +        - $ref: '#/components/parameters/Page'
> +        - $ref: '#/components/parameters/PageSize'
> +        - $ref: '#/components/parameters/Order'
> +        - $ref: '#/components/parameters/Search'
> +      responses:
> +        '200':
> +          description: 'List of comments'
> +          headers:
> +            Link:
> +              $ref: '#/components/headers/Link'
> +          content:
> +            application/json:
> +              schema:
> +                type: array
> +                items:
> +                  $ref: '#/components/schemas/Comment'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - comments
> +  /api/1.4/patches/{patch_id}/comments/{comment_id}:
> +    parameters:
> +      - in: path
> +        name: patch_id
> +        description: A unique integer value identifying the parent patch.
> +        required: true
> +        schema:
> +          title: Patch ID
> +          type: integer
> +      - in: path
> +        name: comment_id
> +        description: A unique integer value identifying this comment.
> +        required: true
> +        schema:
> +          title: Comment ID
> +          type: integer
> +    get:
> +      summary: Show a patch comment.
> +      description: |
> +        Retrieve a patch comment by its ID and the ID of the patch.
> +      operationId: patch_comments_read
> +      responses:
> +        '200':
> +          description: 'A patch comment'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Comment'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - comments
> +    patch:
> +      summary: Update a patch comment (partial).
> +      description:
> +        Partially update an existing patch comment.
> +        You must be a maintainer of the project that the patch comment belongs to.
> +      operationId: patch_comments_partial_update
> +      requestBody:
> +        $ref: '#/components/requestBodies/Comment'
> +      responses:
> +        '200':
> +          description: 'Updated patch'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Comment'
> +        '400':
> +          description: 'Invalid request'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/ErrorCommentUpdate'
> +        '403':
> +          description: 'Forbidden'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - comments
> +  /api/1.4/patches/{patch_id}/checks:
> +    parameters:
> +      - in: path
> +        name: patch_id
> +        description: A unique integer value identifying the parent patch.
> +        required: true
> +        schema:
> +          title: Patch ID
> +          type: integer
> +    get:
> +      summary: List checks.
> +      description: |
> +        List all checks for the given patch.
> +      operationId: checks_list
> +      parameters:
> +        - $ref: '#/components/parameters/Page'
> +        - $ref: '#/components/parameters/PageSize'
> +        - $ref: '#/components/parameters/Order'
> +        - $ref: '#/components/parameters/Search'
> +        - $ref: '#/components/parameters/BeforeFilter'
> +        - $ref: '#/components/parameters/SinceFilter'
> +        - in: query
> +          name: user
> +          description: An ID or username of a user to filter checks by.
> +          schema:
> +            title: ''
> +            type: string
> +        - in: query
> +          name: state
> +          description: A check state to filter checks by.
> +          schema:
> +            title: ''
> +            type: string
> +            enum:
> +              - pending
> +              - success
> +              - warning
> +              - fail
> +        - in: query
> +          name: context
> +          description: A check context to filter checks by.
> +          schema:
> +            title: ''
> +            type: string
> +      responses:
> +        '200':
> +          description: 'List of checks'
> +          headers:
> +            Link:
> +              $ref: '#/components/headers/Link'
> +          content:
> +            application/json:
> +              schema:
> +                type: array
> +                items:
> +                  $ref: '#/components/schemas/Check'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - checks
> +    post:
> +      summary: Create a check.
> +      operationId: checks_create
> +      security:
> +        - basicAuth: []
> +        - apiKeyAuth: []
> +      requestBody:
> +        $ref: '#/components/requestBodies/Check'
> +      responses:
> +        '201':
> +          description: 'Created check'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Check'
> +        '400':
> +          description: 'Invalid request'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/ErrorCheckCreate'
> +        '403':
> +          description: 'Forbidden'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - checks
> +  /api/1.4/patches/{patch_id}/checks/{check_id}:
> +    parameters:
> +      - in: path
> +        name: patch_id
> +        description: A unique integer value identifying the parent patch.
> +        required: true
> +        schema:
> +          title: Patch ID
> +          type: integer
> +      - in: path
> +        name: check_id
> +        description: A unique integer value identifying this check.
> +        required: true
> +        schema:
> +          title: Check ID
> +          type: integer
> +    get:
> +      summary: Show a check.
> +      description: |
> +        Retrieve a check by its ID.
> +      operationId: checks_read
> +      responses:
> +        '200':
> +          description: 'A check'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Check'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - checks
> +  /api/1.4/people:
> +    get:
> +      summary: List people.
> +      description: |
> +        List all people.
> +        A person is anyone that has submitted a patch, a series of patches, or a comment to any project.
> +      operationId: people_list
> +      security:
> +        - basicAuth: []
> +        - apiKeyAuth: []
> +      parameters:
> +        - $ref: '#/components/parameters/Page'
> +        - $ref: '#/components/parameters/PageSize'
> +        - $ref: '#/components/parameters/Order'
> +        - $ref: '#/components/parameters/Search'
> +      responses:
> +        '200':
> +          description: 'List of people'
> +          headers:
> +            Link:
> +              $ref: '#/components/headers/Link'
> +          content:
> +            application/json:
> +              schema:
> +                type: array
> +                items:
> +                  $ref: '#/components/schemas/Person'
> +        '403':
> +          description: 'Forbidden'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - people
> +  /api/1.4/people/{id}:
> +    parameters:
> +      - in: path
> +        name: id
> +        description: A unique integer value identifying this person.
> +        required: true
> +        schema:
> +          title: ID
> +          type: integer
> +    get:
> +      summary: Show a person.
> +      description: |
> +        Retrieve a person by their ID.
> +        A person is anyone that has submitted a patch, a series of patches, or a comment to any project.
> +      operationId: people_read
> +      security:
> +        - basicAuth: []
> +        - apiKeyAuth: []
> +      responses:
> +        '200':
> +          description: 'A person'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Person'
> +        '403':
> +          description: 'Forbidden'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - people
> +  /api/1.4/projects:
> +    get:
> +      summary: List projects.
> +      description: |
> +        List all projects.
> +      operationId: projects_list
> +      parameters:
> +        - $ref: '#/components/parameters/Page'
> +        - $ref: '#/components/parameters/PageSize'
> +        - $ref: '#/components/parameters/Order'
> +        - $ref: '#/components/parameters/Search'
> +      responses:
> +        '200':
> +          description: 'List of projects'
> +          headers:
> +            Link:
> +              $ref: '#/components/headers/Link'
> +          content:
> +            application/json:
> +              schema:
> +                type: array
> +                items:
> +                  $ref: '#/components/schemas/Project'
> +      tags:
> +        - projects
> +  /api/1.4/projects/{id}:
> +    parameters:
> +      - in: path
> +        name: id
> +        description: A unique integer value identifying this project.
> +        required: true
> +        schema:
> +          title: ID
> +          # TODO: Add regex?
> +          type: string
> +    get:
> +      summary: Show a project.
> +      description: |
> +        Retrieve a project by its ID.
> +      operationId: projects_read
> +      responses:
> +        '200':
> +          description: 'A project'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Project'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - projects
> +    patch:
> +      summary: Update a project (partial).
> +      description:
> +        Partially update an existing project.
> +        You must be a maintainer of the project.
> +      operationId: projects_partial_update
> +      security:
> +        - basicAuth: []
> +        - apiKeyAuth: []
> +      requestBody:
> +        $ref: '#/components/requestBodies/Project'
> +      responses:
> +        '200':
> +          description: 'Updated project'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Project'
> +        '400':
> +          description: 'Bad request'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/ErrorProjectUpdate'
> +        '403':
> +          description: 'Forbidden'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - projects
> +    put:
> +      description: Update a project.
> +      operationId: projects_update
> +      security:
> +        - basicAuth: []
> +        - apiKeyAuth: []
> +      requestBody:
> +        $ref: '#/components/requestBodies/Project'
> +      responses:
> +        '200':
> +          description: 'Updated project'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Project'
> +        '400':
> +          description: 'Bad request'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/ErrorProjectUpdate'
> +        '403':
> +          description: 'Forbidden'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - projects
> +  /api/1.4/series:
> +    get:
> +      summary: List series.
> +      description: |
> +        List all series.
> +        A series is a collection of patches with an optional cover letter.
> +      operationId: series_list
> +      parameters:
> +        - $ref: '#/components/parameters/Page'
> +        - $ref: '#/components/parameters/PageSize'
> +        - $ref: '#/components/parameters/Order'
> +        - $ref: '#/components/parameters/Search'
> +        - $ref: '#/components/parameters/BeforeFilter'
> +        - $ref: '#/components/parameters/SinceFilter'
> +        - in: query
> +          name: submitter
> +          description: An ID or email address of a person to filter series by.
> +          schema:
> +            title: ''
> +            type: string
> +        - in: query
> +          name: project
> +          description: An ID or linkname of a project to filter series by.
> +          schema:
> +            title: ''
> +            type: string
> +      responses:
> +        '200':
> +          description: 'List of series'
> +          headers:
> +            Link:
> +              $ref: '#/components/headers/Link'
> +          content:
> +            application/json:
> +              schema:
> +                type: array
> +                items:
> +                  $ref: '#/components/schemas/Series'
> +      tags:
> +        - series
> +  /api/1.4/series/{id}:
> +    parameters:
> +      - in: path
> +        name: id
> +        description: A unique integer value identifying this series.
> +        required: true
> +        schema:
> +          title: ID
> +          type: integer
> +    get:
> +      summary: Show a series.
> +      description: |
> +        Retrieve a series by its ID.
> +        A series is a collection of patches with an optional cover letter.
> +      operationId: series_read
> +      responses:
> +        '200':
> +          description: 'A series'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Series'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - series
> +  /api/1.4/users:
> +    get:
> +      summary: List users.
> +      description: |
> +        List all users.
> +      operationId: users_list
> +      security:
> +        - basicAuth: []
> +        - apiKeyAuth: []
> +      parameters:
> +        - $ref: '#/components/parameters/Page'
> +        - $ref: '#/components/parameters/PageSize'
> +        - $ref: '#/components/parameters/Order'
> +        - $ref: '#/components/parameters/Search'
> +      responses:
> +        '200':
> +          description: 'List of users'
> +          headers:
> +            Link:
> +              $ref: '#/components/headers/Link'
> +          content:
> +            application/json:
> +              schema:
> +                type: array
> +                items:
> +                  $ref: '#/components/schemas/User'
> +        '403':
> +          description: 'Forbidden'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - users
> +  /api/1.4/users/{id}:
> +    parameters:
> +      - in: path
> +        name: id
> +        description: A unique integer value identifying this user.
> +        required: true
> +        schema:
> +          title: ID
> +          type: integer
> +    get:
> +      summary: Show a user.
> +      description: |
> +        Retrieve a user by their ID.
> +      operationId: users_read
> +      security:
> +        - basicAuth: []
> +        - apiKeyAuth: []
> +      responses:
> +        '200':
> +          description: 'A user'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/UserDetail'
> +        '403':
> +          description: 'Forbidden'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - users
> +    patch:
> +      summary: Update a user (partial).
> +      description:
> +        Partially update a user account.
> +        Only super users are allowed to update other user's accounts.
> +      operationId: users_partial_update
> +      security:
> +        - basicAuth: []
> +        - apiKeyAuth: []
> +      requestBody:
> +        $ref: '#/components/requestBodies/User'
> +      responses:
> +        '200':
> +          description: 'Updated user'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/UserDetail'
> +        '400':
> +          description: 'Bad request'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/ErrorUserUpdate'
> +        '403':
> +          description: 'Forbidden'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - users
> +    put:
> +      description: Update a user.
> +      operationId: users_update
> +      security:
> +        - basicAuth: []
> +        - apiKeyAuth: []
> +      requestBody:
> +        $ref: '#/components/requestBodies/User'
> +      responses:
> +        '200':
> +          description: 'Updated user'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/UserDetail'
> +        '400':
> +          description: 'Bad request'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/ErrorUserUpdate'
> +        '403':
> +          description: 'Forbidden'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +        '404':
> +          description: 'Not found'
> +          content:
> +            application/json:
> +              schema:
> +                $ref: '#/components/schemas/Error'
> +      tags:
> +        - users
> +components:
> +  securitySchemes:
> +    basicAuth:
> +      type: http
> +      scheme: basic
> +      description: |
> +        Basic authentication. This should be avoided and may be removed in a future API release.
> +    apiKeyAuth:
> +      type: http
> +      scheme: token
> +      description: |
> +        Token-based authentication.
> +    cookieAuth:
> +      type: apiKey
> +      in: cookie
> +      name: JSESSIONID
> +      description: |
> +        Cookie-based authentication. This is mainly used for the browsable API.
> +  parameters:
> +    Page:
> +      in: query
> +      name: page
> +      description: A page number within the paginated result set.
> +      schema:
> +        title: Page
> +        type: integer
> +    PageSize:
> +      in: query
> +      name: per_page
> +      description: Number of results to return per page.
> +      schema:
> +        title: Page size
> +        type: integer
> +    Order:
> +      in: query
> +      name: order
> +      description: Which field to use when ordering the results.
> +      schema:
> +        title: Ordering
> +        type: string
> +    Search:
> +      in: query
> +      name: q
> +      description: A search term.
> +      schema:
> +        title: Search
> +        type: string
> +    BeforeFilter:
> +      in: query
> +      name: before
> +      description: Latest date-time to retrieve results for.
> +      schema:
> +        title: ''
> +        type: string
> +    SinceFilter:
> +      in: query
> +      name: since
> +      description: Earliest date-time to retrieve results for.
> +      schema:
> +        title: ''
> +        type: string
> +  headers:
> +    Link:
> +      description: |
> +        Links to related resources, in the format defined by
> +        [RFC 5988](https://tools.ietf.org/html/rfc5988#section-5).
> +        This will include a link with relation type `next` to the
> +        next page and `prev` to the previous page, if there is a next
> +        or previous page. It will also include links with the
> +        relation type `first` and `last` pointing to the first and
> +        last page, respectively.
> +      schema:
> +        type: string
> +  requestBodies:
> +    Bundle:
> +      required: true
> +      description: |
> +        A patch bundle.
> +      content:
> +        application/json:
> +          schema:
> +            $ref: '#/components/schemas/BundleCreateUpdate'
> +        multipart/form-data:
> +          schema:
> +            $ref: '#/components/schemas/BundleCreateUpdate'
> +        application/x-www-form-urlencoded:
> +          schema:
> +            $ref: '#/components/schemas/BundleCreateUpdate'
> +    Check:
> +      required: true
> +      description: |
> +        A patch check.
> +      content:
> +        application/json:
> +          schema:
> +            $ref: '#/components/schemas/CheckCreate'
> +        multipart/form-data:
> +          schema:
> +            $ref: '#/components/schemas/CheckCreate'
> +        application/x-www-form-urlencoded:
> +          schema:
> +            $ref: '#/components/schemas/CheckCreate'
> +    Comment:
> +      required: true
> +      description: |
> +        A patch or cover letter comment.
> +      content:
> +        application/json:
> +          schema:
> +            $ref: '#/components/schemas/CommentUpdate'
> +    Patch:
> +      required: true
> +      description: |
> +        A patch.
> +      content:
> +        application/json:
> +          schema:
> +            $ref: '#/components/schemas/PatchUpdate'
> +        multipart/form-data:
> +          schema:
> +            $ref: '#/components/schemas/PatchUpdate'
> +        application/x-www-form-urlencoded:
> +          schema:
> +            $ref: '#/components/schemas/PatchUpdate'
> +    Project:
> +      required: true
> +      description: |
> +        A project.
> +      content:
> +        application/json:
> +          schema:
> +            $ref: '#/components/schemas/Project'
> +        multipart/form-data:
> +          schema:
> +            $ref: '#/components/schemas/Project'
> +        application/x-www-form-urlencoded:
> +          schema:
> +            $ref: '#/components/schemas/Project'
> +    User:
> +      required: true
> +      description: |
> +        A user.
> +      content:
> +        application/json:
> +          schema:
> +            $ref: '#/components/schemas/UserDetail'
> +        multipart/form-data:
> +          schema:
> +            $ref: '#/components/schemas/UserDetail'
> +        application/x-www-form-urlencoded:
> +          schema:
> +            $ref: '#/components/schemas/UserDetail'
> +  schemas:
> +    Index:
> +      type: object
> +      name: Index
> +      description: |
> +        Paths to resource APIs
> +      properties:
> +        bundles:
> +          title: Bundles URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        covers:
> +          title: Covers URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        events:
> +          title: Events URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        patches:
> +          title: Patches URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        people:
> +          title: People URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        projects:
> +          title: Projects URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        users:
> +          title: Users URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        series:
> +          title: Series URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +    Bundle:
> +      required:
> +        - name
> +      type: object
> +      title: Bundle
> +      description: |
> +        A patch bundle
> +      properties:
> +        id:
> +          title: ID
> +          type: integer
> +          readOnly: true
> +        url:
> +          title: URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        web_url:
> +          title: Web URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        project:
> +          $ref: '#/components/schemas/ProjectEmbedded'
> +        name:
> +          title: Name
> +          type: string
> +          minLength: 1
> +          maxLength: 50
> +        owner:
> +          title: Owner
> +          readOnly: true
> +          type:
> +            - 'null'
> +            - 'object'
> +          oneOf:
> +            - type: 'null'
> +            - $ref: '#/components/schemas/UserEmbedded'
> +        patches:
> +          title: Patches
> +          type: array
> +          items:
> +            $ref: '#/components/schemas/PatchEmbedded'
> +          uniqueItems: true
> +        public:
> +          title: Public
> +          type: boolean
> +        mbox:
> +          title: Mbox
> +          description: |
> +            A URL to download the bundle in mbox format. Patches will be
> +            ordered in the same order that they are defined in the bundle.
> +          type: string
> +          format: uri
> +          readOnly: true
> +    BundleCreateUpdate:
> +      type: object
> +      title: Bundle create or update
> +      description: |
> +        The fields to set on a new or existing bundle.
> +      required:
> +        - name
> +      properties:
> +        name:
> +          title: Name
> +          type: string
> +          minLength: 1
> +          maxLength: 50
> +        patches:
> +          title: Patches
> +          type: array
> +          items:
> +            type: integer
> +          uniqueItems: true
> +        public:
> +          title: Public
> +          type: boolean
> +    Check:
> +      type: object
> +      title: Check
> +      description: |
> +        A patch check
> +      properties:
> +        id:
> +          title: ID
> +          type: integer
> +          readOnly: true
> +        url:
> +          title: Url
> +          type: string
> +          format: uri
> +          readOnly: true
> +        user:
> +          $ref: '#/components/schemas/UserEmbedded'
> +        date:
> +          title: Date
> +          type: string
> +          format: iso8601
> +          readOnly: true
> +        state:
> +          title: State
> +          description: The state of the check.
> +          type: string
> +          enum:
> +            - pending
> +            - success
> +            - warning
> +            - fail
> +        target_url:
> +          title: Target URL
> +          description: |
> +            The target URL to associate with this check. This should be
> +            specific to the patch.
> +          type:
> +            - 'null'
> +            - 'string'
> +          oneOf:
> +            - type: 'null'
> +            - type: string
> +              format: uri
> +              maxLength: 200
> +        context:
> +          title: Context
> +          description: |
> +            A label to discern check from checks of other testing systems.
> +          type: string
> +          pattern: ^[-a-zA-Z0-9_]+$
> +          minLength: 1
> +          maxLength: 255
> +        description:
> +          title: Description
> +          description: A brief description of the check.
> +          type:
> +            - 'null'
> +            - 'string'
> +    CheckCreate:
> +      type: object
> +      title: Check
> +      description: |
> +        A patch check
> +      required:
> +       - state
> +      properties:
> +        state:
> +          title: State
> +          description: The state of the check.
> +          type: string
> +          enum:
> +            - pending
> +            - success
> +            - warning
> +            - fail
> +        target_url:
> +          title: Target URL
> +          description: |
> +            The target URL to associate with this check. This should be
> +            specific to the patch.
> +          type:
> +            - 'null'
> +            - 'string'
> +          oneOf:
> +            - type: 'null'
> +            - type: string
> +              format: uri
> +              maxLength: 200
> +        context:
> +          title: Context
> +          description: |
> +            A label to discern check from checks of other testing systems.
> +          type: string
> +          pattern: ^[-a-zA-Z0-9_]+$
> +          minLength: 1
> +          maxLength: 255
> +        description:
> +          title: Description
> +          description: A brief description of the check.
> +          type:
> +            - 'null'
> +            - 'string'
> +    Comment:
> +      type: object
> +      title: Comment
> +      description: |
> +        A comment
> +      properties:
> +        id:
> +          title: ID
> +          type: integer
> +          readOnly: true
> +        url:
> +          title: URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        web_url:
> +          title: Web URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        msgid:
> +          title: Message ID
> +          type: string
> +          readOnly: true
> +          minLength: 1
> +          maxLength: 255
> +        list_archive_url:
> +          title: List archive URL
> +          readOnly: true
> +          type:
> +            - 'null'
> +            - 'string'
> +          oneOf:
> +            - type: 'null'
> +            - type: string
> +              format: uri
> +              maxLength: 2000
> +        date:
> +          title: Date
> +          type: string
> +          format: iso8601
> +          readOnly: true
> +        subject:
> +          title: Subject
> +          type: string
> +          readOnly: true
> +        submitter:
> +          type: object
> +          title: Submitter
> +          readOnly: true
> +          allOf:
> +            - $ref: '#/components/schemas/PersonEmbedded'
> +        content:
> +          title: Content
> +          type: string
> +          readOnly: true
> +          minLength: 1
> +        headers:
> +          title: Headers
> +          anyOf:
> +            - type: object
> +              additionalProperties:
> +                type: array
> +                items:
> +                  type: string
> +            - type: object
> +              additionalProperties:
> +                type: string
> +          readOnly: true
> +        addressed:
> +          title: Addressed
> +          type:
> +            - 'null'
> +            - 'boolean'
> +    CommentUpdate:
> +      type: object
> +      title: Comment update
> +      description: |
> +        The fields to set on an existing comment.
> +      properties:
> +        addressed:
> +          title: Addressed
> +          type:
> +            - 'null'
> +            - 'boolean'
> +    CoverList:
> +      type: object
> +      title: Cover letters
> +      description: |
> +        A list of cover letters
> +      properties:
> +        id:
> +          title: ID
> +          type: integer
> +          readOnly: true
> +        url:
> +          title: URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        web_url:
> +          title: Web URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        project:
> +          $ref: '#/components/schemas/ProjectEmbedded'
> +        msgid:
> +          title: Message ID
> +          type: string
> +          readOnly: true
> +          minLength: 1
> +          maxLength: 255
> +        list_archive_url:
> +          title: List archive URL
> +          readOnly: true
> +          type:
> +            - 'null'
> +            - 'string'
> +          oneOf:
> +            - type: 'null'
> +            - type: string
> +              format: uri
> +              maxLength: 2000
> +        date:
> +          title: Date
> +          type: string
> +          format: iso8601
> +          readOnly: true
> +        name:
> +          title: Name
> +          type: string
> +          readOnly: true
> +          minLength: 1
> +          maxLength: 255
> +        submitter:
> +          type: object
> +          title: Submitter
> +          readOnly: true
> +          allOf:
> +            - $ref: '#/components/schemas/PersonEmbedded'
> +        mbox:
> +          title: Mbox
> +          description: |
> +            A URL to download the cover letter in mbox format.
> +          type: string
> +          format: uri
> +          readOnly: true
> +        series:
> +          type: array
> +          items:
> +            $ref: '#/components/schemas/SeriesEmbedded'
> +          readOnly: true
> +        comments:
> +          title: Comments
> +          type: string
> +          format: uri
> +          readOnly: true
> +    CoverDetail:
> +      type: object
> +      title: Cover letters
> +      description: |
> +        A list of cover letters
> +      allOf:
> +        - $ref: '#/components/schemas/CoverList'
> +        - type: object
> +          properties:
> +            headers:
> +              title: Headers
> +              anyOf:
> +                - type: object
> +                  additionalProperties:
> +                    type: array
> +                    items:
> +                      type: string
> +                - type: object
> +                  additionalProperties:
> +                    type: string
> +              readOnly: true
> +            content:
> +              title: Content
> +              type: string
> +              readOnly: true
> +              minLength: 1
> +    EventBase:
> +      type: object
> +      title: Event base
> +      description: |
> +        Base event. Not directly used.
> +      properties:
> +        id:
> +          title: ID
> +          type: integer
> +          readOnly: true
> +        category:
> +          title: Category
> +          description: The category of the event.
> +          type: string
> +          readOnly: true
> +        project:
> +          $ref: '#/components/schemas/ProjectEmbedded'
> +        date:
> +          title: Date
> +          description: The time this event was created.
> +          type: string
> +          format: iso8601
> +          readOnly: true
> +        actor:
> +          title: Actor
> +          description: The user that caused/created this event.
> +          readOnly: true
> +          type:
> +            - 'null'
> +            - 'object'
> +          oneOf:
> +            - type: 'null'
> +            - $ref: '#/components/schemas/UserEmbedded'
> +        payload:
> +          type: object
> +    EventCoverCreated:
> +      title: Cover created event
> +      description: |
> +        A cover created event.
> +      allOf:
> +        - $ref: '#/components/schemas/EventBase'
> +        - type: object
> +          properties:
> +            category:
> +              enum:
> +                - cover-created
> +            payload:
> +              properties:
> +                cover:
> +                  $ref: '#/components/schemas/CoverEmbedded'
> +    EventPatchCreated:
> +      title: Patch created event
> +      description: |
> +        A patch created event.
> +      allOf:
> +        - $ref: '#/components/schemas/EventBase'
> +        - type: object
> +          properties:
> +            category:
> +              enum:
> +                - patch-created
> +            payload:
> +              properties:
> +                patch:
> +                  $ref: '#/components/schemas/PatchEmbedded'
> +    EventPatchCompleted:
> +      title: Patch completed event
> +      description: |
> +        A patch completed event.
> +      allOf:
> +        - $ref: '#/components/schemas/EventBase'
> +        - type: object
> +          properties:
> +            category:
> +              enum:
> +                - patch-completed
> +            payload:
> +              properties:
> +                patch:
> +                  $ref: '#/components/schemas/PatchEmbedded'
> +                series:
> +                  $ref: '#/components/schemas/SeriesEmbedded'
> +    EventPatchStateChanged:
> +      title: Patch state change event
> +      description: |
> +        A patch state changed event.
> +      allOf:
> +        - $ref: '#/components/schemas/EventBase'
> +        - type: object
> +          properties:
> +            category:
> +              enum:
> +                - patch-state-changed
> +            payload:
> +              properties:
> +                patch:
> +                  $ref: '#/components/schemas/PatchEmbedded'
> +                previous_state:
> +                  title: Previous state
> +                  type: string
> +                current_state:
> +                  title: Current state
> +                  type: string
> +    EventPatchRelationChanged:
> +      title: Patch relation change event
> +      description: |
> +        A patch relation changed event.
> +      allOf:
> +        - $ref: '#/components/schemas/EventBase'
> +        - type: object
> +          properties:
> +            category:
> +              enum:
> +                - patch-relation-changed
> +            payload:
> +              properties:
> +                patch:
> +                  $ref: '#/components/schemas/PatchEmbedded'
> +                previous_relation:
> +                  title: Previous relation
> +                  type:
> +                    - 'null'
> +                    - 'string'
> +                current_relation:
> +                  title: Current relation
> +                  type:
> +                    - 'null'
> +                    - 'string'
> +    EventPatchDelegated:
> +      title: Patch delegated event
> +      description: |
> +        A patch delegated event.
> +      allOf:
> +        - $ref: '#/components/schemas/EventBase'
> +        - type: object
> +          properties:
> +            category:
> +              enum:
> +                - patch-delegated
> +            payload:
> +              properties:
> +                patch:
> +                  $ref: '#/components/schemas/PatchEmbedded'
> +                previous_delegate:
> +                  title: Previous delegate
> +                  type:
> +                    - 'null'
> +                    - 'object'
> +                  oneOf:
> +                    - type: 'null'
> +                    - $ref: '#/components/schemas/UserEmbedded'
> +                current_delegate:
> +                  title: Current delegate
> +                  type:
> +                    - 'null'
> +                    - 'object'
> +                  oneOf:
> +                    - type: 'null'
> +                    - $ref: '#/components/schemas/UserEmbedded'
> +    EventCheckCreated:
> +      title: Check create event
> +      description: |
> +        A check created event.
> +      allOf:
> +        - $ref: '#/components/schemas/EventBase'
> +        - type: object
> +          properties:
> +            category:
> +              enum:
> +                - check-created
> +            payload:
> +              properties:
> +                patch:
> +                  $ref: '#/components/schemas/PatchEmbedded'
> +                check:
> +                  $ref: '#/components/schemas/CheckEmbedded'
> +    EventSeriesCreated:
> +      title: Series create event
> +      description: |
> +        A series created event.
> +      allOf:
> +        - $ref: '#/components/schemas/EventBase'
> +        - type: object
> +          properties:
> +            category:
> +              enum:
> +                - series-created
> +            payload:
> +              properties:
> +                series:
> +                  $ref: '#/components/schemas/SeriesEmbedded'
> +    EventSeriesCompleted:
> +      title: Series completed event
> +      description: |
> +        A series completed event.
> +      allOf:
> +        - $ref: '#/components/schemas/EventBase'
> +        - type: object
> +          properties:
> +            category:
> +              enum:
> +                - series-completed
> +            payload:
> +              properties:
> +                series:
> +                  $ref: '#/components/schemas/SeriesEmbedded'
> +    EventCoverCommentCreated:
> +      title: Cover letter comment create event
> +      description: |
> +        A comment letter comment created event.
> +      allOf:
> +        - $ref: '#/components/schemas/EventBase'
> +        - type: object
> +          properties:
> +            category:
> +              enum:
> +                - cover-comment-created
> +            payload:
> +              properties:
> +                cover:
> +                  $ref: '#/components/schemas/CoverEmbedded'
> +                comment:
> +                  $ref: '#/components/schemas/CommentEmbedded'
> +    EventPatchCommentCreated:
> +      title: Patch comment create event
> +      description: |
> +        A patch comment created event.
> +      allOf:
> +        - $ref: '#/components/schemas/EventBase'
> +        - type: object
> +          properties:
> +            category:
> +              enum:
> +                - patch-comment-created
> +            payload:
> +              properties:
> +                patch:
> +                  $ref: '#/components/schemas/PatchEmbedded'
> +                comment:
> +                  $ref: '#/components/schemas/CommentEmbedded'
> +    PatchList:
> +      required:
> +        - state
> +        - delegate
> +      type: object
> +      title: Patches
> +      description: |
> +        A list of patches.
> +      properties:
> +        id:
> +          title: ID
> +          type: integer
> +          readOnly: true
> +        url:
> +          title: URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        web_url:
> +          title: Web URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        project:
> +          $ref: '#/components/schemas/ProjectEmbedded'
> +        msgid:
> +          title: Message ID
> +          type: string
> +          readOnly: true
> +          minLength: 1
> +          maxLength: 255
> +        list_archive_url:
> +          title: List archive URL
> +          readOnly: true
> +          type:
> +            - 'null'
> +            - 'string'
> +          oneOf:
> +            - type: 'null'
> +            - type: string
> +              format: uri
> +              maxLength: 2000
> +        date:
> +          title: Date
> +          type: string
> +          format: iso8601
> +          readOnly: true
> +        name:
> +          title: Name
> +          type: string
> +          readOnly: true
> +          minLength: 1
> +          maxLength: 255
> +        commit_ref:
> +          title: Commit ref
> +          type:
> +            - 'null'
> +            - 'string'
> +          oneOf:
> +            - type: 'null'
> +            - type: string
> +              maxLength: 255
> +        pull_url:
> +          title: Pull URL
> +          type:
> +            - 'null'
> +            - 'string'
> +          oneOf:
> +            - type: 'null'
> +            - type: string
> +              format: uri
> +              maxLength: 255
> +        state:
> +          title: State
> +          type: string
> +        archived:
> +          title: Archived
> +          type: boolean
> +        hash:
> +          title: Hash
> +          type: string
> +          readOnly: true
> +          minLength: 1
> +        submitter:
> +          type: object
> +          title: Submitter
> +          readOnly: true
> +          allOf:
> +            - $ref: '#/components/schemas/PersonEmbedded'
> +        delegate:
> +          title: Delegate
> +          readOnly: true
> +          type:
> +            - 'null'
> +            - 'object'
> +          oneOf:
> +            - type: 'null'
> +            - $ref: '#/components/schemas/UserEmbedded'
> +        mbox:
> +          title: Mbox
> +          description: |
> +            A URL to download the patch in mbox format. Add the `series=*`
> +            querystring parameter to include series dependencies in the mbox
> +            file.
> +          type: string
> +          format: uri
> +          readOnly: true
> +        series:
> +          type: array
> +          items:
> +            $ref: '#/components/schemas/SeriesEmbedded'
> +          readOnly: true
> +        comments:
> +          title: Comments
> +          type: string
> +          format: uri
> +          readOnly: true
> +        check:
> +          title: Check
> +          type: string
> +          readOnly: true
> +          enum:
> +            - pending
> +            - success
> +            - warning
> +            - fail
> +        checks:
> +          title: Checks
> +          type: string
> +          format: uri
> +          readOnly: true
> +        tags:
> +          title: Tags
> +          type: object
> +          additionalProperties:
> +            type: string
> +          readOnly: true
> +        related:
> +          title: Relations
> +          type: array
> +          items:
> +            $ref: '#/components/schemas/PatchEmbedded'
> +    PatchDetail:
> +      type: object
> +      title: Patches
> +      description: |
> +        A list of patches.
> +      allOf:
> +        - $ref: '#/components/schemas/PatchList'
> +        - type: object
> +          properties:
> +            headers:
> +              title: Headers
> +              anyOf:
> +                - type: object
> +                  additionalProperties:
> +                    type: array
> +                    items:
> +                      type: string
> +                - type: object
> +                  additionalProperties:
> +                    type: string
> +              readOnly: true
> +            content:
> +              title: Content
> +              type: string
> +              readOnly: true
> +              minLength: 1
> +            diff:
> +              title: Diff
> +              type: string
> +              readOnly: true
> +              minLength: 1
> +            prefixes:
> +              title: Prefixes
> +              type: array
> +              items:
> +                type: string
> +              readOnly: true
> +    PatchUpdate:
> +      type: object
> +      title: Patch update
> +      description: |
> +        The fields to set on an existing patch.
> +      properties:
> +        commit_ref:
> +          title: Commit ref
> +          type:
> +            - 'null'
> +            - 'string'
> +          oneOf:
> +            - type: 'null'
> +            - type: string
> +              maxLength: 255
> +        pull_url:
> +          title: Pull URL
> +          type:
> +            - 'null'
> +            - 'string'
> +          oneOf:
> +            - type: 'null'
> +            - type: string
> +              format: uri
> +              maxLength: 255
> +        state:
> +          title: State
> +          type: string
> +        archived:
> +          title: Archived
> +          type: boolean
> +        delegate:
> +          title: Delegate
> +          type:
> +            - 'null'
> +            - 'integer'
> +        related:
> +          title: Relations
> +          type: array
> +          items:
> +            type: integer
> +    Person:
> +      type: object
> +      title: Person
> +      description: |
> +        A person
> +      properties:
> +        id:
> +          title: ID
> +          type: integer
> +          readOnly: true
> +        url:
> +          title: URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        name:
> +          title: Name
> +          type: string
> +          readOnly: true
> +          minLength: 1
> +          maxLength: 255
> +        email:
> +          title: Email
> +          type: string
> +          format: email
> +          readOnly: true
> +          minLength: 1
> +          maxLength: 255
> +        user:
> +          title: User
> +          readOnly: true
> +          type:
> +            - 'null'
> +            - 'object'
> +          oneOf:
> +            - type: 'null'
> +            - $ref: '#/components/schemas/UserEmbedded'
> +    Project:
> +      type: object
> +      title: Project
> +      description: |
> +        A project.
> +      properties:
> +        id:
> +          title: ID
> +          type: integer
> +          readOnly: true
> +        url:
> +          title: URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        name:
> +          title: Name
> +          type: string
> +          readOnly: true
> +          minLength: 1
> +          maxLength: 255
> +        link_name:
> +          title: Link name
> +          type: string
> +          readOnly: true
> +          minLength: 1
> +          maxLength: 255
> +        list_id:
> +          title: List ID
> +          type: string
> +          readOnly: true
> +          minLength: 1
> +          maxLength: 255
> +        list_email:
> +          title: List email
> +          type: string
> +          format: email
> +          readOnly: true
> +          minLength: 1
> +          maxLength: 200
> +        web_url:
> +          title: Web URL
> +          type: string
> +          format: uri
> +          maxLength: 2000
> +        scm_url:
> +          title: SCM URL
> +          type: string
> +          format: uri
> +          maxLength: 2000
> +        webscm_url:
> +          title: Web SCM URL
> +          type: string
> +          format: uri
> +          maxLength: 2000
> +        maintainers:
> +          type: array
> +          items:
> +            $ref: '#/components/schemas/UserEmbedded'
> +          readOnly: true
> +          uniqueItems: true
> +        subject_match:
> +          title: Subject match
> +          description: |
> +            Regex to match the subject against if only part of emails sent to
> +            the list belongs to this project. Will be used with IGNORECASE and
> +            MULTILINE flags. If rules for more projects match the first one
> +            returned from DB is chosen; empty field serves as a default for
> +            every email which has no other match.
> +          type: string
> +          readOnly: true
> +          maxLength: 64
> +        list_archive_url:
> +          title: List archive URL
> +          type:
> +            - 'null'
> +            - 'string'
> +          oneOf:
> +            - type: 'null'
> +            - type: string
> +              format: uri
> +              maxLength: 2000
> +        list_archive_url_format:
> +          title: List archive URL format
> +          description: |
> +            URL format for the list archive's Message-ID redirector. {} will be
> +            replaced by the Message-ID.
> +          type:
> +            - 'null'
> +            - 'string'
> +          oneOf:
> +            - type: 'null'
> +            - type: string
> +              format: uri
> +              maxLength: 2000
> +        commit_url_format:
> +          title: Web SCM URL format for a particular commit
> +          type: string
> +    Series:
> +      type: object
> +      title: Series
> +      description: |
> +        A series
> +      properties:
> +        id:
> +          title: ID
> +          type: integer
> +          readOnly: true
> +        url:
> +          title: URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        web_url:
> +          title: Web URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        project:
> +          $ref: '#/components/schemas/ProjectEmbedded'
> +        name:
> +          title: Name
> +          description: |
> +            An optional name to associate with the series, e.g. "John's PCI
> +            series".
> +          type:
> +            - 'null'
> +            - 'string'
> +          oneOf:
> +            - type: 'null'
> +            - type: 'string'
> +              maxLength: 255
> +        date:
> +          title: Date
> +          type: string
> +          format: iso8601
> +          readOnly: true
> +        submitter:
> +          type: object
> +          title: Submitter
> +          readOnly: true
> +          allOf:
> +            - $ref: '#/components/schemas/PersonEmbedded'
> +        version:
> +          title: Version
> +          description: |
> +            Version of series as indicated by the subject prefix(es).
> +          type: integer
> +        total:
> +          title: Total
> +          description: |
> +            Number of patches in series as indicated by the subject prefix(es).
> +          type: integer
> +          readOnly: true
> +        received_total:
> +          title: Received total
> +          type: integer
> +          readOnly: true
> +        received_all:
> +          title: Received all
> +          type: boolean
> +          readOnly: true
> +        mbox:
> +          title: Mbox
> +          description: |
> +            A URL to download the series in mbox format.
> +          type: string
> +          format: uri
> +          readOnly: true
> +        cover_letter:
> +          $ref: '#/components/schemas/CoverEmbedded'
> +        patches:
> +          title: Patches
> +          type: array
> +          items:
> +            $ref: '#/components/schemas/PatchEmbedded'
> +          readOnly: true
> +          uniqueItems: true
> +        dependencies:
> +          title: Dependencies
> +          type: array
> +          items:
> +            type: string
> +            format: url
> +          readOnly: true
> +          uniqueItems: true
> +        dependents:
> +          title: Dependents
> +          type: array
> +          items:
> +            type: string
> +            format: url
> +          readOnly: true
> +          uniqueItems: true
> +    User:
> +      type: object
> +      title: User
> +      description: |
> +        A user
> +      properties:
> +        id:
> +          title: ID
> +          type: integer
> +          readOnly: true
> +        url:
> +          title: URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        username:
> +          title: Username
> +          type: string
> +          readOnly: true
> +          minLength: 1
> +          maxLength: 150
> +        first_name:
> +          title: First name
> +          type: string
> +          maxLength: 30
> +        last_name:
> +          title: Last name
> +          type: string
> +          maxLength: 150
> +        email:
> +          title: Email address
> +          type: string
> +          format: email
> +          readOnly: true
> +          minLength: 1
> +    UserDetail:
> +      type: object
> +      title: User
> +      description: |
> +        A user
> +      allOf:
> +        - $ref: '#/components/schemas/User'
> +        - type: object
> +          properties:
> +            settings:
> +              type: object
> +              properties:
> +                send_email:
> +                  title: Send email
> +                  description: |
> +                    Whether Patchwork should send email on your behalf.
> +                    Only present and configurable for your account.
> +                  type: boolean
> +                items_per_page:
> +                  title: Items per page
> +                  description: |
> +                    Number of items to display per page (web UI).
> +                    Only present and configurable for your account.
> +                  type: integer
> +                show_ids:
> +                  title: Show IDs
> +                  description: |
> +                    Show click-to-copy IDs in the list view (web UI).
> +                    Only present and configurable for your account.
> +                  type: boolean
> +    CheckEmbedded:
> +      type: object
> +      title: Check
> +      description: |
> +        A patch check
> +      properties:
> +        id:
> +          title: ID
> +          type: integer
> +          readOnly: true
> +        url:
> +          title: Url
> +          type: string
> +          format: uri
> +          readOnly: true
> +        date:
> +          title: Date
> +          type: string
> +          format: iso8601
> +          readOnly: true
> +        state:
> +          title: State
> +          description: The state of the check.
> +          type: string
> +          readOnly: true
> +          enum:
> +            - pending
> +            - success
> +            - warning
> +            - fail
> +        target_url:
> +          title: Target url
> +          description: |
> +            The target URL to associate with this check. This should be specific
> +            to the patch.
> +          readOnly: true
> +          type:
> +            - 'null'
> +            - 'string'
> +          oneOf:
> +            - type: 'null'
> +            - type: string
> +              format: uri
> +              maxLength: 200
> +        context:
> +          title: Context
> +          description: |
> +            A label to discern check from checks of other testing systems.
> +          type: string
> +          pattern: ^[-a-zA-Z0-9_]+$
> +          maxLength: 255
> +          minLength: 1
> +          readOnly: true
> +    CommentEmbedded:
> +      type: object
> +      title: Comment
> +      description: |
> +        A comment
> +      properties:
> +        id:
> +          title: ID
> +          type: integer
> +          readOnly: true
> +        url:
> +          title: URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        web_url:
> +          title: Web URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        msgid:
> +          title: Message ID
> +          type: string
> +          readOnly: true
> +          minLength: 1
> +        list_archive_url:
> +          title: List archive URL
> +          readOnly: true
> +          type:
> +            - 'null'
> +            - 'string'
> +        date:
> +          title: Date
> +          type: string
> +          format: iso8601
> +          readOnly: true
> +        name:
> +          title: Name
> +          type: string
> +          readOnly: true
> +          minLength: 1
> +    CoverEmbedded:
> +      type: object
> +      title: Cover letter
> +      description: |
> +        A cover letter
> +      properties:
> +        id:
> +          title: ID
> +          type: integer
> +          readOnly: true
> +        url:
> +          title: URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        web_url:
> +          title: Web URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        msgid:
> +          title: Message ID
> +          type: string
> +          readOnly: true
> +          minLength: 1
> +        list_archive_url:
> +          title: List archive URL
> +          readOnly: true
> +          type:
> +            - 'null'
> +            - 'string'
> +        date:
> +          title: Date
> +          type: string
> +          format: iso8601
> +          readOnly: true
> +        name:
> +          title: Name
> +          type: string
> +          readOnly: true
> +          minLength: 1
> +        mbox:
> +          title: Mbox
> +          description: |
> +            A URL to download the cover letter in mbox format.
> +          type: string
> +          format: uri
> +          readOnly: true
> +    PatchEmbedded:
> +      type: object
> +      title: Patch
> +      description: |
> +        A patch
> +      properties:
> +        id:
> +          title: ID
> +          type: integer
> +          readOnly: true
> +        url:
> +          title: URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        web_url:
> +          title: Web URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        msgid:
> +          title: Message ID
> +          type: string
> +          readOnly: true
> +          minLength: 1
> +        list_archive_url:
> +          title: List archive URL
> +          readOnly: true
> +          type:
> +            - 'null'
> +            - 'string'
> +        date:
> +          title: Date
> +          type: string
> +          format: iso8601
> +          readOnly: true
> +        name:
> +          title: Name
> +          type: string
> +          readOnly: true
> +          minLength: 1
> +        mbox:
> +          title: Mbox
> +          description: |
> +            A URL to download the patch in mbox format. Add the `series=*`
> +            querystring parameter to include series dependencies in the mbox
> +            file.
> +          type: string
> +          format: uri
> +          readOnly: true
> +    PersonEmbedded:
> +      type: object
> +      title: Person
> +      description: |
> +        A person
> +      properties:
> +        id:
> +          title: ID
> +          type: integer
> +          readOnly: true
> +        url:
> +          title: URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        name:
> +          title: Name
> +          type: string
> +          readOnly: true
> +          minLength: 1
> +        email:
> +          title: Email
> +          type: string
> +          format: email
> +          readOnly: true
> +          minLength: 1
> +    ProjectEmbedded:
> +      type: object
> +      title: Project
> +      description: |
> +        A project
> +      properties:
> +        id:
> +          title: ID
> +          type: integer
> +          readOnly: true
> +        url:
> +          title: URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        name:
> +          title: Name
> +          type: string
> +          readOnly: true
> +          minLength: 1
> +        link_name:
> +          title: Link name
> +          type: string
> +          readOnly: true
> +          maxLength: 255
> +          minLength: 1
> +        list_id:
> +          title: List ID
> +          type: string
> +          readOnly: true
> +          maxLength: 255
> +          minLength: 1
> +        list_email:
> +          title: List email
> +          type: string
> +          format: email
> +          readOnly: true
> +          maxLength: 200
> +          minLength: 1
> +        web_url:
> +          title: Web URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +          maxLength: 2000
> +        scm_url:
> +          title: SCM URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +          maxLength: 2000
> +        webscm_url:
> +          title: WebSCM URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +          maxLength: 2000
> +        list_archive_url:
> +          title: List archive URL
> +          type:
> +            - 'null'
> +            - 'string'
> +          oneOf:
> +            - type: 'null'
> +            - type: string
> +              format: uri
> +              maxLength: 2000
> +        list_archive_url_format:
> +          title: List archive URL format
> +          description: |
> +            URL format for the list archive's Message-ID redirector. {} will be
> +            replaced by the Message-ID.
> +          type:
> +            - 'null'
> +            - 'string'
> +          oneOf:
> +            - type: 'null'
> +            - type: string
> +              format: uri
> +              maxLength: 2000
> +        commit_url_format:
> +          title: Web SCM URL format for a particular commit
> +          type: string
> +          readOnly: true
> +    SeriesEmbedded:
> +      type: object
> +      title: Series
> +      description: |
> +        A series
> +      properties:
> +        id:
> +          title: ID
> +          type: integer
> +          readOnly: true
> +        url:
> +          title: URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        web_url:
> +          title: Web URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        name:
> +          title: Name
> +          description: |
> +            An optional name to associate with the series, e.g. "John's PCI
> +            series".
> +          readOnly: true
> +          type:
> +            - 'null'
> +            - 'string'
> +          oneOf:
> +            - type: 'null'
> +            - type: string
> +              maxLength: 255
> +        date:
> +          title: Date
> +          type: string
> +          format: iso8601
> +          readOnly: true
> +        version:
> +          title: Version
> +          description: |
> +            Version of series as indicated by the subject prefix(es).
> +          type: integer
> +          readOnly: true
> +        mbox:
> +          title: Mbox
> +          description: |
> +            A URL to download the series in mbox format.
> +          type: string
> +          format: uri
> +          readOnly: true
> +    UserEmbedded:
> +      type: object
> +      title: User
> +      description: |
> +        A user
> +      properties:
> +        id:
> +          title: ID
> +          type: integer
> +          readOnly: true
> +        url:
> +          title: URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        username:
> +          title: Username
> +          type: string
> +          readOnly: true
> +          minLength: 1
> +          maxLength: 150
> +        first_name:
> +          title: First name
> +          type: string
> +          maxLength: 30
> +          readOnly: true
> +        last_name:
> +          title: Last name
> +          type: string
> +          maxLength: 150
> +          readOnly: true
> +        email:
> +          title: Email address
> +          type: string
> +          format: email
> +          readOnly: true
> +          minLength: 1
> +    Error:
> +      type: object
> +      title: A generic error.
> +      description: |
> +        A generic error.
> +      properties:
> +        detail:
> +          title: Detail
> +          type: string
> +          readOnly: true
> +    ErrorBundleCreateUpdate:
> +      type: object
> +      title: A bundle creation or update error.
> +      description: |
> +        A mapping of field names to validation failures.
> +      properties:
> +        name:
> +          title: Name
> +          type: array
> +          items:
> +            type: string
> +          readOnly: true
> +        patches:
> +          title: Patches
> +          type: array
> +          items:
> +            type: string
> +          readOnly: true
> +        public:
> +          title: Public
> +          type: array
> +          items:
> +            type: string
> +    ErrorCheckCreate:
> +      type: object
> +      title: A check creation error.
> +      description: |
> +        A mapping of field names to validation failures.
> +      properties:
> +        state:
> +          title: State
> +          type: array
> +          items:
> +            type: string
> +          readOnly: true
> +        target_url:
> +          title: Target URL
> +          type: array
> +          items:
> +            type: string
> +          readOnly: true
> +        context:
> +          title: Context
> +          type: array
> +          items:
> +            type: string
> +          readOnly: true
> +        description:
> +          title: Description
> +          type: array
> +          items:
> +            type: string
> +          readOnly: true
> +    ErrorCommentUpdate:
> +      type: object
> +      title: A comment update error.
> +      description: |
> +        A mapping of field names to validation failures.
> +      properties:
> +        addressed:
> +          title: Addressed
> +          type: array
> +          items:
> +            type: string
> +    ErrorPatchUpdate:
> +      type: object
> +      title: A patch update error.
> +      description: |
> +        A mapping of field names to validation failures.
> +      properties:
> +        state:
> +          title: State
> +          type: array
> +          items:
> +            type: string
> +          readOnly: true
> +        delegate:
> +          title: Delegate
> +          type: array
> +          items:
> +            type: string
> +          readOnly: true
> +        commit_ref:
> +          title: Commit ref
> +          type: array
> +          items:
> +            type: string
> +          readOnly: true
> +        archived:
> +          title: Archived
> +          type: array
> +          items:
> +            type: string
> +          readOnly: true
> +    ErrorProjectUpdate:
> +      type: object
> +      title: A project update error.
> +      description: |
> +        A mapping of field names to validation failures.
> +      properties:
> +        web_url:
> +          title: Web URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        scm_url:
> +          title: SCM URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +        webscm_url:
> +          title: Web SCM URL
> +          type: string
> +          format: uri
> +          readOnly: true
> +    ErrorUserUpdate:
> +      type: object
> +      title: A user update error.
> +      description: |
> +        A mapping of field names to validation failures.
> +      properties:
> +        first_name:
> +          title: First name
> +          type: string
> +          readOnly: true
> +        last_name:
> +          title: First name
> +          type: string
> +          readOnly: true
> +tags:
> +  - name: api
> +    description: General API operations
> +  - name: patches
> +    description: Patch operations
> +  - name: covers
> +    description: Cover letter operations
> +  - name: series
> +    description: Series operations
> +  - name: comments
> +    description: Comment operations
> +  - name: people
> +    description: Submitter operations
> +  - name: users
> +    description: User operations
> +  - name: bundles
> +    description: Bundle operations
> +  - name: projects
> +    description: Project operations
> +  - name: bundles
> +    description: Bundle operations
> +  - name: checks
> +    description: Check operations
> +  - name: events
> +    description: Event operations
> diff --git a/docs/usage/overview.rst b/docs/usage/overview.rst
> index 297569e..7d9d32c 100644
> --- a/docs/usage/overview.rst
> +++ b/docs/usage/overview.rst
> @@ -139,6 +139,18 @@ the email. The following tags are available on a standard Patchwork install:
>  
>        Reviewed-by: Stephen Finucane <stephen at that.guru>
>  
> +Patchwork includes an optional built-in tag for declaring dependencies between
> +series. The series ID, the ID of a patch in a series, or the web URL to either
> +may be used to indicate a dependency. This may be included in the cover letter
> +or any patch file:
> +
> +``Depends-on:``
> +  For example::
> +
> +    Depends-on: series-1234
> +    Depends-on: patch-4567
> +    Depends-on: https://patchwork.example.com/project/testproject/list?series=7890
> +
>  The available tags, along with the significance of said tags, varies from
>  project to project and Patchwork instance to Patchwork instance. The `kernel
>  project documentation`__ provides an overview of the supported tags for the



More information about the Patchwork mailing list