From 7cd70a63e7629d07b6b3fc18ddc4a60f18a05797 Mon Sep 17 00:00:00 2001
From: Avielle Wolfe <awolfe@gitlab.com>
Date: Tue, 3 Jan 2023 14:30:29 +0000
Subject: [PATCH] Add variables argument to `PlayJob`

We are transitioning the manual job page to GraphQL, so we now need to
make it possible to play a job with a given set of variables via the
`PlayJob` mutation.

Changelog: changed
---
 app/graphql/mutations/ci/job/play.rb          | 12 +++++-
 doc/api/graphql/reference/index.md            |  1 +
 .../api/graphql/mutations/ci/job_play_spec.rb | 39 +++++++++++++++++--
 3 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/app/graphql/mutations/ci/job/play.rb b/app/graphql/mutations/ci/job/play.rb
index 99f62ea3e706c..8bb69119a4465 100644
--- a/app/graphql/mutations/ci/job/play.rb
+++ b/app/graphql/mutations/ci/job/play.rb
@@ -11,13 +11,21 @@ class Play < Base
               null: true,
               description: 'Job after the mutation.'
 
+        argument :variables, [::Types::Ci::VariableInputType],
+                 required: false,
+                 default_value: [],
+                 replace_null_with_default: true,
+                 description: 'Variables to use when playing a manual job.'
+
         authorize :update_build
 
-        def resolve(id:)
+        def resolve(id:, variables:)
           job = authorized_find!(id: id)
           project = job.project
+          variables = variables.map(&:to_h)
+
+          ::Ci::PlayBuildService.new(project, current_user).execute(job, variables)
 
-          ::Ci::PlayBuildService.new(project, current_user).execute(job)
           {
             job: job,
             errors: errors_on_object(job)
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 535979567c552..1a0a94417248d 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -3704,6 +3704,7 @@ Input type: `JobPlayInput`
 | ---- | ---- | ----------- |
 | <a id="mutationjobplayclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
 | <a id="mutationjobplayid"></a>`id` | [`CiBuildID!`](#cibuildid) | ID of the job to mutate. |
+| <a id="mutationjobplayvariables"></a>`variables` | [`[CiVariableInput!]`](#civariableinput) | Variables to use when playing a manual job. |
 
 #### Fields
 
diff --git a/spec/requests/api/graphql/mutations/ci/job_play_spec.rb b/spec/requests/api/graphql/mutations/ci/job_play_spec.rb
index 014a5e0f1c75f..9ba80e51dee18 100644
--- a/spec/requests/api/graphql/mutations/ci/job_play_spec.rb
+++ b/spec/requests/api/graphql/mutations/ci/job_play_spec.rb
@@ -8,17 +8,25 @@
   let_it_be(:user) { create(:user) }
   let_it_be(:project) { create(:project) }
   let_it_be(:pipeline) { create(:ci_pipeline, project: project, user: user) }
-  let_it_be(:job) { create(:ci_build, pipeline: pipeline, name: 'build') }
+  let_it_be(:job) { create(:ci_build, :playable, pipeline: pipeline, name: 'build') }
 
-  let(:mutation) do
-    variables = {
+  let(:variables) do
+    {
       id: job.to_global_id.to_s
     }
+  end
+
+  let(:mutation) do
     graphql_mutation(:job_play, variables,
                      <<-QL
                        errors
                        job {
                          id
+                         manualVariables {
+                           nodes {
+                             key
+                           }
+                         }
                        }
                      QL
     )
@@ -43,4 +51,29 @@
     expect(response).to have_gitlab_http_status(:success)
     expect(mutation_response['job']['id']).to eq(job_id)
   end
+
+  context 'when given variables' do
+    let(:variables) do
+      {
+        id: job.to_global_id.to_s,
+        variables: [
+          { key: 'MANUAL_VAR_1', value: 'test var' },
+          { key: 'MANUAL_VAR_2', value: 'test var 2' }
+        ]
+      }
+    end
+
+    it 'provides those variables to the job', :aggregated_errors do
+      expect_next_instance_of(Ci::PlayBuildService) do |instance|
+        expect(instance).to receive(:execute).with(an_instance_of(Ci::Build), variables[:variables]).and_call_original
+      end
+
+      post_graphql_mutation(mutation, current_user: user)
+
+      expect(response).to have_gitlab_http_status(:success)
+      expect(mutation_response['job']['manualVariables']['nodes'].pluck('key')).to contain_exactly(
+        'MANUAL_VAR_1', 'MANUAL_VAR_2'
+      )
+    end
+  end
 end
-- 
GitLab