Skip to content
Snippets Groups Projects
Commit e19bac4c authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets
Browse files

Merge branch 'gitlab_importer' into 'master'

Gitlab.com integration && Gitlab importer

#1933

See merge request !1456
parents 0a9cab4e 1ac20698
No related branches found
No related tags found
No related merge requests found
Pipeline #
Showing
with 266 additions and 50 deletions
Loading
@@ -32,6 +32,8 @@ v 7.8.0
Loading
@@ -32,6 +32,8 @@ v 7.8.0
- Disable blacklist validation for project names - Disable blacklist validation for project names
- Allow configuring protection of the default branch upon first push (Marco Wessel) - Allow configuring protection of the default branch upon first push (Marco Wessel)
- -
- Add gitlab.com importer
- Add an ability to login with gitlab.com
- -
- Add a commit calendar to the user profile (Hannes Rosenögger) - Add a commit calendar to the user profile (Hannes Rosenögger)
- -
Loading
Loading
Loading
@@ -29,6 +29,7 @@ gem 'omniauth-twitter'
Loading
@@ -29,6 +29,7 @@ gem 'omniauth-twitter'
gem 'omniauth-github' gem 'omniauth-github'
gem 'omniauth-shibboleth' gem 'omniauth-shibboleth'
gem 'omniauth-kerberos' gem 'omniauth-kerberos'
gem 'omniauth-gitlab'
gem 'doorkeeper', '2.1.0' gem 'doorkeeper', '2.1.0'
gem "rack-oauth2", "~> 1.0.5" gem "rack-oauth2", "~> 1.0.5"
   
Loading
Loading
Loading
@@ -332,6 +332,9 @@ GEM
Loading
@@ -332,6 +332,9 @@ GEM
omniauth-github (1.1.1) omniauth-github (1.1.1)
omniauth (~> 1.0) omniauth (~> 1.0)
omniauth-oauth2 (~> 1.1) omniauth-oauth2 (~> 1.1)
omniauth-gitlab (1.0.0)
omniauth (~> 1.0)
omniauth-oauth2 (~> 1.0)
omniauth-google-oauth2 (0.2.5) omniauth-google-oauth2 (0.2.5)
omniauth (> 1.0) omniauth (> 1.0)
omniauth-oauth2 (~> 1.1) omniauth-oauth2 (~> 1.1)
Loading
@@ -689,6 +692,7 @@ DEPENDENCIES
Loading
@@ -689,6 +692,7 @@ DEPENDENCIES
octokit (= 3.7.0) octokit (= 3.7.0)
omniauth (~> 1.1.3) omniauth (~> 1.1.3)
omniauth-github omniauth-github
omniauth-gitlab
omniauth-google-oauth2 omniauth-google-oauth2
omniauth-kerberos omniauth-kerberos
omniauth-shibboleth omniauth-shibboleth
Loading
Loading
app/assets/images/authbuttons/gitlab_32.png

1.01 KiB

app/assets/images/authbuttons/gitlab_64.png

2.94 KiB

class @ImporterStatus
constructor: (@jobs_url, @import_url) ->
this.initStatusPage()
this.setAutoUpdate()
initStatusPage: ->
$(".btn-add-to-import").click (event) =>
new_namespace = null
tr = $(event.currentTarget).closest("tr")
id = tr.attr("id").replace("repo_", "")
if tr.find(".import-target input").length > 0
new_namespace = tr.find(".import-target input").prop("value")
tr.find(".import-target").empty().append(new_namespace + "/" + tr.find(".import-target").data("project_name"))
$.post @import_url, {repo_id: id, new_namespace: new_namespace}, dataType: 'script'
setAutoUpdate: ->
setInterval (=>
$.get @jobs_url, (data) =>
$.each data, (i, job) =>
job_item = $("#project_" + job.id)
status_field = job_item.find(".job-status")
if job.import_status == 'finished'
job_item.removeClass("active").addClass("success")
status_field.html('<span class="cgreen"><i class="fa fa-check"></i> done</span>')
else if job.import_status == 'started'
status_field.html("<i class='fa fa-spinner fa-spin'></i> started")
else
status_field.html(job.import_status)
), 4000
\ No newline at end of file
class Import::BaseController < ApplicationController
private
def get_or_create_namespace
existing_namespace = Namespace.find_by("path = ? OR name = ?", @target_namespace, @target_namespace)
if existing_namespace
if existing_namespace.owner == current_user
namespace = existing_namespace
else
@already_been_taken = true
return false
end
else
namespace = Group.create(name: @target_namespace, path: @target_namespace, owner: current_user)
namespace.add_owner(current_user)
namespace
end
end
end
class GithubImportsController < ApplicationController class Import::GithubController < Import::BaseController
before_filter :github_auth, except: :callback before_filter :github_auth, except: :callback
   
