From 4f348066b8611a0a4c945da3349621e1bf92daa0 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 19 May 2026 09:28:19 +0000 Subject: [PATCH 1/2] docs(branches): align operations with controller behavior Aligns the Branches operations and branch schema with the actual behavior of Api::V2::BranchesController: - Add 401, 403, 422, and 409 responses where reachable across all Branches endpoints; 403 descriptions note the specific conditions (OAuth scope, Pundit, restrict_feature!(:branching)) - Document asynchronous semantics for create, merge, and sync: background jobs, transitional states, empty response bodies for merge/sync, and guidance to poll until state settles - Add base field to create request body and branch schema (nullable, newer-branching system only) - Declare strategy as an enum (use_main, use_branch) in merge and sync - Enumerate the seven public-facing state values in branch schema - Note that the Branching account feature must be enabled on every operation; clarify that update only accepts name --- paths/branches/create.yaml | 17 ++++++++++++++++- paths/branches/destroy.yaml | 17 ++++++++++++++++- paths/branches/index.yaml | 10 +++++++++- paths/branches/merge.yaml | 26 +++++++++++++++++++++++--- paths/branches/show.yaml | 10 +++++++++- paths/branches/sync.yaml | 23 +++++++++++++++++++---- paths/branches/update.yaml | 12 +++++++++++- schemas/branch.yaml | 12 ++++++++++++ 8 files changed, 115 insertions(+), 12 deletions(-) diff --git a/paths/branches/create.yaml b/paths/branches/create.yaml index 6cc27b9a1..950748745 100644 --- a/paths/branches/create.yaml +++ b/paths/branches/create.yaml @@ -2,7 +2,11 @@ summary: Create a branch description: | Create a new branch. - + + Branch project provisioning runs asynchronously, so the newly created branch is returned in a transitional state (typically `creating_branch`) and only reaches `success` once the underlying project has been set up. Poll the branch resource until its `state` becomes `success` before performing further operations on it. + + Requires the Branching feature to be enabled on the account. + *Note: Creating a new branch may take several minutes depending on the project size.* operationId: branch/create tags: @@ -26,8 +30,15 @@ responses: "$ref": "../../headers.yaml#/X-Rate-Limit-Reset" '400': "$ref": "../../responses.yaml#/400" + '401': + "$ref": "../../responses.yaml#/401" + '403': + "$ref": "../../responses.yaml#/403" + description: Forbidden. Returned when the access token lacks the `write` scope, when the user is not allowed to create branches in this project, or when the Branching feature is not available on the account. '404': "$ref": "../../responses.yaml#/404" + '422': + "$ref": "../../responses.yaml#/422" '429': "$ref": "../../responses.yaml#/429" x-code-samples: @@ -58,4 +69,8 @@ requestBody: description: Name of the branch type: string example: my-branch + base: + description: Name of an existing branch to use as the base for the new branch. + type: string + example: parent-branch x-cli-version: '2.5' diff --git a/paths/branches/destroy.yaml b/paths/branches/destroy.yaml index 8ceefe0a7..a2d165be2 100644 --- a/paths/branches/destroy.yaml +++ b/paths/branches/destroy.yaml @@ -1,6 +1,11 @@ --- summary: Delete a branch -description: Delete an existing branch. +description: | + Delete an existing branch. + + A branch cannot be deleted while it still has open jobs or open translation orders attached to its branch project — in that case the request is rejected with `409 Conflict`. A branch whose current `state` does not allow deletion (for example, while a merge or sync is in progress) is rejected with `422 Unprocessable Entity`. + + Requires the Branching feature to be enabled on the account. operationId: branch/delete tags: - Branches @@ -13,8 +18,18 @@ responses: "$ref": "../../responses.yaml#/204" '400': "$ref": "../../responses.yaml#/400" + '401': + "$ref": "../../responses.yaml#/401" + '403': + "$ref": "../../responses.yaml#/403" + description: Forbidden. Returned when the access token lacks the `write` scope, when the user is not allowed to delete this branch, or when the Branching feature is not available on the account. '404': "$ref": "../../responses.yaml#/404" + '409': + "$ref": "../../responses.yaml#/409" + description: Conflict. The branch has open jobs or open translation orders. The response body lists the blockers, for example `{"errors":["open_jobs","open_orders"]}`. Close or complete the listed resources before retrying. + '422': + "$ref": "../../responses.yaml#/422" '429': "$ref": "../../responses.yaml#/429" x-code-samples: diff --git a/paths/branches/index.yaml b/paths/branches/index.yaml index b80656d64..08836350e 100644 --- a/paths/branches/index.yaml +++ b/paths/branches/index.yaml @@ -1,6 +1,9 @@ --- summary: List branches -description: List all branches the of the current project. +description: | + List all branches of the current project. + + Requires the Branching feature to be enabled on the account. operationId: branches/list tags: - Branches @@ -31,6 +34,11 @@ responses: "$ref": "../../headers.yaml#/Pagination" '400': "$ref": "../../responses.yaml#/400" + '401': + "$ref": "../../responses.yaml#/401" + '403': + "$ref": "../../responses.yaml#/403" + description: Forbidden. Returned when the access token lacks the `read` scope, when the user is not allowed to read branches in this project, or when the Branching feature is not available on the account. '404': "$ref": "../../responses.yaml#/404" '429': diff --git a/paths/branches/merge.yaml b/paths/branches/merge.yaml index 53a73d0ce..a09b5be48 100644 --- a/paths/branches/merge.yaml +++ b/paths/branches/merge.yaml @@ -1,7 +1,13 @@ --- summary: Merge a branch description: | - Merge an existing branch. + Merge an existing branch back into its base branch. + + The merge runs asynchronously. The branch transitions to `merging_branch` and settles in `merged`, `merge_error`, or `merge_conflict` once the background job completes; the response body for this request is empty. Poll the branch resource to observe the final state. + + A branch cannot be merged while it still has open jobs or open translation orders attached to its branch project — in that case the request is rejected with `409 Conflict`. A branch whose current `state` does not allow a merge is rejected with `422 Unprocessable Entity`. + + Requires the Branching feature to be enabled on the account. *Note: Merging a branch may take several minutes depending on diff size.* operationId: branch/merge @@ -13,7 +19,7 @@ parameters: - "$ref": "../../parameters.yaml#/name" responses: '200': - description: OK + description: OK. The merge has been scheduled. The response body is empty; observe progress by polling the branch resource. headers: X-Rate-Limit-Limit: "$ref": "../../headers.yaml#/X-Rate-Limit-Limit" @@ -23,8 +29,18 @@ responses: "$ref": "../../headers.yaml#/X-Rate-Limit-Reset" '400': "$ref": "../../responses.yaml#/400" + '401': + "$ref": "../../responses.yaml#/401" + '403': + "$ref": "../../responses.yaml#/403" + description: Forbidden. Returned when the access token lacks the `write` scope, when the user is not allowed to merge this branch, or when the Branching feature is not available on the account. '404': "$ref": "../../responses.yaml#/404" + '409': + "$ref": "../../responses.yaml#/409" + description: Conflict. The branch has open jobs or open translation orders. The response body lists the blockers, for example `{"errors":["open_jobs","open_orders"]}`. Close or complete the listed resources before retrying. + '422': + "$ref": "../../responses.yaml#/422" '429': "$ref": "../../responses.yaml#/429" x-code-samples: @@ -51,6 +67,10 @@ requestBody: title: branch/merge/parameters properties: strategy: - description: strategy used for merge conflicts, use_main or use_branch + description: | + Conflict resolution strategy applied when the branch and its base have diverged. `use_main` keeps the values from the base branch; `use_branch` keeps the values from the branch being merged. type: string + enum: + - use_main + - use_branch example: use_main diff --git a/paths/branches/show.yaml b/paths/branches/show.yaml index 715bf6dbf..06dd80be9 100644 --- a/paths/branches/show.yaml +++ b/paths/branches/show.yaml @@ -1,6 +1,9 @@ --- summary: Get a single branch -description: Get details on a single branch for a given project. +description: | + Get details on a single branch for a given project. + + Requires the Branching feature to be enabled on the account. operationId: branch/show tags: - Branches @@ -24,6 +27,11 @@ responses: "$ref": "../../headers.yaml#/X-Rate-Limit-Reset" '400': "$ref": "../../responses.yaml#/400" + '401': + "$ref": "../../responses.yaml#/401" + '403': + "$ref": "../../responses.yaml#/403" + description: Forbidden. Returned when the access token lacks the `read` scope, when the user is not allowed to read this branch, or when the Branching feature is not available on the account. '404': "$ref": "../../responses.yaml#/404" '429': diff --git a/paths/branches/sync.yaml b/paths/branches/sync.yaml index 0b8c3e8a1..9317f0bb9 100644 --- a/paths/branches/sync.yaml +++ b/paths/branches/sync.yaml @@ -1,9 +1,13 @@ --- summary: Sync a branch description: | - Sync an existing branch. + Pull changes from the base branch into this branch, applying the chosen conflict-resolution strategy. - *Note: Only available for branches created with new branching.* + The sync runs asynchronously. The branch transitions to `syncing_branch` and settles back into `success` (or `merge_conflict` / `branch_error`) once the background job completes; the response body for this request is empty. Poll the branch resource to observe the final state. + + Only branches created with the newer branching system can be synced. Requests against branches from the older system, or against branches whose current state does not allow a sync, are rejected with `422 Unprocessable Entity` and an empty body. + + Requires the Branching feature to be enabled on the account. operationId: branch/sync tags: - Branches @@ -13,7 +17,7 @@ parameters: - "$ref": "../../parameters.yaml#/name" responses: '200': - description: OK + description: OK. The sync has been scheduled. The response body is empty; observe progress by polling the branch resource. headers: X-Rate-Limit-Limit: "$ref": "../../headers.yaml#/X-Rate-Limit-Limit" @@ -23,8 +27,15 @@ responses: "$ref": "../../headers.yaml#/X-Rate-Limit-Reset" '400': "$ref": "../../responses.yaml#/400" + '401': + "$ref": "../../responses.yaml#/401" + '403': + "$ref": "../../responses.yaml#/403" + description: Forbidden. Returned when the access token lacks the `write` scope, when the user is not allowed to sync this branch, or when the Branching feature is not available on the account. '404': "$ref": "../../responses.yaml#/404" + '422': + "$ref": "../../responses.yaml#/422" '429': "$ref": "../../responses.yaml#/429" x-code-samples: @@ -51,6 +62,10 @@ requestBody: title: branch/sync/parameters properties: strategy: - description: strategy used for conflicts, use_main or use_branch + description: | + Conflict resolution strategy applied when the branch and its base have diverged. `use_main` keeps the values from the base branch; `use_branch` keeps the values from this branch. type: string + enum: + - use_main + - use_branch example: use_main diff --git a/paths/branches/update.yaml b/paths/branches/update.yaml index 12de76646..5e4dd58c0 100644 --- a/paths/branches/update.yaml +++ b/paths/branches/update.yaml @@ -1,6 +1,9 @@ --- summary: Update a branch -description: Update an existing branch. +description: | + Update an existing branch. Only the branch name can be changed. + + Requires the Branching feature to be enabled on the account. operationId: branch/update tags: - Branches @@ -24,8 +27,15 @@ responses: "$ref": "../../headers.yaml#/X-Rate-Limit-Reset" '400': "$ref": "../../responses.yaml#/400" + '401': + "$ref": "../../responses.yaml#/401" + '403': + "$ref": "../../responses.yaml#/403" + description: Forbidden. Returned when the access token lacks the `write` scope, when the user is not allowed to update this branch, or when the Branching feature is not available on the account. '404': "$ref": "../../responses.yaml#/404" + '422': + "$ref": "../../responses.yaml#/422" '429': "$ref": "../../responses.yaml#/429" x-code-samples: diff --git a/schemas/branch.yaml b/schemas/branch.yaml index 1ab08976b..75a1e0c10 100644 --- a/schemas/branch.yaml +++ b/schemas/branch.yaml @@ -9,6 +9,10 @@ branch: type: string name: type: string + base: + type: string + nullable: true + description: Name of the base branch this branch was created from. Only present for branches created with the newer branching system. created_at: type: string format: date-time @@ -24,6 +28,14 @@ branch: "$ref": "./user_preview.yaml#/user_preview" state: type: string + enum: + - creating_branch + - merging_branch + - syncing_branch + - merged + - success + - branch_error + - merge_conflict child_branches: type: array items: From 42763b39e9cfd5d4af934210db1022ee249d2438 Mon Sep 17 00:00:00 2001 From: Sven Dunemann Date: Tue, 19 May 2026 11:40:01 +0200 Subject: [PATCH 2/2] chore: recompile bundled JSON --- doc/compiled.json | 123 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 111 insertions(+), 12 deletions(-) diff --git a/doc/compiled.json b/doc/compiled.json index f778ce6a9..97848039e 100644 --- a/doc/compiled.json +++ b/doc/compiled.json @@ -3631,6 +3631,11 @@ "name": { "type": "string" }, + "base": { + "type": "string", + "nullable": true, + "description": "Name of the base branch this branch was created from. Only present for branches created with the newer branching system." + }, "created_at": { "type": "string", "format": "date-time" @@ -3650,7 +3655,16 @@ "$ref": "#/components/schemas/user_preview" }, "state": { - "type": "string" + "type": "string", + "enum": [ + "creating_branch", + "merging_branch", + "syncing_branch", + "merged", + "success", + "branch_error", + "merge_conflict" + ] }, "child_branches": { "type": "array", @@ -18393,7 +18407,7 @@ "/projects/{project_id}/branches": { "get": { "summary": "List branches", - "description": "List all branches the of the current project.", + "description": "List all branches of the current project.\n\nRequires the Branching feature to be enabled on the account.\n", "operationId": "branches/list", "tags": [ "Branches" @@ -18446,6 +18460,13 @@ "400": { "$ref": "#/components/responses/400" }, + "401": { + "$ref": "#/components/responses/401" + }, + "403": { + "$ref": "#/components/responses/403", + "description": "Forbidden. Returned when the access token lacks the `read` scope, when the user is not allowed to read branches in this project, or when the Branching feature is not available on the account." + }, "404": { "$ref": "#/components/responses/404" }, @@ -18467,7 +18488,7 @@ }, "post": { "summary": "Create a branch", - "description": "Create a new branch.\n\n*Note: Creating a new branch may take several minutes depending on the project size.*\n", + "description": "Create a new branch.\n\nBranch project provisioning runs asynchronously, so the newly created branch is returned in a transitional state (typically `creating_branch`) and only reaches `success` once the underlying project has been set up. Poll the branch resource until its `state` becomes `success` before performing further operations on it.\n\nRequires the Branching feature to be enabled on the account.\n\n*Note: Creating a new branch may take several minutes depending on the project size.*\n", "operationId": "branch/create", "tags": [ "Branches" @@ -18505,9 +18526,19 @@ "400": { "$ref": "#/components/responses/400" }, + "401": { + "$ref": "#/components/responses/401" + }, + "403": { + "$ref": "#/components/responses/403", + "description": "Forbidden. Returned when the access token lacks the `write` scope, when the user is not allowed to create branches in this project, or when the Branching feature is not available on the account." + }, "404": { "$ref": "#/components/responses/404" }, + "422": { + "$ref": "#/components/responses/422" + }, "429": { "$ref": "#/components/responses/429" } @@ -18537,6 +18568,11 @@ "description": "Name of the branch", "type": "string", "example": "my-branch" + }, + "base": { + "description": "Name of an existing branch to use as the base for the new branch.", + "type": "string", + "example": "parent-branch" } } } @@ -18549,7 +18585,7 @@ "/projects/{project_id}/branches/{name}": { "get": { "summary": "Get a single branch", - "description": "Get details on a single branch for a given project.", + "description": "Get details on a single branch for a given project.\n\nRequires the Branching feature to be enabled on the account.\n", "operationId": "branch/show", "tags": [ "Branches" @@ -18590,6 +18626,13 @@ "400": { "$ref": "#/components/responses/400" }, + "401": { + "$ref": "#/components/responses/401" + }, + "403": { + "$ref": "#/components/responses/403", + "description": "Forbidden. Returned when the access token lacks the `read` scope, when the user is not allowed to read this branch, or when the Branching feature is not available on the account." + }, "404": { "$ref": "#/components/responses/404" }, @@ -18611,7 +18654,7 @@ }, "patch": { "summary": "Update a branch", - "description": "Update an existing branch.", + "description": "Update an existing branch. Only the branch name can be changed.\n\nRequires the Branching feature to be enabled on the account.\n", "operationId": "branch/update", "tags": [ "Branches" @@ -18652,9 +18695,19 @@ "400": { "$ref": "#/components/responses/400" }, + "401": { + "$ref": "#/components/responses/401" + }, + "403": { + "$ref": "#/components/responses/403", + "description": "Forbidden. Returned when the access token lacks the `write` scope, when the user is not allowed to update this branch, or when the Branching feature is not available on the account." + }, "404": { "$ref": "#/components/responses/404" }, + "422": { + "$ref": "#/components/responses/422" + }, "429": { "$ref": "#/components/responses/429" } @@ -18691,7 +18744,7 @@ }, "delete": { "summary": "Delete a branch", - "description": "Delete an existing branch.", + "description": "Delete an existing branch.\n\nA branch cannot be deleted while it still has open jobs or open translation orders attached to its branch project — in that case the request is rejected with `409 Conflict`. A branch whose current `state` does not allow deletion (for example, while a merge or sync is in progress) is rejected with `422 Unprocessable Entity`.\n\nRequires the Branching feature to be enabled on the account.\n", "operationId": "branch/delete", "tags": [ "Branches" @@ -18714,9 +18767,23 @@ "400": { "$ref": "#/components/responses/400" }, + "401": { + "$ref": "#/components/responses/401" + }, + "403": { + "$ref": "#/components/responses/403", + "description": "Forbidden. Returned when the access token lacks the `write` scope, when the user is not allowed to delete this branch, or when the Branching feature is not available on the account." + }, "404": { "$ref": "#/components/responses/404" }, + "409": { + "$ref": "#/components/responses/409", + "description": "Conflict. The branch has open jobs or open translation orders. The response body lists the blockers, for example `{\"errors\":[\"open_jobs\",\"open_orders\"]}`. Close or complete the listed resources before retrying." + }, + "422": { + "$ref": "#/components/responses/422" + }, "429": { "$ref": "#/components/responses/429" } @@ -18737,7 +18804,7 @@ "/projects/{project_id}/branches/{name}/merge": { "patch": { "summary": "Merge a branch", - "description": "Merge an existing branch.\n\n*Note: Merging a branch may take several minutes depending on diff size.*\n", + "description": "Merge an existing branch back into its base branch.\n\nThe merge runs asynchronously. The branch transitions to `merging_branch` and settles in `merged`, `merge_error`, or `merge_conflict` once the background job completes; the response body for this request is empty. Poll the branch resource to observe the final state.\n\nA branch cannot be merged while it still has open jobs or open translation orders attached to its branch project — in that case the request is rejected with `409 Conflict`. A branch whose current `state` does not allow a merge is rejected with `422 Unprocessable Entity`.\n\nRequires the Branching feature to be enabled on the account.\n\n*Note: Merging a branch may take several minutes depending on diff size.*\n", "operationId": "branch/merge", "tags": [ "Branches" @@ -18755,7 +18822,7 @@ ], "responses": { "200": { - "description": "OK", + "description": "OK. The merge has been scheduled. The response body is empty; observe progress by polling the branch resource.", "headers": { "X-Rate-Limit-Limit": { "$ref": "#/components/headers/X-Rate-Limit-Limit" @@ -18771,9 +18838,23 @@ "400": { "$ref": "#/components/responses/400" }, + "401": { + "$ref": "#/components/responses/401" + }, + "403": { + "$ref": "#/components/responses/403", + "description": "Forbidden. Returned when the access token lacks the `write` scope, when the user is not allowed to merge this branch, or when the Branching feature is not available on the account." + }, "404": { "$ref": "#/components/responses/404" }, + "409": { + "$ref": "#/components/responses/409", + "description": "Conflict. The branch has open jobs or open translation orders. The response body lists the blockers, for example `{\"errors\":[\"open_jobs\",\"open_orders\"]}`. Close or complete the listed resources before retrying." + }, + "422": { + "$ref": "#/components/responses/422" + }, "429": { "$ref": "#/components/responses/429" } @@ -18797,8 +18878,12 @@ "title": "branch/merge/parameters", "properties": { "strategy": { - "description": "strategy used for merge conflicts, use_main or use_branch", + "description": "Conflict resolution strategy applied when the branch and its base have diverged. `use_main` keeps the values from the base branch; `use_branch` keeps the values from the branch being merged.\n", "type": "string", + "enum": [ + "use_main", + "use_branch" + ], "example": "use_main" } } @@ -18811,7 +18896,7 @@ "/projects/{project_id}/branches/{name}/sync": { "patch": { "summary": "Sync a branch", - "description": "Sync an existing branch.\n\n*Note: Only available for branches created with new branching.*\n", + "description": "Pull changes from the base branch into this branch, applying the chosen conflict-resolution strategy.\n\nThe sync runs asynchronously. The branch transitions to `syncing_branch` and settles back into `success` (or `merge_conflict` / `branch_error`) once the background job completes; the response body for this request is empty. Poll the branch resource to observe the final state.\n\nOnly branches created with the newer branching system can be synced. Requests against branches from the older system, or against branches whose current state does not allow a sync, are rejected with `422 Unprocessable Entity` and an empty body.\n\nRequires the Branching feature to be enabled on the account.\n", "operationId": "branch/sync", "tags": [ "Branches" @@ -18829,7 +18914,7 @@ ], "responses": { "200": { - "description": "OK", + "description": "OK. The sync has been scheduled. The response body is empty; observe progress by polling the branch resource.", "headers": { "X-Rate-Limit-Limit": { "$ref": "#/components/headers/X-Rate-Limit-Limit" @@ -18845,9 +18930,19 @@ "400": { "$ref": "#/components/responses/400" }, + "401": { + "$ref": "#/components/responses/401" + }, + "403": { + "$ref": "#/components/responses/403", + "description": "Forbidden. Returned when the access token lacks the `write` scope, when the user is not allowed to sync this branch, or when the Branching feature is not available on the account." + }, "404": { "$ref": "#/components/responses/404" }, + "422": { + "$ref": "#/components/responses/422" + }, "429": { "$ref": "#/components/responses/429" } @@ -18871,8 +18966,12 @@ "title": "branch/sync/parameters", "properties": { "strategy": { - "description": "strategy used for conflicts, use_main or use_branch", + "description": "Conflict resolution strategy applied when the branch and its base have diverged. `use_main` keeps the values from the base branch; `use_branch` keeps the values from this branch.\n", "type": "string", + "enum": [ + "use_main", + "use_branch" + ], "example": "use_main" } }