diff --git a/doc/api/graphql/reference/_index.md b/doc/api/graphql/reference/_index.md index 9a8d024e821027fcec9df46ec67c9392ffdc3aad..d4a975f51c66e9c987a56c15287de9388582b59d 100644 --- a/doc/api/graphql/reference/_index.md +++ b/doc/api/graphql/reference/_index.md @@ -12958,7 +12958,8 @@ Input type: `WorkspaceCreateInput` | `maxHoursBeforeTermination` {{< icon name="warning-solid" >}} | [`Int`](#int) | **Deprecated:** Field is not used. Deprecated in GitLab 17.9. | | `projectId` | [`ProjectID!`](#projectid) | ID of the project that will provide the Devfile for the created workspace. | | `projectRef` | [`String`](#string) | Project repo git ref. | -| `variables` | [`[WorkspaceVariableInput!]`](#workspacevariableinput) | Variables to inject into the workspace. | +| `variables` {{< icon name="warning-solid" >}} | [`[WorkspaceVariableInput!]`](#workspacevariableinput) | **Deprecated:** Argument is renamed to workspace_variables. Deprecated in GitLab 18.0. | +| `workspaceVariables` {{< icon name="warning-solid" >}} | [`[WorkspaceVariableInput!]`](#workspacevariableinput) | **Deprecated:** **Status**: Experiment. Introduced in GitLab 18.0. | #### Fields diff --git a/ee/app/graphql/mutations/remote_development/workspace_operations/create.rb b/ee/app/graphql/mutations/remote_development/workspace_operations/create.rb index 71b89876c58a022d21f83ffa41671317c5cad936..6491e0a9cc06012ceea4afc17dba8994b39f1993 100644 --- a/ee/app/graphql/mutations/remote_development/workspace_operations/create.rb +++ b/ee/app/graphql/mutations/remote_development/workspace_operations/create.rb @@ -67,6 +67,14 @@ class Create < BaseMutation required: false, default_value: [], replace_null_with_default: true, + description: 'Variables to inject into the workspace.', + deprecated: { reason: 'Argument is renamed to workspace_variables', milestone: '18.0' } + + argument :workspace_variables, [::Types::RemoteDevelopment::WorkspaceVariableInput], + required: false, + default_value: [], + replace_null_with_default: true, + experiment: { milestone: '18.0' }, description: 'Variables to inject into the workspace.' # @param [Hash] args @@ -93,6 +101,12 @@ def resolve(args) devfile_ref = args.delete(:devfile_ref) args[:project_ref] = devfile_ref if args[:project_ref].nil? + # If 'workspace_variables' is not specified, use 'variables' arg for backward compatibility. + workspace_variables = args.delete(:workspace_variables) + variables_array = workspace_variables.presence || args.fetch(:variables, []) + + variables = variables_array.map(&:to_h) + # NOTE: What the following line actually does - the agent is delegating to the project to check that the user # has the :create_workspace ability on the _agent's_ project, which will be true if the user is a developer # on the agent's project. @@ -123,7 +137,6 @@ def resolve(args) # noinspection RubyNilAnalysis - This is because the superclass #current_user uses #[], which can return nil track_usage_event(:users_creating_workspaces, current_user.id) - variables = args.fetch(:variables, []).map(&:to_h) params = args.merge( agent: agent, user: current_user, diff --git a/ee/spec/requests/api/graphql/mutations/remote_development/workspace_operations/create_spec.rb b/ee/spec/requests/api/graphql/mutations/remote_development/workspace_operations/create_spec.rb index 647485ba47d6744f55bfab5492fb9c69fe1483eb..db6a6dc576f3655f3204c3c06fe554eb8a7a4925 100644 --- a/ee/spec/requests/api/graphql/mutations/remote_development/workspace_operations/create_spec.rb +++ b/ee/spec/requests/api/graphql/mutations/remote_development/workspace_operations/create_spec.rb @@ -39,7 +39,7 @@ let(:desired_state) { RemoteDevelopment::WorkspaceOperations::States::RUNNING } let(:devfile_path) { '.devfile.yaml' } - let(:mutation_expected_varaiables) do + let(:variables) do [ { key: 'VAR1', value: 'value 1', type: 'ENVIRONMENT', variable_type: 'ENVIRONMENT' }, { key: 'VAR2', value: 'value 2', type: 'ENVIRONMENT', variable_type: 'ENVIRONMENT' } @@ -53,7 +53,7 @@ ] end - let(:all_mutation_args) do + let(:base_mutation_args) do { desired_state: desired_state, editor: 'webide', @@ -61,21 +61,19 @@ project_id: workspace_project.to_global_id.to_s, project_ref: 'main', devfile_path: devfile_path, - variables: [ - { key: 'VAR1', value: 'value 1', type: 'ENVIRONMENT' }, - { key: 'VAR2', value: 'value 2', type: 'ENVIRONMENT' } - ] + workspace_variables: variables } end - let(:mutation_args) { all_mutation_args } - - let(:mutation) do - graphql_mutation(:workspace_create, mutation_args) - end + let(:expected_service_params) do + params = { + desired_state: desired_state, + editor: 'webide', + project_ref: 'main', + devfile_path: devfile_path, + variables: variables + } - let(:expected_service_args) do - params = all_mutation_args.except(:cluster_agent_id, :project_id) # noinspection RubyMismatchedArgumentType - RubyMine is misinterpreting types for Hash values params[:variables] = service_class_expected_variables # noinspection RubyMismatchedArgumentType - RubyMine is misinterpreting types for Hash values @@ -84,11 +82,21 @@ # noinspection RubyMismatchedArgumentType - RubyMine is misinterpreting types for Hash values params[:project] = workspace_project + params + end + + let(:mutation_args) { base_mutation_args } + + let(:mutation) do + graphql_mutation(:workspace_create, mutation_args) + end + + let(:expected_service_args) do { domain_main_class: ::RemoteDevelopment::WorkspaceOperations::Create::Main, domain_main_class_args: { user: current_user, - params: params, + params: expected_service_params, vscode_extension_marketplace_metadata: { enabled: true }, vscode_extension_marketplace: { some_setting: "some-value" } } @@ -154,29 +162,19 @@ def mutation_response it_behaves_like 'successful create' end - context 'when devfile_path is nil' do - let(:devfile_path) { nil } + describe 'devfile_path behavior' do + context 'when devfile_path is nil' do + let(:devfile_path) { nil } - it_behaves_like 'successful create' - end - - context 'when devfile_path is not present' do - let(:devfile_path) { nil } - let(:mutation_args) { all_mutation_args.except(:devfile_path) } - - it_behaves_like 'successful create' - end - - context 'when project_ref is not present and devfile_ref is present' do - let(:mutation_args) { all_mutation_args.except(:project_ref).merge(devfile_ref: 'main') } - - it_behaves_like 'successful create' - end + it_behaves_like 'successful create' + end - context 'when project_ref and devfile_ref are both present' do - let(:mutation_args) { all_mutation_args.merge(devfile_ref: 'main1') } + context 'when devfile_path is not present' do + let(:devfile_path) { nil } + let(:mutation_args) { base_mutation_args.except(:devfile_path) } - it_behaves_like 'successful create' + it_behaves_like 'successful create' + end end context "when the agent project no longer exists under the namespace it is mapped to" do @@ -202,6 +200,34 @@ def mutation_response it_behaves_like 'a mutation that returns errors in the response', errors: ['some error'] end + + describe 'deprecated fields behavior' do + context 'when project_ref is not present and devfile_ref is present' do + let(:mutation_args) do + base_mutation_args.except(:project_ref).merge(devfile_ref: 'main') + end + + it_behaves_like 'successful create' + end + + context 'when project_ref and devfile_ref are both present' do + let(:mutation_args) { base_mutation_args.merge(devfile_ref: 'main1') } + + it_behaves_like 'successful create' + end + + context 'when workspace_variables is not present and variables is present' do + let(:mutation_args) { base_mutation_args.except(:workspace_variables).merge(variables: variables) } + + it_behaves_like 'successful create' + end + + context 'when workspace_variables and variables are both present' do + let(:mutation_args) { base_mutation_args.merge(variables: variables) } + + it_behaves_like 'successful create' + end + end end context 'when workspace project and agent project are NOT in the same root namespace' do @@ -225,7 +251,7 @@ def mutation_response context 'when required arguments are missing' do context 'when validates against GraphQL not allow null behaviour' do - let(:mutation_args) { all_mutation_args.except(:desired_state) } + let(:mutation_args) { base_mutation_args.except(:desired_state) } it 'returns error about required argument' do post_graphql_mutation(mutation, current_user: user) @@ -235,7 +261,7 @@ def mutation_response end context 'when both project_ref and devfile_ref not present' do - let(:mutation_args) { all_mutation_args.except(:project_ref, :devfile_ref) } + let(:mutation_args) { base_mutation_args.except(:project_ref, :devfile_ref) } it 'returns error about required argument' do post_graphql_mutation(mutation, current_user: user)