From 2b0a0f9b03d8411c0b6e312e9399fe74cfa5dfea Mon Sep 17 00:00:00 2001
From: Hiroyuki Sato <sathiroyuki@gmail.com>
Date: Mon, 4 Mar 2019 21:07:36 +0000
Subject: [PATCH] Merge branch 'master' into
 expose-additional-merge-request-pipeline-variables

Conflicts:
  doc/ci/variables/README.md
  spec/models/ci/pipeline_spec.rb
---
 app/models/merge_request.rb                   | 50 ++++++++-----------
 ...ional-merge-request-pipeline-variables.yml |  5 ++
 doc/ci/variables/README.md                    | 30 ++++++-----
 spec/models/ci/pipeline_spec.rb               | 39 ++++++++++++++-
 4 files changed, 80 insertions(+), 44 deletions(-)
 create mode 100644 changelogs/unreleased/expose-additional-merge-request-pipeline-variables.yml

diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 1468ae1c34a..1e4735bac8c 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -1154,35 +1154,16 @@ class MergeRequest < ActiveRecord::Base
     Gitlab::Ci::Variables::Collection.new.tap do |variables|
       variables.append(key: 'CI_MERGE_REQUEST_ID', value: id.to_s)
       variables.append(key: 'CI_MERGE_REQUEST_IID', value: iid.to_s)
-
-      variables.append(key: 'CI_MERGE_REQUEST_REF_PATH',
-                       value: ref_path.to_s)
-
-      variables.append(key: 'CI_MERGE_REQUEST_PROJECT_ID',
-                       value: project.id.to_s)
-
-      variables.append(key: 'CI_MERGE_REQUEST_PROJECT_PATH',
-                       value: project.full_path)
-
-      variables.append(key: 'CI_MERGE_REQUEST_PROJECT_URL',
-                       value: project.web_url)
-
-      variables.append(key: 'CI_MERGE_REQUEST_TARGET_BRANCH_NAME',
-                       value: target_branch.to_s)
-
-      if source_project
-        variables.append(key: 'CI_MERGE_REQUEST_SOURCE_PROJECT_ID',
-                         value: source_project.id.to_s)
-
-        variables.append(key: 'CI_MERGE_REQUEST_SOURCE_PROJECT_PATH',
-                         value: source_project.full_path)
-
-        variables.append(key: 'CI_MERGE_REQUEST_SOURCE_PROJECT_URL',
-                         value: source_project.web_url)
-
-        variables.append(key: 'CI_MERGE_REQUEST_SOURCE_BRANCH_NAME',
-                         value: source_branch.to_s)
-      end
+      variables.append(key: 'CI_MERGE_REQUEST_REF_PATH', value: ref_path.to_s)
+      variables.append(key: 'CI_MERGE_REQUEST_PROJECT_ID', value: project.id.to_s)
+      variables.append(key: 'CI_MERGE_REQUEST_PROJECT_PATH', value: project.full_path)
+      variables.append(key: 'CI_MERGE_REQUEST_PROJECT_URL', value: project.web_url)
+      variables.append(key: 'CI_MERGE_REQUEST_TARGET_BRANCH_NAME', value: target_branch.to_s)
+      variables.append(key: 'CI_MERGE_REQUEST_TITLE', value: title)
+      variables.append(key: 'CI_MERGE_REQUEST_ASSIGNEES', value: assignee.username) if assignee
+      variables.append(key: 'CI_MERGE_REQUEST_MILESTONE', value: milestone.title) if milestone
+      variables.append(key: 'CI_MERGE_REQUEST_LABELS', value: label_names.join(',')) if labels.present?
+      variables.concat(source_project_variables)
     end
   end
 
@@ -1389,4 +1370,15 @@ class MergeRequest < ActiveRecord::Base
     source_project&.ci_pipelines
                   &.latest_for_merge_request(self, source_branch, diff_head_sha)
   end
+
+  def source_project_variables
+    Gitlab::Ci::Variables::Collection.new.tap do |variables|
+      break variables unless source_project
+
+      variables.append(key: 'CI_MERGE_REQUEST_SOURCE_PROJECT_ID', value: source_project.id.to_s)
+      variables.append(key: 'CI_MERGE_REQUEST_SOURCE_PROJECT_PATH', value: source_project.full_path)
+      variables.append(key: 'CI_MERGE_REQUEST_SOURCE_PROJECT_URL', value: source_project.web_url)
+      variables.append(key: 'CI_MERGE_REQUEST_SOURCE_BRANCH_NAME', value: source_branch.to_s)
+    end
+  end
 end