rescue_from Octokit::Unauthorized, with: :github_unauthorized rescue_from Octokit::Unauthorized, with: :github_unauthorized
Loading
@@ -7,7 +7,7 @@ class GithubImportsController < ApplicationController
Loading
@@ -7,7 +7,7 @@ class GithubImportsController < ApplicationController
token = client.auth_code.get_token(params[:code]).token token = client.auth_code.get_token(params[:code]).token
current_user.github_access_token = token current_user.github_access_token = token
current_user.save current_user.save
redirect_to status_github_import_url redirect_to status_import_github_url
end end
   
def status def status
Loading
@@ -30,30 +30,18 @@ class GithubImportsController < ApplicationController
Loading
@@ -30,30 +30,18 @@ class GithubImportsController < ApplicationController
def create def create
@repo_id = params[:repo_id].to_i @repo_id = params[:repo_id].to_i
repo = octo_client.repo(@repo_id) repo = octo_client.repo(@repo_id)
target_namespace = params[:new_namespace].presence || repo.owner.login @target_namespace = params[:new_namespace].presence || repo.owner.login
existing_namespace = Namespace.find_by("path = ? OR name = ?", target_namespace, target_namespace)
if existing_namespace
if existing_namespace.owner == current_user
namespace = existing_namespace
else
@already_been_taken = true
@target_namespace = target_namespace
@project_name = repo.name @project_name = repo.name
render and return
end
else
namespace = Group.create(name: target_namespace, path: target_namespace, owner: current_user)
namespace.add_owner(current_user)
end
@project = Gitlab::Github::ProjectCreator.new(repo, namespace, current_user).execute namespace = get_or_create_namespace || (render and return)
@project = Gitlab::GithubImport::ProjectCreator.new(repo, namespace, current_user).execute
end end
   
private private
   
def client def client
@client ||= Gitlab::Github::Client.new.client @client ||= Gitlab::GithubImport::Client.new.client
end end
   
def octo_client def octo_client
Loading
@@ -69,7 +57,7 @@ class GithubImportsController < ApplicationController
Loading
@@ -69,7 +57,7 @@ class GithubImportsController < ApplicationController
   
def go_to_github_for_permissions def go_to_github_for_permissions
redirect_to client.auth_code.authorize_url({ redirect_to client.auth_code.authorize_url({
redirect_uri: callback_github_import_url, redirect_uri: callback_import_github_url,
scope: "repo, user, user:email" scope: "repo, user, user:email"
}) })
end end
Loading
Loading
class Import::GitlabController < Import::BaseController
before_filter :gitlab_auth, except: :callback
rescue_from OAuth2::Error, with: :gitlab_unauthorized
def callback
token = client.get_token(params[:code], callback_import_gitlab_url)
current_user.gitlab_access_token = token
current_user.save
redirect_to status_import_gitlab_url
end
def status
@repos = client.projects
@already_added_projects = current_user.created_projects.where(import_type: "gitlab")
already_added_projects_names = @already_added_projects.pluck(:import_source)
@repos.to_a.reject!{ |repo| already_added_projects_names.include? repo["path_with_namespace"] }
end
def jobs
jobs = current_user.created_projects.where(import_type: "gitlab").to_json(only: [:id, :import_status])
render json: jobs
end
def create
@repo_id = params[:repo_id].to_i
repo = client.project(@repo_id)
@target_namespace = params[:new_namespace].presence || repo["namespace"]["path"]
@project_name = repo["name"]
namespace = get_or_create_namespace || (render and return)
@project = Gitlab::GitlabImport::ProjectCreator.new(repo, namespace, current_user).execute
end
private
def client
@client ||= Gitlab::GitlabImport::Client.new(current_user.gitlab_access_token)
end
def gitlab_auth
if current_user.gitlab_access_token.blank?
go_to_gitlab_for_permissions
end
end
def go_to_gitlab_for_permissions
redirect_to client.authorize_url(callback_import_gitlab_url)
end
def gitlab_unauthorized
go_to_gitlab_for_permissions
end
end
Loading
@@ -4,7 +4,7 @@ module OauthHelper
Loading
@@ -4,7 +4,7 @@ module OauthHelper
end end
   
