From 05b52e0f5e4d06edb736849daaac5c33c68c1d47 Mon Sep 17 00:00:00 2001
From: Andrew Smith <espadav8@gmail.com>
Date: Thu, 25 Aug 2016 07:45:31 +1000
Subject: [PATCH] Import GitHub release notes

# Conflicts:
#	lib/gitlab/github_import/importer.rb
---
 CHANGELOG                                     |  1 +
 .../importing/import_projects_from_github.md  |  1 +
 lib/gitlab/github_import/importer.rb          | 13 +++++
 lib/gitlab/github_import/release_formatter.rb | 23 ++++++++
 .../lib/gitlab/github_import/importer_spec.rb | 30 ++++++++++-
 .../github_import/release_formatter_spec.rb   | 54 +++++++++++++++++++
 6 files changed, 120 insertions(+), 2 deletions(-)
 create mode 100644 lib/gitlab/github_import/release_formatter.rb
 create mode 100644 spec/lib/gitlab/github_import/release_formatter_spec.rb

diff --git a/CHANGELOG b/CHANGELOG
index d69168985cd..22ed94f648b 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -79,6 +79,7 @@ v 8.12.0 (unreleased)
   - Remove inconsistent font weight for sidebar's labels (ClemMakesApps)
   - Align add button on repository view (ClemMakesApps)
   - Fix contributions calendar month label truncation (ClemMakesApps)
+  - Import release note descriptions from GitHub (EspadaV8)
   - Added tests for diff notes
   - Add pipeline events to Slack integration !5525
   - Add a button to download latest successful artifacts for branches and tags !5142
diff --git a/doc/workflow/importing/import_projects_from_github.md b/doc/workflow/importing/import_projects_from_github.md
index 306caabf6e6..370d885d366 100644
--- a/doc/workflow/importing/import_projects_from_github.md
+++ b/doc/workflow/importing/import_projects_from_github.md
@@ -15,6 +15,7 @@ At its current state, GitHub importer can import:
 - the wiki pages (introduced in GitLab 8.4)
 - the milestones (introduced in GitLab 8.7)
 - the labels (introduced in GitLab 8.7)
+- the release note descriptions (introduced in GitLab 8.12)
 
 With GitLab 8.7+, references to pull requests and issues are preserved.
 
diff --git a/lib/gitlab/github_import/importer.rb b/lib/gitlab/github_import/importer.rb
index 0388c58f811..d35ee2a1c65 100644
--- a/lib/gitlab/github_import/importer.rb
+++ b/lib/gitlab/github_import/importer.rb
@@ -24,6 +24,7 @@ module Gitlab
         import_issues
         import_pull_requests
         import_wiki
+        import_releases
         handle_errors
 
         true
@@ -177,6 +178,18 @@ module Gitlab
           errors << { type: :wiki, errors: e.message }
         end
       end
+
+      def import_releases
+        releases = client.releases(repo, per_page: 100)
+        releases.each do |raw|
+          begin
+            gh_release = ReleaseFormatter.new(project, raw)
+            gh_release.create! if gh_release.valid?
+          rescue => e
+            errors << { type: :release, url: Gitlab::UrlSanitizer.sanitize(raw.url), errors: e.message }
+          end
+        end
+      end
     end
   end
 end
diff --git a/lib/gitlab/github_import/release_formatter.rb b/lib/gitlab/github_import/release_formatter.rb
new file mode 100644
index 00000000000..73d643b00ad
--- /dev/null
+++ b/lib/gitlab/github_import/release_formatter.rb
@@ -0,0 +1,23 @@
+module Gitlab
+  module GithubImport
+    class ReleaseFormatter < BaseFormatter
+      def attributes
+        {
+          project: project,
+          tag: raw_data.tag_name,
+          description: raw_data.body,
+          created_at: raw_data.created_at,
+          updated_at: raw_data.created_at
+        }
+      end
+
+      def klass
+        Release
+      end
+
+      def valid?
+        !raw_data.draft
+      end
+    end
+  end
+end
diff --git a/spec/lib/gitlab/github_import/importer_spec.rb b/spec/lib/gitlab/github_import/importer_spec.rb
index 7df288f619f..553c849c9b4 100644
--- a/spec/lib/gitlab/github_import/importer_spec.rb
+++ b/spec/lib/gitlab/github_import/importer_spec.rb
@@ -98,6 +98,30 @@ describe Gitlab::GithubImport::Importer, lib: true do
         )
       end
 