diff --git a/changelogs/unreleased/expose-additional-merge-request-pipeline-variables.yml b/changelogs/unreleased/expose-additional-merge-request-pipeline-variables.yml
new file mode 100644
index 00000000000..399f60ef219
--- /dev/null
+++ b/changelogs/unreleased/expose-additional-merge-request-pipeline-variables.yml
@@ -0,0 +1,5 @@
+---
+title: Expose additional merge request pipeline variables
+merge_request: 24595
+author: Hiroyuki Sato
+type: added
diff --git a/doc/ci/variables/README.md b/doc/ci/variables/README.md
index 6fe352df48a..08db89124de 100644
--- a/doc/ci/variables/README.md
+++ b/doc/ci/variables/README.md
@@ -79,19 +79,23 @@ future GitLab releases.**
 | **CI_JOB_STAGE**                          | 9.0    | 0.5    | The name of the stage as defined in `.gitlab-ci.yml` |
 | **CI_JOB_TOKEN**                          | 9.0    | 1.2    | Token used for authenticating with the [GitLab Container Registry][registry] and downloading [dependent repositories][dependent-repositories] |
 | **CI_JOB_URL**                            | 11.1   | 0.5    | Job details URL |
-| **CI_MERGE_REQUEST_ID**                   | 11.6   | all    | The ID of the merge request if it's [pipelines for merge requests](../merge_request_pipelines/index.md) |
-| **CI_MERGE_REQUEST_IID**                  | 11.6   | all    | The IID of the merge request if it's [pipelines for merge requests](../merge_request_pipelines/index.md) |
-| **CI_MERGE_REQUEST_PROJECT_ID**           | 11.6   | all    | The ID of the project of the merge request if it's [pipelines for merge requests](../merge_request_pipelines/index.md) |
-| **CI_MERGE_REQUEST_PROJECT_PATH**         | 11.6   | all    | The path of the project of the merge request if it's [pipelines for merge requests](../merge_request_pipelines/index.md) (e.g. `namespace/awesome-project`) |
-| **CI_MERGE_REQUEST_PROJECT_URL**          | 11.6   | all    | The URL of the project of the merge request if it's [pipelines for merge requests](../merge_request_pipelines/index.md) (e.g. `http://192.168.10.15:3000/namespace/awesome-project`) |
-| **CI_MERGE_REQUEST_REF_PATH**             | 11.6   | all    | The ref path of the merge request if it's [pipelines for merge requests](../merge_request_pipelines/index.md). (e.g. `refs/merge-requests/1/head`) |
-| **CI_MERGE_REQUEST_SOURCE_BRANCH_NAME**   | 11.6   | all    | The source branch name of the merge request if it's [pipelines for merge requests](../merge_request_pipelines/index.md) |
-| **CI_MERGE_REQUEST_SOURCE_BRANCH_SHA**    | 11.9   | all    | The HEAD sha of the source branch of the merge request if it's [pipelines for merge requests](../merge_request_pipelines/index.md) |
-| **CI_MERGE_REQUEST_SOURCE_PROJECT_ID**    | 11.6   | all    | The ID of the source project of the merge request if it's [pipelines for merge requests](../merge_request_pipelines/index.md) |
-| **CI_MERGE_REQUEST_SOURCE_PROJECT_PATH**  | 11.6   | all    | The path of the source project of the merge request if it's [pipelines for merge requests](../merge_request_pipelines/index.md) |
-| **CI_MERGE_REQUEST_SOURCE_PROJECT_URL**   | 11.6   | all    | The URL of the source project of the merge request if it's [pipelines for merge requests](../merge_request_pipelines/index.md) |
-| **CI_MERGE_REQUEST_TARGET_BRANCH_NAME**   | 11.6   | all    | The target branch name of the merge request if it's [pipelines for merge requests](../merge_request_pipelines/index.md) |
-| **CI_MERGE_REQUEST_TARGET_BRANCH_SHA**    | 11.9   | all    | The HEAD sha of the target branch of the merge request if it's [pipelines for merge requests](../merge_request_pipelines/index.md) |
+| **CI_MERGE_REQUEST_ID**                   | 11.6   | all    | The ID of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md) |
+| **CI_MERGE_REQUEST_IID**                  | 11.6   | all    | The IID of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md) |
+| **CI_MERGE_REQUEST_PROJECT_ID**           | 11.6   | all    | The ID of the project of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md) |
+| **CI_MERGE_REQUEST_PROJECT_PATH**         | 11.6   | all    | The path of the project of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md) (e.g. `namespace/awesome-project`) |
+| **CI_MERGE_REQUEST_PROJECT_URL**          | 11.6   | all    | The URL of the project of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md) (e.g. `http://192.168.10.15:3000/namespace/awesome-project`) |
+| **CI_MERGE_REQUEST_REF_PATH**             | 11.6   | all    | The ref path of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). (e.g. `refs/merge-requests/1/head`) |
+| **CI_MERGE_REQUEST_SOURCE_BRANCH_NAME**   | 11.6   | all    | The source branch name of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md) |
+| **CI_MERGE_REQUEST_SOURCE_BRANCH_SHA**    | 11.9   | all    | The HEAD sha of the source branch of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md) |
+| **CI_MERGE_REQUEST_SOURCE_PROJECT_ID**    | 11.6   | all    | The ID of the source project of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md) |
+| **CI_MERGE_REQUEST_SOURCE_PROJECT_PATH**  | 11.6   | all    | The path of the source project of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md) |
+| **CI_MERGE_REQUEST_SOURCE_PROJECT_URL**   | 11.6   | all    | The URL of the source project of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md) |
+| **CI_MERGE_REQUEST_TARGET_BRANCH_NAME**   | 11.6   | all    | The target branch name of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md) |
+| **CI_MERGE_REQUEST_TARGET_BRANCH_SHA**    | 11.9   | all    | The HEAD sha of the target branch of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md) |
+| **CI_MERGE_REQUEST_TITLE**                | 11.9   | all    | The title of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md) |
+| **CI_MERGE_REQUEST_ASSIGNEES**            | 11.9   | all    | Comma-separated usernames of the assignees of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). **Comming soon**: [Multitle assignees for merge requests](https://gitlab.com/gitlab-org/gitlab-ee/issues/2004) |
+| **CI_MERGE_REQUEST_MILESTONE**            | 11.9   | all    | The milestone title of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md) |
+| **CI_MERGE_REQUEST_LABELS**               | 11.9   | all    | Comma-separated label names of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md) |
 | **CI_NODE_INDEX**                         | 11.5   | all    | Index of the job in the job set. If the job is not parallelized, this variable is not set. |
 | **CI_NODE_TOTAL**                         | 11.5   | all    | Total number of instances of this job running in parallel. If the job is not parallelized, this variable is set to `1`. |
 | **CI_API_V4_URL**                         | 11.7   | all    | The GitLab API v4 root URL |
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 462793b259b..3a6de57bd63 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -513,9 +513,16 @@ describe Ci::Pipeline, :mailer do
                source_project: project,
                source_branch: 'feature',
                target_project: project,
