mirror of
https://github.com/wahyd4/gitlabhq.git
synced 2026-08-19 17:46:07 +10:00
Merge branch 'sync-project-create' into 'master'
Create project & repository at the same time * block project creation if repository cant be created * show proper error message about failed to create repository * dont use ajax for project creation any more - its fast enough * if project repository does not exist - propose to create one or import * move import functionality to separate resource Fixes #1768 See merge request !1278
This commit is contained in:
@@ -7,8 +7,8 @@ v 7.6.0
|
||||
- Add optional Sidekiq MemoryKiller middleware (enabled via SIDEKIQ_MAX_RSS env variable)
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
- Create project with repository in synchrony
|
||||
- Added ability to create empty repo or import existing one if project does not have repository
|
||||
-
|
||||
-
|
||||
-
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
class Projects::ImportsController < Projects::ApplicationController
|
||||
# Authorize
|
||||
before_filter :authorize_admin_project!
|
||||
before_filter :require_no_repo
|
||||
before_filter :redirect_if_progress, except: :show
|
||||
|
||||
def new
|
||||
end
|
||||
|
||||
def create
|
||||
@project.import_url = params[:project][:import_url]
|
||||
|
||||
if @project.save
|
||||
@project.reload
|
||||
|
||||
if @project.import_failed?
|
||||
@project.import_retry
|
||||
else
|
||||
@project.import_start
|
||||
end
|
||||
end
|
||||
|
||||
redirect_to project_import_path(@project)
|
||||
end
|
||||
|
||||
def show
|
||||
unless @project.import_in_progress?
|
||||
if @project.import_finished?
|
||||
redirect_to(@project) and return
|
||||
else
|
||||
redirect_to new_project_import_path(@project) and return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def require_no_repo
|
||||
if @project.repository_exists?
|
||||
redirect_to(@project) and return
|
||||
end
|
||||
end
|
||||
|
||||
def redirect_if_progress
|
||||
if @project.import_in_progress?
|
||||
redirect_to project_import_path(@project) and return
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,7 +1,14 @@
|
||||
class Projects::RepositoriesController < Projects::ApplicationController
|
||||
# Authorize
|
||||
before_filter :authorize_download_code!
|
||||
before_filter :require_non_empty_project
|
||||
before_filter :require_non_empty_project, except: :create
|
||||
before_filter :authorize_admin_project!, only: :create
|
||||
|
||||
def create
|
||||
@project.create_repository
|
||||
|
||||
redirect_to @project
|
||||
end
|
||||
|
||||
def archive
|
||||
unless can?(current_user, :download_code, @project)
|
||||
|
||||
@@ -4,7 +4,7 @@ class ProjectsController < ApplicationController
|
||||
before_filter :repository, except: [:new, :create]
|
||||
|
||||
# Authorize
|
||||
before_filter :authorize_admin_project!, only: [:edit, :update, :destroy, :transfer, :archive, :unarchive, :retry_import]
|
||||
before_filter :authorize_admin_project!, only: [:edit, :update, :destroy, :transfer, :archive, :unarchive]
|
||||
|
||||
layout 'navless', only: [:new, :create, :fork]
|
||||
before_filter :set_title, only: [:new, :create]
|
||||
@@ -19,10 +19,11 @@ class ProjectsController < ApplicationController
|
||||
|
||||
def create
|
||||
@project = ::Projects::CreateService.new(current_user, project_params).execute
|
||||
flash[:notice] = 'Project was successfully created.' if @project.saved?
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
if @project.saved?
|
||||
redirect_to project_path(@project), notice: 'Project was successfully created.'
|
||||
else
|
||||
render 'new'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -47,7 +48,7 @@ class ProjectsController < ApplicationController
|
||||
|
||||
def show
|
||||
if @project.import_in_progress?
|
||||
redirect_to import_project_path(@project)
|
||||
redirect_to project_import_path(@project)
|
||||
return
|
||||
end
|
||||
|
||||
@@ -60,39 +61,22 @@ class ProjectsController < ApplicationController
|
||||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
if @project.empty_repo?
|
||||
render "projects/empty", layout: user_layout
|
||||
if @project.repository_exists?
|
||||
if @project.empty_repo?
|
||||
render "projects/empty", layout: user_layout
|
||||
else
|
||||
@last_push = current_user.recent_push(@project.id) if current_user
|
||||
render :show, layout: user_layout
|
||||
end
|
||||
else
|
||||
@last_push = current_user.recent_push(@project.id) if current_user
|
||||
render :show, layout: user_layout
|
||||
render "projects/no_repo", layout: user_layout
|
||||
end
|
||||
end
|
||||
|
||||
format.json { pager_json("events/_events", @events.count) }
|
||||
end
|
||||
end
|
||||
|
||||
def import
|
||||
if @project.import_finished?
|
||||
redirect_to @project
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
def retry_import
|
||||
unless @project.import_failed?
|
||||
redirect_to import_project_path(@project)
|
||||
end
|
||||
|
||||
@project.import_url = project_params[:import_url]
|
||||
|
||||
if @project.save
|
||||
@project.reload
|
||||
@project.import_retry
|
||||
end
|
||||
|
||||
redirect_to import_project_path(@project)
|
||||
end
|
||||
|
||||
def destroy
|
||||
return access_denied! unless can?(current_user, :remove_project, @project)
|
||||
|
||||
|
||||
+22
-1
@@ -136,7 +136,7 @@ class Project < ActiveRecord::Base
|
||||
|
||||
state_machine :import_status, initial: :none do
|
||||
event :import_start do
|
||||
transition :none => :started
|
||||
transition [:none, :finished] => :started
|
||||
end
|
||||
|
||||
event :import_finish do
|
||||
@@ -586,4 +586,25 @@ class Project < ActiveRecord::Base
|
||||
def origin_merge_requests
|
||||
merge_requests.where(source_project_id: self.id)
|
||||
end
|
||||
|
||||
def create_repository
|
||||
if gitlab_shell.add_repository(path_with_namespace)
|
||||
true
|
||||
else
|
||||
errors.add(:base, "Failed to create repository")
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def repository_exists?
|
||||
!!repository.exists?
|
||||
end
|
||||
|
||||
def create_wiki
|
||||
ProjectWiki.new(self, self.owner).wiki
|
||||
true
|
||||
rescue ProjectWiki::CouldNotCreateWikiError => ex
|
||||
errors.add(:base, "Failed create wiki")
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
@@ -37,37 +37,24 @@ module Projects
|
||||
|
||||
@project.creator = current_user
|
||||
|
||||
if @project.save
|
||||
log_info("#{@project.owner.name} created a new project \"#{@project.name_with_namespace}\"")
|
||||
system_hook_service.execute_hooks_for(@project, :create)
|
||||
Project.transaction do
|
||||
@project.save
|
||||
|
||||
unless @project.group
|
||||
@project.team << [current_user, :master]
|
||||
end
|
||||
|
||||
@project.update_column(:last_activity_at, @project.created_at)
|
||||
|
||||
if @project.import?
|
||||
@project.import_start
|
||||
else
|
||||
GitlabShellWorker.perform_async(
|
||||
:add_repository,
|
||||
@project.path_with_namespace
|
||||
)
|
||||
end
|
||||
|
||||
if @project.wiki_enabled?
|
||||
begin
|
||||
# force the creation of a wiki,
|
||||
ProjectWiki.new(@project, @project.owner).wiki
|
||||
rescue ProjectWiki::CouldNotCreateWikiError => ex
|
||||
# Prevent project observer crash
|
||||
# if failed to create wiki
|
||||
nil
|
||||
unless @project.import?
|
||||
unless @project.create_repository
|
||||
raise 'Failed to create repository'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if @project.persisted?
|
||||
if @project.wiki_enabled?
|
||||
@project.create_wiki
|
||||
end
|
||||
|
||||
after_create_actions
|
||||
end
|
||||
|
||||
@project
|
||||
rescue => ex
|
||||
@project.errors.add(:base, "Can't save project. Please try again later")
|
||||
@@ -84,5 +71,20 @@ module Projects
|
||||
namespace = Namespace.find_by(id: namespace_id)
|
||||
current_user.can?(:create_projects, namespace)
|
||||
end
|
||||
|
||||
def after_create_actions
|
||||
log_info("#{@project.owner.name} created a new project \"#{@project.name_with_namespace}\"")
|
||||
system_hook_service.execute_hooks_for(@project, :create)
|
||||
|
||||
unless @project.group
|
||||
@project.team << [current_user, :master]
|
||||
end
|
||||
|
||||
@project.update_column(:last_activity_at, @project.created_at)
|
||||
|
||||
if @project.import?
|
||||
@project.import_start
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
- if @project.saved?
|
||||
- if @project.import?
|
||||
:plain
|
||||
location.href = "#{import_project_path(@project)}";
|
||||
- else
|
||||
:plain
|
||||
location.href = "#{project_path(@project)}";
|
||||
- else
|
||||
:plain
|
||||
$(".project-edit-errors").html("#{escape_javascript(render('errors'))}");
|
||||
$('.project-submit').enable();
|
||||
$('.save-project-loader').hide();
|
||||
$('.project-edit-container').show();
|
||||
@@ -1,31 +0,0 @@
|
||||
- if @project.import_in_progress?
|
||||
.save-project-loader
|
||||
.center
|
||||
%h2
|
||||
%i.fa.fa-spinner.fa-spin
|
||||
Import in progress.
|
||||
%p.monospace git clone --bare #{hidden_pass_url(@project.import_url)}
|
||||
%p Please wait while we import the repository for you. Refresh at will.
|
||||
:javascript
|
||||
new ProjectImport();
|
||||
|
||||
- elsif @project.import_failed?
|
||||
.save-project-loader
|
||||
.center
|
||||
%h2
|
||||
Import failed. Retry?
|
||||
%hr
|
||||
- if can?(current_user, :admin_project, @project)
|
||||
= form_for @project, url: retry_import_project_path(@project), method: :put, html: { class: 'form-horizontal' } do |f|
|
||||
.form-group.import-url-data
|
||||
= f.label :import_url, class: 'control-label' do
|
||||
%span Import existing git repo
|
||||
.col-sm-10
|
||||
= f.text_field :import_url, class: 'form-control', placeholder: 'https://github.com/randx/six.git'
|
||||
.bs-callout.bs-callout-info
|
||||
This URL must be publicly accessible or you can add a username and password like this: https://username:password@gitlab.com/company/project.git.
|
||||
%br
|
||||
The import will time out after 4 minutes. For big repositories, use a clone/push combination.
|
||||
For SVN repositories, check #{link_to "this migrating from SVN doc.", "http://doc.gitlab.com/ce/workflow/migrating_from_svn.html"}
|
||||
.form-actions
|
||||
= f.submit 'Retry import', class: "btn btn-create", tabindex: 4
|
||||
@@ -0,0 +1,21 @@
|
||||
%h3.page-title
|
||||
- if @project.import_failed?
|
||||
Import failed. Retry?
|
||||
- else
|
||||
Import repository
|
||||
|
||||
%hr
|
||||
|
||||
= form_for @project, url: project_import_path(@project), method: :post, html: { class: 'form-horizontal' } do |f|
|
||||
.form-group.import-url-data
|
||||
= f.label :import_url, class: 'control-label' do
|
||||
%span Import existing git repo
|
||||
.col-sm-10
|
||||
= f.text_field :import_url, class: 'form-control', placeholder: 'https://github.com/randx/six.git'
|
||||
.bs-callout.bs-callout-info
|
||||
This URL must be publicly accessible or you can add a username and password like this: https://username:password@gitlab.com/company/project.git.
|
||||
%br
|
||||
The import will time out after 4 minutes. For big repositories, use a clone/push combination.
|
||||
For SVN repositories, check #{link_to "this migrating from SVN doc.", "http://doc.gitlab.com/ce/workflow/migrating_from_svn.html"}
|
||||
.form-actions
|
||||
= f.submit 'Start import', class: "btn btn-create", tabindex: 4
|
||||
@@ -0,0 +1,9 @@
|
||||
.save-project-loader
|
||||
.center
|
||||
%h2
|
||||
%i.fa.fa-spinner.fa-spin
|
||||
Import in progress.
|
||||
%p.monospace git clone --bare #{hidden_pass_url(@project.import_url)}
|
||||
%p Please wait while we import the repository for you. Refresh at will.
|
||||
:javascript
|
||||
new ProjectImport();
|
||||
@@ -3,7 +3,7 @@
|
||||
= render 'projects/errors'
|
||||
.project-edit-content
|
||||
|
||||
= form_for @project, remote: true, html: { class: 'new_project form-horizontal' } do |f|
|
||||
= form_for @project, html: { class: 'new_project form-horizontal' } do |f|
|
||||
.form-group.project-name-holder
|
||||
= f.label :name, class: 'control-label' do
|
||||
%strong Project name
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
%h2
|
||||
%i.fa.fa-warning
|
||||
No repository
|
||||
|
||||
%p.slead
|
||||
The repository for this project does not exist.
|
||||
%br
|
||||
This means you can not push code until you create an empty repository or import existing one.
|
||||
%hr
|
||||
|
||||
.no-repo-actions
|
||||
= link_to project_repository_path(@project), method: :post, class: 'btn btn-primary' do
|
||||
Create empty bare repository
|
||||
|
||||
%strong.prepend-left-10.append-right-10 or
|
||||
|
||||
= link_to new_project_import_path(@project), class: 'btn' do
|
||||
Import repository
|
||||
|
||||
- if can? current_user, :remove_project, @project
|
||||
.prepend-top-20
|
||||
= link_to 'Remove project', @project, data: { confirm: remove_project_message(@project)}, method: :delete, class: "btn btn-remove pull-right"
|
||||
+2
-3
@@ -186,8 +186,6 @@ Gitlab::Application.routes.draw do
|
||||
post :upload_image
|
||||
post :toggle_star
|
||||
get :autocomplete_sources
|
||||
get :import
|
||||
put :retry_import
|
||||
end
|
||||
|
||||
scope module: :projects do
|
||||
@@ -232,8 +230,9 @@ Gitlab::Application.routes.draw do
|
||||
end
|
||||
|
||||
resource :fork, only: [:new, :create]
|
||||
resource :import, only: [:new, :create, :show]
|
||||
|
||||
resource :repository, only: [:show] do
|
||||
resource :repository, only: [:show, :create] do
|
||||
member do
|
||||
get "archive", constraints: { format: Gitlab::Regex.archive_formats_regex }
|
||||
end
|
||||
|
||||
@@ -131,7 +131,7 @@ module SharedProject
|
||||
end
|
||||
|
||||
step 'public empty project "Empty Public Project"' do
|
||||
create :empty_project, :public, name: "Empty Public Project"
|
||||
create :project_empty_repo, :public, name: "Empty Public Project"
|
||||
end
|
||||
|
||||
step 'project "Community" has comments' do
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
#
|
||||
|
||||
FactoryGirl.define do
|
||||
# Project without repository
|
||||
#
|
||||
# Project does not have bare repository.
|
||||
# Use this factory if you dont need repository in tests
|
||||
factory :empty_project, class: 'Project' do
|
||||
sequence(:name) { |n| "project#{n}" }
|
||||
path { name.downcase.gsub(/\s/, '_') }
|
||||
@@ -47,6 +51,20 @@ FactoryGirl.define do
|
||||
end
|
||||
end
|
||||
|
||||
# Project with empty repository
|
||||
#
|
||||
# This is a case when you just created a project
|
||||
# but not pushed any code there yet
|
||||
factory :project_empty_repo, parent: :empty_project do
|
||||
after :create do |project|
|
||||
project.create_repository
|
||||
end
|
||||
end
|
||||
|
||||
# Project with test repository
|
||||
#
|
||||
# Test repository source can be found at
|
||||
# https://gitlab.com/gitlab-org/gitlab-test
|
||||
factory :project, parent: :empty_project do
|
||||
path { 'gitlabhq' }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user