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)