-               target_branch: 'master')
+               target_branch: 'master',
+               assignee: assignee,
+               milestone: milestone,
+               labels: labels)
       end
 
+      let(:assignee) { create(:user) }
+      let(:milestone) { create(:milestone) }
+      let(:labels) { create_list(:label, 2) }
+
       it 'exposes merge request pipeline variables' do
         expect(subject.to_hash)
           .to include(
@@ -531,7 +538,11 @@ describe Ci::Pipeline, :mailer do
             'CI_MERGE_REQUEST_SOURCE_PROJECT_PATH' => merge_request.source_project.full_path,
             'CI_MERGE_REQUEST_SOURCE_PROJECT_URL' => merge_request.source_project.web_url,
             'CI_MERGE_REQUEST_SOURCE_BRANCH_NAME' => merge_request.source_branch.to_s,
-            'CI_MERGE_REQUEST_SOURCE_BRANCH_SHA' => pipeline.source_sha.to_s)
+            'CI_MERGE_REQUEST_SOURCE_BRANCH_SHA' => pipeline.source_sha.to_s,
+            'CI_MERGE_REQUEST_TITLE' => merge_request.title,
+            'CI_MERGE_REQUEST_ASSIGNEES' => assignee.username,
+            'CI_MERGE_REQUEST_MILESTONE' => milestone.title,
+            'CI_MERGE_REQUEST_LABELS' => labels.map(&:title).join(','))
       end
 
       context 'when source project does not exist' do
@@ -547,6 +558,30 @@ describe Ci::Pipeline, :mailer do
                CI_MERGE_REQUEST_SOURCE_BRANCH_NAME])
         end
       end
+
+      context 'without assignee' do
+        let(:assignee) { nil }
+
+        it 'does not expose assignee variable' do
+          expect(subject.to_hash.keys).not_to include('CI_MERGE_REQUEST_ASSIGNEES')
+        end
+      end
+
+      context 'without milestone' do
+        let(:milestone) { nil }
+
+        it 'does not expose milestone variable' do
+          expect(subject.to_hash.keys).not_to include('CI_MERGE_REQUEST_MILESTONE')
+        end
+      end
+
+      context 'without labels' do
+        let(:labels) { [] }
+
+        it 'does not expose labels variable' do
+          expect(subject.to_hash.keys).not_to include('CI_MERGE_REQUEST_LABELS')
+        end
+      end
     end
   end
 
-- 
2.30.9