def default_providers def default_providers
[:twitter, :github, :google_oauth2, :ldap] [:twitter, :github, :gitlab, :google_oauth2, :ldap]
end end
   
def enabled_oauth_providers def enabled_oauth_providers
Loading
@@ -13,7 +13,7 @@ module OauthHelper
Loading
@@ -13,7 +13,7 @@ module OauthHelper
   
def enabled_social_providers def enabled_social_providers
enabled_oauth_providers.select do |name| enabled_oauth_providers.select do |name|
[:twitter, :github, :google_oauth2].include?(name.to_sym) [:twitter, :gitlab, :github, :google_oauth2].include?(name.to_sym)
end end
end end
   
Loading
Loading
Loading
@@ -253,4 +253,8 @@ module ProjectsHelper
Loading
@@ -253,4 +253,8 @@ module ProjectsHelper
def github_import_enabled? def github_import_enabled?
enabled_oauth_providers.include?(:github) enabled_oauth_providers.include?(:github)
end end
def gitlab_import_enabled?
enabled_oauth_providers.include?(:gitlab)
end
end end
Loading
@@ -17,7 +17,7 @@
Loading
@@ -17,7 +17,7 @@
%tr{id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}"} %tr{id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}"}
%td= project.import_source %td= project.import_source
%td %td
%strong= link_to project.name_with_namespace, project %strong= link_to project.path_with_namespace, project
%td.job-status %td.job-status
- if project.import_status == 'finished' - if project.import_status == 'finished'
%span.cgreen %span.cgreen
Loading
@@ -34,30 +34,6 @@
Loading
@@ -34,30 +34,6 @@
%td.import-actions.job-status %td.import-actions.job-status
= button_tag "Add", class: "btn btn-add-to-import" = button_tag "Add", class: "btn btn-add-to-import"
   
:coffeescript :coffeescript
$(".btn-add-to-import").click () -> $ ->
new_namespace = null new ImporterStatus("#{jobs_import_github_path}", "#{import_github_path}")
tr = $(this).closest("tr")
id = tr.attr("id").replace("repo_", "")
if tr.find(".import-target input").length > 0
new_namespace = tr.find(".import-target input").prop("value")
tr.find(".import-target").empty().append(new_namespace + "/" + tr.find(".import-target").data("project_name"))
$.post "#{github_import_url}", {repo_id: id, new_namespace: new_namespace}, dataType: 'script'
setInterval (->
$.get "#{jobs_github_import_path}", (data)->
$.each data, (i, job) ->
job_item = $("#project_" + job.id)
status_field = job_item.find(".job-status")
if job.import_status == 'finished'
job_item.removeClass("active").addClass("success")
status_field.html('<span class="cgreen"><i class="fa fa-check"></i> done</span>')
else if job.import_status == 'started'
status_field.html("<i class='fa fa-spinner fa-spin'></i> started")
else
status_field.html(job.import_status)
), 4000
%h3.page-title
%i.fa.fa-github
Import repositories from GitLab.com
%p.light
Select projects you want to import.
%hr
%table.table.import-jobs
%thead
%tr
%th From GitLab.com
%th To GitLab private instance
%th Status
%tbody
- @already_added_projects.each do |project|
%tr{id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}"}
%td= project.import_source
%td
%strong= link_to project.path_with_namespace, project
%td.job-status
- if project.import_status == 'finished'
%span.cgreen
%i.fa.fa-check
done
- else
= project.human_import_status_name
- @repos.each do |repo|
%tr{id: "repo_#{repo["id"]}"}
%td= repo["path_with_namespace"]
%td.import-target
= repo["path_with_namespace"]
%td.import-actions.job-status
= button_tag "Add", class: "btn btn-add-to-import"
:coffeescript
$ ->
new ImporterStatus("#{jobs_import_gitlab_path}", "#{import_gitlab_url}")
Loading
@@ -7,16 +7,3 @@
Loading
@@ -7,16 +7,3 @@
.modal-body .modal-body
You need to setup integration with GitHub first. You need to setup integration with GitHub first.
= link_to 'How to setup integration with GitHub', 'https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/integration/github.md' = link_to 'How to setup integration with GitHub', 'https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/integration/github.md'
:javascript
$(function(){
var import_modal = $('#github_import_modal').modal({modal: true, show:false});
$('.how_to_import_link').bind("click", function(e){
e.preventDefault();
import_modal.show();
});
$('.modal-header .close').bind("click", function(){
import_modal.hide();
})
})
%div#gitlab_import_modal.modal.hide
.modal-dialog
.modal-content
.modal-header
%a.close{href: "#", "data-dismiss" => "modal"} ×
%h3 GitLab OAuth import
.modal-body
You need to setup integration with GitLab first.
= link_to 'How to setup integration with GitLab', 'https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/integration/gitlab.md'
\ No newline at end of file
Loading
@@ -44,7 +44,7 @@
Loading
@@ -44,7 +44,7 @@
.col-sm-2 .col-sm-2
.col-sm-10 .col-sm-10
- if github_import_enabled? - if github_import_enabled?
= link_to status_github_import_path do = link_to status_import_github_path do
%i.fa.fa-github %i.fa.fa-github
Import projects from GitHub Import projects from GitHub
- else - else
Loading
@@ -53,6 +53,19 @@
Loading
@@ -53,6 +53,19 @@
Import projects from GitHub Import projects from GitHub
= render 'github_import_modal' = render 'github_import_modal'
.project-import.form-group
.col-sm-2
.col-sm-10
- if gitlab_import_enabled?
= link_to status_import_gitlab_path do
%i.fa.fa-heart
Import projects from GitLab.com
- else
= link_to '#', class: 'how_to_import_link light' do
%i.fa.fa-heart
Import projects from GitLab.com
= render 'gitlab_import_modal'
%hr.prepend-botton-10 %hr.prepend-botton-10
   
