diff --git a/app/Http/Controllers/Api/SharedEnvironmentVariablesController.php b/app/Http/Controllers/Api/SharedEnvironmentVariablesController.php index 32145f4ec3..61289e3c0a 100644 --- a/app/Http/Controllers/Api/SharedEnvironmentVariablesController.php +++ b/app/Http/Controllers/Api/SharedEnvironmentVariablesController.php @@ -12,6 +12,32 @@ use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use OpenApi\Attributes as OA; +#[OA\Schema( + schema: 'SharedEnvironmentVariableCreateRequest', + type: 'object', + required: ['key'], + properties: [ + new OA\Property(property: 'key', type: 'string'), + new OA\Property(property: 'value', type: 'string', nullable: true), + new OA\Property(property: 'is_literal', type: 'boolean'), + new OA\Property(property: 'is_multiline', type: 'boolean'), + new OA\Property(property: 'is_shown_once', type: 'boolean', description: 'If true, the saved value is hidden in the UI and API responses. MCP never returns environment variable values.'), + new OA\Property(property: 'comment', type: 'string', maxLength: 256, nullable: true), + ], +)] +#[OA\Schema( + schema: 'SharedEnvironmentVariableUpdateRequest', + description: 'Send at least one field.', + type: 'object', + properties: [ + new OA\Property(property: 'key', type: 'string'), + new OA\Property(property: 'value', type: 'string', nullable: true), + new OA\Property(property: 'is_literal', type: 'boolean'), + new OA\Property(property: 'is_multiline', type: 'boolean'), + new OA\Property(property: 'is_shown_once', type: 'boolean', description: 'If true, the saved value is hidden in the UI and API responses. MCP never returns environment variable values.'), + new OA\Property(property: 'comment', type: 'string', maxLength: 256, nullable: true), + ], +)] class SharedEnvironmentVariablesController extends Controller { private const ALLOWED_FIELDS = ['key', 'value', 'is_literal', 'is_multiline', 'is_shown_once', 'comment']; @@ -347,20 +373,7 @@ class SharedEnvironmentVariablesController extends Controller operationId: 'create-team-shared-env', security: [['bearerAuth' => []]], tags: ['Shared Environment Variables'], - requestBody: new OA\RequestBody( - required: true, - content: new OA\JsonContent( - required: ['key'], - properties: [ - new OA\Property(property: 'key', type: 'string'), - new OA\Property(property: 'value', type: 'string', nullable: true), - new OA\Property(property: 'is_literal', type: 'boolean'), - new OA\Property(property: 'is_multiline', type: 'boolean'), - new OA\Property(property: 'is_shown_once', type: 'boolean', description: 'If true, the saved value is hidden in the UI and API responses. MCP never returns environment variable values.'), - new OA\Property(property: 'comment', type: 'string', nullable: true), - ], - ), - ), + requestBody: new OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/SharedEnvironmentVariableCreateRequest')), responses: [ new OA\Response(response: 201, description: 'Environment variable created.'), new OA\Response(response: 401, ref: '#/components/responses/401'), @@ -388,6 +401,7 @@ class SharedEnvironmentVariablesController extends Controller parameters: [ new OA\Parameter(name: 'env_id', in: 'path', required: true, description: 'Shared env id (integer).', schema: new OA\Schema(type: 'integer')), ], + requestBody: new OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/SharedEnvironmentVariableUpdateRequest')), responses: [ new OA\Response(response: 200, description: 'Environment variable updated.'), new OA\Response(response: 401, ref: '#/components/responses/401'), @@ -476,6 +490,7 @@ class SharedEnvironmentVariablesController extends Controller parameters: [ new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Project UUID', schema: new OA\Schema(type: 'string')), ], + requestBody: new OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/SharedEnvironmentVariableCreateRequest')), responses: [ new OA\Response(response: 201, description: 'Environment variable created.'), new OA\Response(response: 401, ref: '#/components/responses/401'), @@ -512,6 +527,7 @@ class SharedEnvironmentVariablesController extends Controller new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Project UUID', schema: new OA\Schema(type: 'string')), new OA\Parameter(name: 'env_id', in: 'path', required: true, description: 'Shared env id (integer).', schema: new OA\Schema(type: 'integer')), ], + requestBody: new OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/SharedEnvironmentVariableUpdateRequest')), responses: [ new OA\Response(response: 200, description: 'Environment variable updated.'), new OA\Response(response: 401, ref: '#/components/responses/401'), @@ -633,6 +649,7 @@ class SharedEnvironmentVariablesController extends Controller new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Project UUID', schema: new OA\Schema(type: 'string')), new OA\Parameter(name: 'environment_name_or_uuid', in: 'path', required: true, description: 'Environment name or UUID', schema: new OA\Schema(type: 'string')), ], + requestBody: new OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/SharedEnvironmentVariableCreateRequest')), responses: [ new OA\Response(response: 201, description: 'Environment variable created.'), new OA\Response(response: 401, ref: '#/components/responses/401'), @@ -675,6 +692,7 @@ class SharedEnvironmentVariablesController extends Controller new OA\Parameter(name: 'environment_name_or_uuid', in: 'path', required: true, description: 'Environment name or UUID', schema: new OA\Schema(type: 'string')), new OA\Parameter(name: 'env_id', in: 'path', required: true, description: 'Shared env id (integer).', schema: new OA\Schema(type: 'integer')), ], + requestBody: new OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/SharedEnvironmentVariableUpdateRequest')), responses: [ new OA\Response(response: 200, description: 'Environment variable updated.'), new OA\Response(response: 401, ref: '#/components/responses/401'), @@ -800,6 +818,7 @@ class SharedEnvironmentVariablesController extends Controller parameters: [ new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Server UUID', schema: new OA\Schema(type: 'string')), ], + requestBody: new OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/SharedEnvironmentVariableCreateRequest')), responses: [ new OA\Response(response: 201, description: 'Environment variable created.'), new OA\Response(response: 401, ref: '#/components/responses/401'), @@ -836,6 +855,7 @@ class SharedEnvironmentVariablesController extends Controller new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Server UUID', schema: new OA\Schema(type: 'string')), new OA\Parameter(name: 'env_id', in: 'path', required: true, description: 'Shared env id (integer).', schema: new OA\Schema(type: 'integer')), ], + requestBody: new OA\RequestBody(required: true, content: new OA\JsonContent(ref: '#/components/schemas/SharedEnvironmentVariableUpdateRequest')), responses: [ new OA\Response(response: 200, description: 'Environment variable updated.'), new OA\Response(response: 401, ref: '#/components/responses/401'), diff --git a/openapi.json b/openapi.json index 53f3325211..e77c49af10 100644 --- a/openapi.json +++ b/openapi.json @@ -22230,37 +22230,7 @@ "content": { "application\/json": { "schema": { - "required": [ - "key" - ], - "properties": { - "key": { - "type": "string" - }, - "value": { - "type": [ - "string", - "null" - ] - }, - "is_literal": { - "type": "boolean" - }, - "is_multiline": { - "type": "boolean" - }, - "is_shown_once": { - "description": "If true, the saved value is hidden in the UI and API responses. MCP never returns environment variable values.", - "type": "boolean" - }, - "comment": { - "type": [ - "string", - "null" - ] - } - }, - "type": "object" + "$ref": "#\/components\/schemas\/SharedEnvironmentVariableCreateRequest" } } } @@ -22340,6 +22310,16 @@ } } ], + "requestBody": { + "required": true, + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/SharedEnvironmentVariableUpdateRequest" + } + } + } + }, "responses": { "200": { "description": "Environment variable updated." @@ -22415,6 +22395,16 @@ } } ], + "requestBody": { + "required": true, + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/SharedEnvironmentVariableCreateRequest" + } + } + } + }, "responses": { "201": { "description": "Environment variable created." @@ -22511,6 +22501,16 @@ } } ], + "requestBody": { + "required": true, + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/SharedEnvironmentVariableUpdateRequest" + } + } + } + }, "responses": { "200": { "description": "Environment variable updated." @@ -22604,6 +22604,16 @@ } } ], + "requestBody": { + "required": true, + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/SharedEnvironmentVariableCreateRequest" + } + } + } + }, "responses": { "201": { "description": "Environment variable created." @@ -22718,6 +22728,16 @@ } } ], + "requestBody": { + "required": true, + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/SharedEnvironmentVariableUpdateRequest" + } + } + } + }, "responses": { "200": { "description": "Environment variable updated." @@ -22793,6 +22813,16 @@ } } ], + "requestBody": { + "required": true, + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/SharedEnvironmentVariableCreateRequest" + } + } + } + }, "responses": { "201": { "description": "Environment variable created." @@ -22889,6 +22919,16 @@ } } ], + "requestBody": { + "required": true, + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/SharedEnvironmentVariableUpdateRequest" + } + } + } + }, "responses": { "200": { "description": "Environment variable updated." @@ -24732,6 +24772,72 @@ }, "type": "object" }, + "SharedEnvironmentVariableCreateRequest": { + "required": [ + "key" + ], + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": [ + "string", + "null" + ] + }, + "is_literal": { + "type": "boolean" + }, + "is_multiline": { + "type": "boolean" + }, + "is_shown_once": { + "description": "If true, the saved value is hidden in the UI and API responses. MCP never returns environment variable values.", + "type": "boolean" + }, + "comment": { + "type": [ + "string", + "null" + ], + "maxLength": 256 + } + }, + "type": "object" + }, + "SharedEnvironmentVariableUpdateRequest": { + "description": "Send at least one field.", + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": [ + "string", + "null" + ] + }, + "is_literal": { + "type": "boolean" + }, + "is_multiline": { + "type": "boolean" + }, + "is_shown_once": { + "description": "If true, the saved value is hidden in the UI and API responses. MCP never returns environment variable values.", + "type": "boolean" + }, + "comment": { + "type": [ + "string", + "null" + ], + "maxLength": 256 + } + }, + "type": "object" + }, "VolumeBackupScheduleRequest": { "required": [ "frequency" diff --git a/openapi.yaml b/openapi.yaml index 743cf4b7ee..c5ec7a7029 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -14008,23 +14008,7 @@ paths: content: application/json: schema: - required: - - key - properties: - key: - type: string - value: - type: [string, 'null'] - is_literal: - type: boolean - is_multiline: - type: boolean - is_shown_once: - description: 'If true, the saved value is hidden in the UI and API responses. MCP never returns environment variable values.' - type: boolean - comment: - type: [string, 'null'] - type: object + $ref: '#/components/schemas/SharedEnvironmentVariableCreateRequest' responses: '201': description: 'Environment variable created.' @@ -14076,6 +14060,12 @@ paths: required: true schema: type: integer + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SharedEnvironmentVariableUpdateRequest' responses: '200': description: 'Environment variable updated.' @@ -14127,6 +14117,12 @@ paths: required: true schema: type: string + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SharedEnvironmentVariableCreateRequest' responses: '201': description: 'Environment variable created.' @@ -14194,6 +14190,12 @@ paths: required: true schema: type: integer + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SharedEnvironmentVariableUpdateRequest' responses: '200': description: 'Environment variable updated.' @@ -14259,6 +14261,12 @@ paths: required: true schema: type: string + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SharedEnvironmentVariableCreateRequest' responses: '201': description: 'Environment variable created.' @@ -14340,6 +14348,12 @@ paths: required: true schema: type: integer + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SharedEnvironmentVariableUpdateRequest' responses: '200': description: 'Environment variable updated.' @@ -14391,6 +14405,12 @@ paths: required: true schema: type: string + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SharedEnvironmentVariableCreateRequest' responses: '201': description: 'Environment variable created.' @@ -14458,6 +14478,12 @@ paths: required: true schema: type: integer + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SharedEnvironmentVariableUpdateRequest' responses: '200': description: 'Environment variable updated.' @@ -15702,6 +15728,51 @@ components: preview: $ref: '#/components/schemas/ApplicationPreview' type: object + SharedEnvironmentVariableCreateRequest: + required: + - key + properties: + key: + type: string + value: + type: + - string + - 'null' + is_literal: + type: boolean + is_multiline: + type: boolean + is_shown_once: + description: 'If true, the saved value is hidden in the UI and API responses. MCP never returns environment variable values.' + type: boolean + comment: + type: + - string + - 'null' + maxLength: 256 + type: object + SharedEnvironmentVariableUpdateRequest: + description: 'Send at least one field.' + properties: + key: + type: string + value: + type: + - string + - 'null' + is_literal: + type: boolean + is_multiline: + type: boolean + is_shown_once: + description: 'If true, the saved value is hidden in the UI and API responses. MCP never returns environment variable values.' + type: boolean + comment: + type: + - string + - 'null' + maxLength: 256 + type: object VolumeBackupScheduleRequest: required: - frequency diff --git a/tests/Unit/SharedEnvironmentVariablesOpenApiTest.php b/tests/Unit/SharedEnvironmentVariablesOpenApiTest.php new file mode 100644 index 0000000000..1ed2a710af --- /dev/null +++ b/tests/Unit/SharedEnvironmentVariablesOpenApiTest.php @@ -0,0 +1,37 @@ +toBeTrue() + ->and($operation['requestBody']['content']['application/json']['schema']['$ref'] ?? null) + ->toBe("#/components/schemas/{$schemaName}"); +})->with([ + ['/team/envs', 'post', 'SharedEnvironmentVariableCreateRequest'], + ['/team/envs/{env_id}', 'patch', 'SharedEnvironmentVariableUpdateRequest'], + ['/projects/{uuid}/envs', 'post', 'SharedEnvironmentVariableCreateRequest'], + ['/projects/{uuid}/envs/{env_id}', 'patch', 'SharedEnvironmentVariableUpdateRequest'], + ['/projects/{uuid}/environments/{environment_name_or_uuid}/envs', 'post', 'SharedEnvironmentVariableCreateRequest'], + ['/projects/{uuid}/environments/{environment_name_or_uuid}/envs/{env_id}', 'patch', 'SharedEnvironmentVariableUpdateRequest'], + ['/servers/{uuid}/envs', 'post', 'SharedEnvironmentVariableCreateRequest'], + ['/servers/{uuid}/envs/{env_id}', 'patch', 'SharedEnvironmentVariableUpdateRequest'], +]); + +it('documents the fields accepted by the shared env validator', function () { + $schemas = sharedEnvOpenApiSpec()['components']['schemas']; + $fields = ['key', 'value', 'is_literal', 'is_multiline', 'is_shown_once', 'comment']; + + expect(array_keys($schemas['SharedEnvironmentVariableCreateRequest']['properties']))->toBe($fields) + ->and($schemas['SharedEnvironmentVariableCreateRequest']['required'])->toBe(['key']) + ->and(array_keys($schemas['SharedEnvironmentVariableUpdateRequest']['properties']))->toBe($fields) + ->and($schemas['SharedEnvironmentVariableUpdateRequest'])->not->toHaveKey('required'); +});