From 069f2d347585a0f79ab8e3ddfb194ebbc86176c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9my=20Coutable?= <remy@rymai.me>
Date: Thu, 29 Sep 2016 19:31:14 +0200
Subject: [PATCH] Draft a quick CE->EE merge check rake task
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Rémy Coutable <remy@rymai.me>
---
 .gitlab-ci.yml                      |  7 +++
 lib/tasks/ce_to_ee_merge_check.rake |  6 ++
 lib/tasks/gitlab/dev.rake           | 96 +++++++++++++++++++++++++++++
 3 files changed, 109 insertions(+)
 create mode 100644 lib/tasks/ce_to_ee_merge_check.rake
 create mode 100644 lib/tasks/gitlab/dev.rake

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 7d19f55aca3..7e2d705a888 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -210,6 +210,13 @@ rake brakeman: *exec
 rake flay: *exec
 license_finder: *exec
 rake downtime_check: *exec
+rake ce_to_ee_merge_check:
+  <<: *exec
+  only:
+    - branches
+  except:
+    - tags
+    - master
 
 rake db:migrate:reset:
   stage: test
diff --git a/lib/tasks/ce_to_ee_merge_check.rake b/lib/tasks/ce_to_ee_merge_check.rake
new file mode 100644
index 00000000000..bb87f85cd9c
--- /dev/null
+++ b/lib/tasks/ce_to_ee_merge_check.rake
@@ -0,0 +1,6 @@
+desc 'Checks if the branch would apply cleanly to EE'
+task ce_to_ee_merge_check: :environment do
+  return if defined?(Gitlab::License)
+
+  Rake::Task['gitlab:dev:ce_to_ee_merge_check'].invoke
+end
diff --git a/lib/tasks/gitlab/dev.rake b/lib/tasks/gitlab/dev.rake
new file mode 100644
index 00000000000..bf17ba499bc
--- /dev/null
+++ b/lib/tasks/gitlab/dev.rake
@@ -0,0 +1,96 @@
+namespace :gitlab do
+  namespace :dev do
+    desc 'Checks if the branch would apply cleanly to EE'
+    task ce_to_ee_merge_check: :environment do
+      ce_repo = ENV['CI_BUILD_REPO']
+      ce_branch = ENV['CI_BUILD_REF_NAME']
+
+      ee_repo = 'https://gitlab.com/gitlab-org/gitlab-ee.git'
+      ee_branch = "#{ce_branch}-ee"
+      ee_dir = 'gitlab-ee-merge-check'
+
+      puts "\n=> Cloning #{ee_repo} into #{ee_dir}\n"
+      `git clone #{ee_repo} #{ee_dir} --depth 1`
+      Dir.chdir(ee_dir) do
+        puts "\n => Fetching #{ce_repo}/#{ce_branch}\n"
+        `git fetch #{ce_repo} #{ce_branch} --depth 1`
+
+        # Try to merge the current tested branch to EE/master...
+        puts "\n => Merging #{ce_repo}/#{ce_branch} into #{ee_repo}/master\n"
+        `git merge --ff-only FETCH_HEAD`
+
+        exit 0 if $?.success?
+
+        # Try to merge a possible <branch>-ee branch to EE/master...
+        puts "\n => Merging #{ee_repo}/#{ee_branch} into #{ee_repo}/master\n"
+        `git merge --ff-only #{ee_branch}`
+
+        # The <branch>-ee doesn't exist
+        if $?.exitstatus == 1
+          puts <<-MSG.strip_heredoc
+            \n=================================================================
+            The #{ce_branch} branch cannot be merged without conflicts to the
+            current EE/master, and no #{ee_branch} branch was detected in
+            the EE repository.
+
+            Please create a #{ee_branch} branch that includes changes
+            #{ce_branch} but also specific changes than can be applied cleanly
+            to EE/master.
+
+            You can create this branch as follow:
+
+            1. In the EE repo:
+              $ git fetch origin
+              $ git fetch #{ce_repo} #{ce_branch}
+              $ git checkout -b #{ee_branch} FETCH_HEAD
+              $ git rebase origin/master
+            2. At this point you will likely have conflicts, solve them, and
+              continue/finish the rebase.
+            3. You can squash all the original #{ce_branch} commits into a
+              single "Port of #{ce_branch} to EE".
+            4. Push your branch to #{ee_repo}:
+              $ git push origin #{ee_branch}
+            =================================================================\n
+          MSG
+
+          exit 1
+        end
+
+        # The <branch>-ee cannot be merged cleanly to EE/master...
+        unless $?.success?
+          puts <<-MSG.strip_heredoc
+            \n=================================================================
+            The #{ce_branch} branch cannot be merged without conflicts to
+            EE/master, and even though the #{ee_branch} branch exists in the EE
+            repository, it cannot be merged without conflicts to EE/master.
+
+            Please update the #{ee_branch}, push it again to #{ee_repo}, and
+            retry this job.
+            =================================================================\n
+          MSG
+
+          exit 2
+        end
+
+        puts "\n => Merging #{ce_repo}/#{ce_branch} into #{ee_repo}/master\n"
+        `git merge --ff-only FETCH_HEAD`
+        exit 0 if $?.success?
+
+        # The <branch>-ee can be merged cleanly to EE/master, but <branch> still
+        # cannot be merged cleanly to EE/master...
+        puts <<-MSG.strip_heredoc
+          \n=================================================================
+          The #{ce_branch} branch cannot be merged without conflicts to EE, and
+          even though the #{ee_branch} branch exists in the EE repository and
+          applies cleanly to EE/master, it doesn't prevent conflicts when
+          merging #{ce_branch} into EE.
+
+          We may be in a complex situation here.
+          =================================================================\n
+        MSG
+
+        exit 3
+      end
+    end
+  end
+end
-- 
GitLab