.form-group .form-group
Loading
@@ -79,3 +92,11 @@
Loading
@@ -79,3 +92,11 @@
%i.fa.fa-spinner.fa-spin %i.fa.fa-spinner.fa-spin
Creating project &amp; repository. Creating project &amp; repository.
%p Please wait a moment, this page will automatically refresh when ready. %p Please wait a moment, this page will automatically refresh when ready.
:coffeescript
$ ->
$('.how_to_import_link').bind 'click', (e) ->
e.preventDefault()
import_modal = $(this).parent().find(".modal").show()
$('.modal-header .close').bind 'click', ->
$(".modal").hide()
\ No newline at end of file
Loading
@@ -10,10 +10,12 @@ class RepositoryImportWorker
Loading
@@ -10,10 +10,12 @@ class RepositoryImportWorker
project.path_with_namespace, project.path_with_namespace,
project.import_url) project.import_url)
   
if project.import_type == 'github' result_of_data_import = if project.import_type == 'github'
result_of_data_import = Gitlab::Github::Importer.new(project).execute Gitlab::GithubImport::Importer.new(project).execute
elsif project.import_type == 'gitlab'
Gitlab::GitlabImport::Importer.new(project).execute
else else
result_of_data_import = true true
end end
   
if result && result_of_data_import if result && result_of_data_import
Loading
Loading
Loading
@@ -27,7 +27,7 @@ Doorkeeper.configure do
Loading
@@ -27,7 +27,7 @@ Doorkeeper.configure do
   
# Access token expiration time (default 2 hours). # Access token expiration time (default 2 hours).
# If you want to disable expiration, set this to nil. # If you want to disable expiration, set this to nil.
# access_token_expires_in 2.hours access_token_expires_in nil
   
# Reuse access token for the same resource owner within an application (disabled by default) # Reuse access token for the same resource owner within an application (disabled by default)
# Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/383 # Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/383
Loading
Loading
Loading
@@ -51,15 +51,26 @@ Gitlab::Application.routes.draw do
Loading
@@ -51,15 +51,26 @@ Gitlab::Application.routes.draw do
end end
get '/s/:username' => 'snippets#user_index', as: :user_snippets, constraints: { username: /.*/ } get '/s/:username' => 'snippets#user_index', as: :user_snippets, constraints: { username: /.*/ }
   
# #
# Github importer area # Import
# #
resource :github_import, only: [:create, :new] do namespace :import do
resource :github, only: [:create, :new], controller: :github do
get :status get :status
get :callback get :callback
get :jobs get :jobs
end end
   
resource :gitlab, only: [:create, :new], controller: :gitlab do
get :status
get :callback
get :jobs
end
end
# #
# Explore area # Explore area
# #
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment