From a345f5fbe1ba81ded7cb7b476d0c7ebb3eca46ed Mon Sep 17 00:00:00 2001 From: Vincent DAMERY Date: Fri, 19 Sep 2025 12:01:10 +0200 Subject: [PATCH 1/3] [docker-hub-api] Add `Create repository` endpoint --- content/reference/api/hub/changelog.md | 13 +++ content/reference/api/hub/deprecated.md | 7 ++ content/reference/api/hub/latest.yaml | 116 ++++++++++++++++++++++++ 3 files changed, 136 insertions(+) diff --git a/content/reference/api/hub/changelog.md b/content/reference/api/hub/changelog.md index 568d9607bf44..b611ceea44d9 100644 --- a/content/reference/api/hub/changelog.md +++ b/content/reference/api/hub/changelog.md @@ -15,6 +15,19 @@ issues for Docker Service APIs. --- +## 2025-09-19 + +### New + +- Add [Create repository](/reference/api/hub/latest/#tag/repositories/operation/CreateRepository) endpoints for a given `namespace`. + +### Deprecations + +- [Deprecate POST /v2/repositories](/reference/api/hub/deprecated/#deprecate-legacy-createrepository) +- [Deprecate POST /v2/repositories/{namespace}](/reference/api/hub/deprecated/#deprecate-legacy-createrepository) + +--- + ## 2025-07-29 ### New diff --git a/content/reference/api/hub/deprecated.md b/content/reference/api/hub/deprecated.md index fc7d1ec78546..cf60618cadfb 100644 --- a/content/reference/api/hub/deprecated.md +++ b/content/reference/api/hub/deprecated.md @@ -28,12 +28,19 @@ The endpoint may be removed, disabled, or change behavior in a future release. | Status | Feature | Date | |------------|---------------------------------------------------------------------------------------|------------| +| Deprecated | [Deprecate undocumented create repository](#deprecate-legacy-createrepository) | 2025-09-19 | | Deprecated | [Deprecate /v2/repositories/{namespace}](#deprecate-legacy-listnamespacerepositories) | 2025-06-27 | | | [Create deprecation log table](#create-deprecation-log-table) | 2025-06-27 | | Removed | [Docker Hub API v1 deprecation](#docker-hub-api-v1-deprecation) | 2022-08-23 | --- +### Deprecate legacy CreateRepository + +Deprecate undocumented endpoint `POST /v2/repositories` and `POST /v2/repositories/{namespace}` replaced by [Create repository](/reference/api/hub/latest/#tag/repositories/operation/CreateRepository). + +--- + ### Deprecate legacy ListNamespaceRepositories Deprecate undocumented endpoint `GET /v2/repositories/{namespace}` replaced by [List repositories](/reference/api/hub/latest/#tag/repositories/operation/listNamespaceRepositories). diff --git a/content/reference/api/hub/latest.yaml b/content/reference/api/hub/latest.yaml index 143521115de5..984d8cd0482f 100644 --- a/content/reference/api/hub/latest.yaml +++ b/content/reference/api/hub/latest.yaml @@ -1129,6 +1129,79 @@ paths: application/json: schema: $ref: "#/components/schemas/error" + post: + summary: Create a new repository + description: | + Creates a new repository within the specified namespace. The repository will be created + with the provided metadata including name, description, and privacy settings. + operationId: CreateRepository + tags: + - repositories + security: + - BearerAuth: [ ] + parameters: + - name: namespace + in: path + required: true + description: The namespace where the repository will be created + schema: + type: string + example: "myorganization" + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/repo_creation_request' + example: + name: "my-app" + namespace: "myorganization" + description: "A sample application repository" + full_description: "This is a comprehensive description of my application repository that contains additional details about the project." + registry: "docker.io" + is_private: false + responses: + 201: + description: Repository created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/repository_info' + example: + name: "my-app" + namespace: "myorganization" + repository_type: "image" + status: 1 + status_description: "Active" + description: "A sample application repository" + is_private: false + is_automated: false + star_count: 0 + pull_count: 0 + last_updated: "2025-01-20T10:30:00Z" + date_registered: "2025-01-20T10:30:00Z" + collaborator_count: 0 + hub_user: "myorganization" + has_starred: false + full_description: "This is a comprehensive description of my application repository that contains additional details about the project." + media_types: [ ] + content_types: [ ] + categories: [ ] + immutable_tags_settings: + enabled: false + rules: [ ] + storage_size: null + source: null + 400: + $ref: "#/components/responses/bad_request" + 401: + $ref: "#/components/responses/unauthorized" + 403: + $ref: "#/components/responses/forbidden" + 404: + $ref: "#/components/responses/not_found" + 500: + $ref: "#/components/responses/internal_error" /v2/orgs/{org_name}/members: parameters: @@ -2240,6 +2313,45 @@ components: required: - immutable_tags - immutable_tags_rules + repo_creation_request: + type: object + required: + - name + - namespace + properties: + name: + type: string + description: | + The name of the repository. Must be 2-255 characters long and may only include + alphanumeric characters, periods (.), underscores (_), or hyphens (-). + Letters must be lowercase. + minLength: 2 + maxLength: 255 + pattern: '^[a-z0-9]+(?:[._-][a-z0-9]+)*$' + example: "my-app" + namespace: + type: string + description: The namespace where the repository will be created + example: "myorganization" + description: + type: string + description: Short description of the repository + maxLength: 100 + example: "A sample application repository" + full_description: + type: string + description: Detailed description of the repository + maxLength: 25000 + example: "This is a comprehensive description of my application repository that contains additional details about the project, its purpose, usage instructions, and other relevant information." + registry: + type: string + description: The registry where the repository will be hosted + example: "docker.io" + is_private: + type: boolean + description: Whether the repository should be private + default: false + example: false repository_info: type: object properties: @@ -2339,6 +2451,10 @@ components: format: int64 nullable: true description: Storage size in bytes + source: + type: string + nullable: true + description: Source of the repository, where it was created from required: - user - name From 93d93a1f7a33c3641d18140797b2bd13e0b75d63 Mon Sep 17 00:00:00 2001 From: Vincent DAMERY Date: Fri, 19 Sep 2025 14:39:00 +0200 Subject: [PATCH 2/3] [docker-hub-api] Add `Get/Check repository` endpoints --- content/reference/api/hub/changelog.md | 4 + content/reference/api/hub/deprecated.md | 19 ++-- content/reference/api/hub/latest.yaml | 115 +++++++++++++++++++++--- 3 files changed, 120 insertions(+), 18 deletions(-) diff --git a/content/reference/api/hub/changelog.md b/content/reference/api/hub/changelog.md index b611ceea44d9..5e56ec77af0f 100644 --- a/content/reference/api/hub/changelog.md +++ b/content/reference/api/hub/changelog.md @@ -20,11 +20,15 @@ issues for Docker Service APIs. ### New - Add [Create repository](/reference/api/hub/latest/#tag/repositories/operation/CreateRepository) endpoints for a given `namespace`. +- Add [Get repository](/reference/api/hub/latest/#tag/repositories/operation/GetRepository) endpoints for a given `namespace`. +- Add [Check repository](/reference/api/hub/latest/#tag/repositories/operation/CheckRepository) endpoints for a given `namespace`. ### Deprecations - [Deprecate POST /v2/repositories](/reference/api/hub/deprecated/#deprecate-legacy-createrepository) - [Deprecate POST /v2/repositories/{namespace}](/reference/api/hub/deprecated/#deprecate-legacy-createrepository) +- [Deprecate GET /v2/repositories/{namespace}/{repository}](/reference/api/hub/deprecated/#deprecate-legacy-getrepository) +- [Deprecate HEAD /v2/repositories/{namespace}/{repository}](/reference/api/hub/deprecated/#deprecate-legacy-getrepository) --- diff --git a/content/reference/api/hub/deprecated.md b/content/reference/api/hub/deprecated.md index cf60618cadfb..a803afb1d6f9 100644 --- a/content/reference/api/hub/deprecated.md +++ b/content/reference/api/hub/deprecated.md @@ -26,18 +26,21 @@ The endpoint may be removed, disabled, or change behavior in a future release. --- -| Status | Feature | Date | -|------------|---------------------------------------------------------------------------------------|------------| -| Deprecated | [Deprecate undocumented create repository](#deprecate-legacy-createrepository) | 2025-09-19 | -| Deprecated | [Deprecate /v2/repositories/{namespace}](#deprecate-legacy-listnamespacerepositories) | 2025-06-27 | -| | [Create deprecation log table](#create-deprecation-log-table) | 2025-06-27 | -| Removed | [Docker Hub API v1 deprecation](#docker-hub-api-v1-deprecation) | 2022-08-23 | +| Status | Feature | Date | +|------------|------------------------------------------------------------------------------------------------------|------------| +| Deprecated | [Deprecate undocumented create/get repository](#deprecate-legacy-createrepository-and-getrepository) | 2025-09-19 | +| Deprecated | [Deprecate /v2/repositories/{namespace}](#deprecate-legacy-listnamespacerepositories) | 2025-06-27 | +| | [Create deprecation log table](#create-deprecation-log-table) | 2025-06-27 | +| Removed | [Docker Hub API v1 deprecation](#docker-hub-api-v1-deprecation) | 2022-08-23 | --- -### Deprecate legacy CreateRepository +### Deprecate legacy CreateRepository and GetRepository -Deprecate undocumented endpoint `POST /v2/repositories` and `POST /v2/repositories/{namespace}` replaced by [Create repository](/reference/api/hub/latest/#tag/repositories/operation/CreateRepository). +Deprecate undocumented endpoints : +- `POST /v2/repositories` and `POST /v2/repositories/{namespace}` replaced by [Create repository](/reference/api/hub/latest/#tag/repositories/operation/CreateRepository). +- `GET /v2/repositories/{namespace}/{repository}` replaced by [Get repository](/reference/api/hub/latest/#tag/repositories/operation/GetRepository). +- `HEAD /v2/repositories/{namespace}/{repository}` replaced by [Check repository](/reference/api/hub/latest/#tag/repositories/operation/CheckRepository). --- diff --git a/content/reference/api/hub/latest.yaml b/content/reference/api/hub/latest.yaml index 984d8cd0482f..3191955b7f8f 100644 --- a/content/reference/api/hub/latest.yaml +++ b/content/reference/api/hub/latest.yaml @@ -1138,15 +1138,7 @@ paths: tags: - repositories security: - - BearerAuth: [ ] - parameters: - - name: namespace - in: path - required: true - description: The namespace where the repository will be created - schema: - type: string - example: "myorganization" + - BearerAuth: [ ] requestBody: required: true content: @@ -1202,7 +1194,110 @@ paths: $ref: "#/components/responses/not_found" 500: $ref: "#/components/responses/internal_error" - + /v2/namespaces/{namespace}/repositories/{repository}: + parameters: + - $ref: "#/components/parameters/namespace" + - $ref: "#/components/parameters/repository" + get: + operationId: GetRepository + summary: Get repository in a namespace + description: | + Returns a repository within the specified namespace (organization or user). + + Public repositories are accessible to everyone, while private repositories require appropriate authentication and permissions. + tags: + - repositories + security: + - bearerAuth: [ ] + - { } # Allow anonymous access for public repositories + 200: + content: + application/json: + schema: + $ref: '#/components/schemas/repository_info' + example: + name: "my-app" + namespace: "myorganization" + repository_type: "image" + status: 1 + status_description: "Active" + description: "A sample application repository" + is_private: false + is_automated: false + star_count: 0 + pull_count: 0 + last_updated: "2025-01-20T10:30:00Z" + date_registered: "2025-01-20T10:30:00Z" + collaborator_count: 0 + hub_user: "myorganization" + has_starred: false + full_description: "This is a comprehensive description of my application repository that contains additional details about the project." + media_types: [ ] + content_types: [ ] + categories: [ ] + immutable_tags_settings: + enabled: false + rules: [ ] + storage_size: null + source: null + 401: + $ref: "#/components/responses/unauthorized" + 403: + $ref: "#/components/responses/forbidden" + 404: + $ref: "#/components/responses/not_found" + 500: + $ref: "#/components/responses/internal_error" + head: + operationId: CheckRepository + summary: Check repository in a namespace + description: | + Check a repository within the specified namespace (organization or user). + + Public repositories are accessible to everyone, while private repositories require appropriate authentication and permissions. + tags: + - repositories + security: + - bearerAuth: [ ] + - { } # Allow anonymous access for public repositories + 200: + content: + application/json: + schema: + $ref: '#/components/schemas/repository_info' + example: + name: "my-app" + namespace: "myorganization" + repository_type: "image" + status: 1 + status_description: "Active" + description: "A sample application repository" + is_private: false + is_automated: false + star_count: 0 + pull_count: 0 + last_updated: "2025-01-20T10:30:00Z" + date_registered: "2025-01-20T10:30:00Z" + collaborator_count: 0 + hub_user: "myorganization" + has_starred: false + full_description: "This is a comprehensive description of my application repository that contains additional details about the project." + media_types: [ ] + content_types: [ ] + categories: [ ] + immutable_tags_settings: + enabled: false + rules: [ ] + storage_size: null + source: null + 401: + $ref: "#/components/responses/unauthorized" + 403: + $ref: "#/components/responses/forbidden" + 404: + $ref: "#/components/responses/not_found" + 500: + $ref: "#/components/responses/internal_error" /v2/orgs/{org_name}/members: parameters: - $ref: "#/components/parameters/org_name" From dcf472aff2f0ace5f5486f4d44cf71627d3375a2 Mon Sep 17 00:00:00 2001 From: Vincent DAMERY Date: Fri, 19 Sep 2025 14:46:43 +0200 Subject: [PATCH 3/3] fixup! missing responses --- content/reference/api/hub/latest.yaml | 154 +++++++++++++------------- 1 file changed, 78 insertions(+), 76 deletions(-) diff --git a/content/reference/api/hub/latest.yaml b/content/reference/api/hub/latest.yaml index 3191955b7f8f..bb6a510746d3 100644 --- a/content/reference/api/hub/latest.yaml +++ b/content/reference/api/hub/latest.yaml @@ -1210,44 +1210,45 @@ paths: security: - bearerAuth: [ ] - { } # Allow anonymous access for public repositories - 200: - content: - application/json: - schema: - $ref: '#/components/schemas/repository_info' - example: - name: "my-app" - namespace: "myorganization" - repository_type: "image" - status: 1 - status_description: "Active" - description: "A sample application repository" - is_private: false - is_automated: false - star_count: 0 - pull_count: 0 - last_updated: "2025-01-20T10:30:00Z" - date_registered: "2025-01-20T10:30:00Z" - collaborator_count: 0 - hub_user: "myorganization" - has_starred: false - full_description: "This is a comprehensive description of my application repository that contains additional details about the project." - media_types: [ ] - content_types: [ ] - categories: [ ] - immutable_tags_settings: - enabled: false - rules: [ ] - storage_size: null - source: null - 401: - $ref: "#/components/responses/unauthorized" - 403: - $ref: "#/components/responses/forbidden" - 404: - $ref: "#/components/responses/not_found" - 500: - $ref: "#/components/responses/internal_error" + responses: + 200: + content: + application/json: + schema: + $ref: '#/components/schemas/repository_info' + example: + name: "my-app" + namespace: "myorganization" + repository_type: "image" + status: 1 + status_description: "Active" + description: "A sample application repository" + is_private: false + is_automated: false + star_count: 0 + pull_count: 0 + last_updated: "2025-01-20T10:30:00Z" + date_registered: "2025-01-20T10:30:00Z" + collaborator_count: 0 + hub_user: "myorganization" + has_starred: false + full_description: "This is a comprehensive description of my application repository that contains additional details about the project." + media_types: [ ] + content_types: [ ] + categories: [ ] + immutable_tags_settings: + enabled: false + rules: [ ] + storage_size: null + source: null + 401: + $ref: "#/components/responses/unauthorized" + 403: + $ref: "#/components/responses/forbidden" + 404: + $ref: "#/components/responses/not_found" + 500: + $ref: "#/components/responses/internal_error" head: operationId: CheckRepository summary: Check repository in a namespace @@ -1260,44 +1261,45 @@ paths: security: - bearerAuth: [ ] - { } # Allow anonymous access for public repositories - 200: - content: - application/json: - schema: - $ref: '#/components/schemas/repository_info' - example: - name: "my-app" - namespace: "myorganization" - repository_type: "image" - status: 1 - status_description: "Active" - description: "A sample application repository" - is_private: false - is_automated: false - star_count: 0 - pull_count: 0 - last_updated: "2025-01-20T10:30:00Z" - date_registered: "2025-01-20T10:30:00Z" - collaborator_count: 0 - hub_user: "myorganization" - has_starred: false - full_description: "This is a comprehensive description of my application repository that contains additional details about the project." - media_types: [ ] - content_types: [ ] - categories: [ ] - immutable_tags_settings: - enabled: false - rules: [ ] - storage_size: null - source: null - 401: - $ref: "#/components/responses/unauthorized" - 403: - $ref: "#/components/responses/forbidden" - 404: - $ref: "#/components/responses/not_found" - 500: - $ref: "#/components/responses/internal_error" + responses: + 200: + content: + application/json: + schema: + $ref: '#/components/schemas/repository_info' + example: + name: "my-app" + namespace: "myorganization" + repository_type: "image" + status: 1 + status_description: "Active" + description: "A sample application repository" + is_private: false + is_automated: false + star_count: 0 + pull_count: 0 + last_updated: "2025-01-20T10:30:00Z" + date_registered: "2025-01-20T10:30:00Z" + collaborator_count: 0 + hub_user: "myorganization" + has_starred: false + full_description: "This is a comprehensive description of my application repository that contains additional details about the project." + media_types: [ ] + content_types: [ ] + categories: [ ] + immutable_tags_settings: + enabled: false + rules: [ ] + storage_size: null + source: null + 401: + $ref: "#/components/responses/unauthorized" + 403: + $ref: "#/components/responses/forbidden" + 404: + $ref: "#/components/responses/not_found" + 500: + $ref: "#/components/responses/internal_error" /v2/orgs/{org_name}/members: parameters: - $ref: "#/components/parameters/org_name"