+      let(:release1) do
+        double(
+          tag_name: 'v1.0.0',
+          name: 'First release',
+          body: 'Release v1.0.0',
+          draft: false,
+          created_at: created_at,
+          updated_at: updated_at,
+          url: 'https://api.github.com/repos/octocat/Hello-World/releases/1'
+        )
+      end
+
+      let(:release2) do
+        double(
+          tag_name: 'v2.0.0',
+          name: 'Second release',
+          body: nil,
+          draft: false,
+          created_at: created_at,
+          updated_at: updated_at,
+          url: 'https://api.github.com/repos/octocat/Hello-World/releases/2'
+        )
+      end
+
       before do
         allow(project).to receive(:import_data).and_return(double.as_null_object)
         allow_any_instance_of(Octokit::Client).to receive(:rate_limit!).and_raise(Octokit::NotFound)
@@ -106,6 +130,7 @@ describe Gitlab::GithubImport::Importer, lib: true do
         allow_any_instance_of(Octokit::Client).to receive(:issues).and_return([issue1, issue2])
         allow_any_instance_of(Octokit::Client).to receive(:pull_requests).and_return([pull_request, pull_request])
         allow_any_instance_of(Octokit::Client).to receive(:last_response).and_return(double(rels: { next: nil }))
+        allow_any_instance_of(Octokit::Client).to receive(:releases).and_return([release1, release2])
         allow_any_instance_of(Gitlab::Shell).to receive(:import_repository).and_raise(Gitlab::Shell::Error)
       end
 
@@ -127,8 +152,9 @@ describe Gitlab::GithubImport::Importer, lib: true do
             { type: :issue, url: "https://api.github.com/repos/octocat/Hello-World/issues/1348", errors: "Validation failed: Title can't be blank, Title is too short (minimum is 0 characters)" },
             { type: :pull_request, url: "https://api.github.com/repos/octocat/Hello-World/pulls/1347", errors: "Invalid Repository. Use user/repo format." },
             { type: :pull_request, url: "https://api.github.com/repos/octocat/Hello-World/pulls/1347", errors: "Validation failed: Validate branches Cannot Create: This merge request already exists: [\"New feature\"]" },
-            { type: :wiki, errors: "Gitlab::Shell::Error" }
-          ]
+            { type: :wiki, errors: "Gitlab::Shell::Error" },
+            { type: :release, url: 'https://api.github.com/repos/octocat/Hello-World/releases/2', errors: "Validation failed: Description can't be blank" }
+        ]
         }
 
         described_class.new(project).execute
diff --git a/spec/lib/gitlab/github_import/release_formatter_spec.rb b/spec/lib/gitlab/github_import/release_formatter_spec.rb
new file mode 100644
index 00000000000..793128c6ab9
--- /dev/null
+++ b/spec/lib/gitlab/github_import/release_formatter_spec.rb
@@ -0,0 +1,54 @@
+require 'spec_helper'
+
+describe Gitlab::GithubImport::ReleaseFormatter, lib: true do
+  let!(:project) { create(:project, namespace: create(:namespace, path: 'octocat')) }
+  let(:octocat) { double(id: 123456, login: 'octocat') }
+  let(:created_at) { DateTime.strptime('2011-01-26T19:01:12Z') }
+
+  let(:base_data) do
+    {
+      tag_name: 'v1.0.0',
+      name: 'First release',
+      draft: false,
+      created_at: created_at,
+      published_at: created_at,
+      body: 'Release v1.0.0'
+    }
+  end
+
+  subject(:release) { described_class.new(project, raw_data) }
+
+  describe '#attributes' do
+    let(:raw_data) { double(base_data) }
+
+    it 'returns formatted attributes' do
+      expected = {
+        project: project,
+        tag: 'v1.0.0',
+        description: 'Release v1.0.0',
+        created_at: created_at,
+        updated_at: created_at
+      }
+
+      expect(release.attributes).to eq(expected)
+    end
+  end
+
+  describe '#valid' do
+    context 'when release is not a draft' do
+      let(:raw_data) { double(base_data) }
+
+      it 'returns true' do
+        expect(release.valid?).to eq true
+      end
+    end
+
+    context 'when release is draft' do
+      let(:raw_data) { double(base_data.merge(draft: true)) }
+
+      it 'returns false' do
+        expect(release.valid?).to eq false
+      end
+    end
+  end
+end
-- 
GitLab