Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
gitlab-ce
Commits
d77181d5
Commit
d77181d5
authored
Jan 27, 2018
by
Matija Čupić
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into persistent-callouts
parents
860c7c4b
dc325c67
Changes
26
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
295 additions
and
173 deletions
+295
-173
app/assets/javascripts/clusters/clusters_bundle.js
app/assets/javascripts/clusters/clusters_bundle.js
+2
-10
app/assets/javascripts/clusters/clusters_index.js
app/assets/javascripts/clusters/clusters_index.js
+15
-53
app/assets/javascripts/toggle_buttons.js
app/assets/javascripts/toggle_buttons.js
+61
-0
app/models/project.rb
app/models/project.rb
+3
-0
app/models/project_services/emails_on_push_service.rb
app/models/project_services/emails_on_push_service.rb
+1
-1
app/models/project_services/irker_service.rb
app/models/project_services/irker_service.rb
+1
-1
app/models/project_services/pipelines_email_service.rb
app/models/project_services/pipelines_email_service.rb
+1
-1
app/models/service.rb
app/models/service.rb
+6
-0
app/views/help/index.html.haml
app/views/help/index.html.haml
+9
-8
app/views/projects/clusters/_cluster.html.haml
app/views/projects/clusters/_cluster.html.haml
+3
-2
app/views/projects/clusters/_integration_form.html.haml
app/views/projects/clusters/_integration_form.html.haml
+3
-4
app/workers/repository_import_worker.rb
app/workers/repository_import_worker.rb
+9
-1
changelogs/unreleased/42327-import-from-gitlab-com-fails-destination-already-exists-and-is-not-an-empty-directory-error.yml
...on-already-exists-and-is-not-an-empty-directory-error.yml
+6
-0
changelogs/unreleased/cs-fix-commercial-content-check.yml
changelogs/unreleased/cs-fix-commercial-content-check.yml
+6
-0
lib/gitlab/import_export/shared.rb
lib/gitlab/import_export/shared.rb
+6
-1
spec/features/projects/clusters/gcp_spec.rb
spec/features/projects/clusters/gcp_spec.rb
+1
-1
spec/features/projects/clusters/user_spec.rb
spec/features/projects/clusters/user_spec.rb
+1
-1
spec/features/projects/clusters_spec.rb
spec/features/projects/clusters_spec.rb
+3
-3
spec/javascripts/clusters/clusters_bundle_spec.js
spec/javascripts/clusters/clusters_bundle_spec.js
+16
-8
spec/javascripts/clusters/clusters_index_spec.js
spec/javascripts/clusters/clusters_index_spec.js
+0
-58
spec/javascripts/fixtures/clusters.rb
spec/javascripts/fixtures/clusters.rb
+0
-15
spec/javascripts/toggle_buttons_spec.js
spec/javascripts/toggle_buttons_spec.js
+120
-0
spec/lib/gitlab/import_export/project.json
spec/lib/gitlab/import_export/project.json
+1
-1
spec/lib/gitlab/import_export/project_tree_saver_spec.rb
spec/lib/gitlab/import_export/project_tree_saver_spec.rb
+5
-1
spec/requests/api/issues_spec.rb
spec/requests/api/issues_spec.rb
+2
-2
spec/workers/repository_import_worker_spec.rb
spec/workers/repository_import_worker_spec.rb
+14
-1
No files found.
app/assets/javascripts/clusters/clusters_bundle.js
View file @
d77181d5
...
@@ -14,6 +14,7 @@ import {
...
@@ -14,6 +14,7 @@ import {
import
ClustersService
from
'
./services/clusters_service
'
;
import
ClustersService
from
'
./services/clusters_service
'
;
import
ClustersStore
from
'
./stores/clusters_store
'
;
import
ClustersStore
from
'
./stores/clusters_store
'
;
import
applications
from
'
./components/applications.vue
'
;
import
applications
from
'
./components/applications.vue
'
;
import
setupToggleButtons
from
'
../toggle_buttons
'
;
/**
/**
* Cluster page has 2 separate parts:
* Cluster page has 2 separate parts:
...
@@ -48,12 +49,9 @@ export default class Clusters {
...
@@ -48,12 +49,9 @@ export default class Clusters {
installPrometheusEndpoint
:
installPrometheusPath
,
installPrometheusEndpoint
:
installPrometheusPath
,
});
});
this
.
toggle
=
this
.
toggle
.
bind
(
this
);
this
.
installApplication
=
this
.
installApplication
.
bind
(
this
);
this
.
installApplication
=
this
.
installApplication
.
bind
(
this
);
this
.
showToken
=
this
.
showToken
.
bind
(
this
);
this
.
showToken
=
this
.
showToken
.
bind
(
this
);
this
.
toggleButton
=
document
.
querySelector
(
'
.js-toggle-cluster
'
);
this
.
toggleInput
=
document
.
querySelector
(
'
.js-toggle-input
'
);
this
.
errorContainer
=
document
.
querySelector
(
'
.js-cluster-error
'
);
this
.
errorContainer
=
document
.
querySelector
(
'
.js-cluster-error
'
);
this
.
successContainer
=
document
.
querySelector
(
'
.js-cluster-success
'
);
this
.
successContainer
=
document
.
querySelector
(
'
.js-cluster-success
'
);
this
.
creatingContainer
=
document
.
querySelector
(
'
.js-cluster-creating
'
);
this
.
creatingContainer
=
document
.
querySelector
(
'
.js-cluster-creating
'
);
...
@@ -63,6 +61,7 @@ export default class Clusters {
...
@@ -63,6 +61,7 @@ export default class Clusters {
this
.
tokenField
=
document
.
querySelector
(
'
.js-cluster-token
'
);
this
.
tokenField
=
document
.
querySelector
(
'
.js-cluster-token
'
);
initSettingsPanels
();
initSettingsPanels
();
setupToggleButtons
(
document
.
querySelector
(
'
.js-cluster-enable-toggle-area
'
));
this
.
initApplications
();
this
.
initApplications
();
if
(
this
.
store
.
state
.
status
!==
'
created
'
)
{
if
(
this
.
store
.
state
.
status
!==
'
created
'
)
{
...
@@ -101,13 +100,11 @@ export default class Clusters {
...
@@ -101,13 +100,11 @@ export default class Clusters {
}
}
addListeners
()
{
addListeners
()
{
this
.
toggleButton
.
addEventListener
(
'
click
'
,
this
.
toggle
);
if
(
this
.
showTokenButton
)
this
.
showTokenButton
.
addEventListener
(
'
click
'
,
this
.
showToken
);
if
(
this
.
showTokenButton
)
this
.
showTokenButton
.
addEventListener
(
'
click
'
,
this
.
showToken
);
eventHub
.
$on
(
'
installApplication
'
,
this
.
installApplication
);
eventHub
.
$on
(
'
installApplication
'
,
this
.
installApplication
);
}
}
removeListeners
()
{
removeListeners
()
{
this
.
toggleButton
.
removeEventListener
(
'
click
'
,
this
.
toggle
);
if
(
this
.
showTokenButton
)
this
.
showTokenButton
.
removeEventListener
(
'
click
'
,
this
.
showToken
);
if
(
this
.
showTokenButton
)
this
.
showTokenButton
.
removeEventListener
(
'
click
'
,
this
.
showToken
);
eventHub
.
$off
(
'
installApplication
'
,
this
.
installApplication
);
eventHub
.
$off
(
'
installApplication
'
,
this
.
installApplication
);
}
}
...
@@ -151,11 +148,6 @@ export default class Clusters {
...
@@ -151,11 +148,6 @@ export default class Clusters {
this
.
updateContainer
(
prevStatus
,
this
.
store
.
state
.
status
,
this
.
store
.
state
.
statusReason
);
this
.
updateContainer
(
prevStatus
,
this
.
store
.
state
.
status
,
this
.
store
.
state
.
statusReason
);
}
}
toggle
()
{
this
.
toggleButton
.
classList
.
toggle
(
'
is-checked
'
);
this
.
toggleInput
.
setAttribute
(
'
value
'
,
this
.
toggleButton
.
classList
.
contains
(
'
is-checked
'
).
toString
());
}
showToken
()
{
showToken
()
{
const
type
=
this
.
tokenField
.
getAttribute
(
'
type
'
);
const
type
=
this
.
tokenField
.
getAttribute
(
'
type
'
);
...
...
app/assets/javascripts/clusters/clusters_index.js
View file @
d77181d5
import
Flash
from
'
../flash
'
;
import
Flash
from
'
../flash
'
;
import
{
s__
}
from
'
../locale
'
;
import
{
s__
}
from
'
../locale
'
;
import
setupToggleButtons
from
'
../toggle_buttons
'
;
import
ClustersService
from
'
./services/clusters_service
'
;
import
ClustersService
from
'
./services/clusters_service
'
;
/**
* Toggles loading and disabled classes.
* @param {HTMLElement} button
*/
const
toggleLoadingButton
=
(
button
)
=>
{
if
(
button
.
getAttribute
(
'
disabled
'
))
{
button
.
removeAttribute
(
'
disabled
'
);
}
else
{
button
.
setAttribute
(
'
disabled
'
,
true
);
}
button
.
classList
.
toggle
(
'
is-loading
'
);
};
/**
export
default
()
=>
{
* Toggles checked class for the given button
const
clusterList
=
document
.
querySelector
(
'
.js-clusters-list
'
);
* @param {HTMLElement} button
// The empty state won't have a clusterList
*/
if
(
clusterList
)
{
const
toggleValue
=
(
button
)
=>
{
setupToggleButtons
(
button
.
classList
.
toggle
(
'
is-checked
'
);
document
.
querySelector
(
'
.js-clusters-list
'
),
(
value
,
toggle
)
=>
ClustersService
.
updateCluster
(
toggle
.
dataset
.
endpoint
,
{
cluster
:
{
enabled
:
value
}
})
.
catch
((
err
)
=>
{
Flash
(
s__
(
'
ClusterIntegration|Something went wrong on our end.
'
));
throw
err
;
}),
);
}
};
};
/**
* Handles toggle buttons in the cluster's table.
*
* When the user clicks the toggle button for each cluster, it:
* - toggles the button
* - shows a loading and disables button
* - Makes a put request to the given endpoint
* Once we receive the response, either:
* 1) Show updated status in case of successfull response
* 2) Show initial status in case of failed response
*/
export
default
function
setClusterTableToggles
()
{
document
.
querySelectorAll
(
'
.js-toggle-cluster-list
'
)
.
forEach
(
button
=>
button
.
addEventListener
(
'
click
'
,
(
e
)
=>
{
const
toggleButton
=
e
.
currentTarget
;
const
endpoint
=
toggleButton
.
getAttribute
(
'
data-endpoint
'
);
toggleValue
(
toggleButton
);
toggleLoadingButton
(
toggleButton
);
const
value
=
toggleButton
.
classList
.
contains
(
'
is-checked
'
);
ClustersService
.
updateCluster
(
endpoint
,
{
cluster
:
{
enabled
:
value
}
})
.
then
(()
=>
{
toggleLoadingButton
(
toggleButton
);
})
.
catch
(()
=>
{
toggleLoadingButton
(
toggleButton
);
toggleValue
(
toggleButton
);
Flash
(
s__
(
'
ClusterIntegration|Something went wrong on our end.
'
));
});
}));
}
app/assets/javascripts/toggle_buttons.js
0 → 100644
View file @
d77181d5
import
$
from
'
jquery
'
;
import
Flash
from
'
./flash
'
;
import
{
__
}
from
'
./locale
'
;
import
{
convertPermissionToBoolean
}
from
'
./lib/utils/common_utils
'
;
/*
example HAML:
```
%button.js-project-feature-toggle.project-feature-toggle{ type: "button",
class: "#{'is-checked' if enabled?}",
'aria-label': _('Toggle Cluster') }
%input{ type: "hidden", class: 'js-project-feature-toggle-input', value: enabled? }
```
*/
function
updatetoggle
(
toggle
,
isOn
)
{
toggle
.
classList
.
toggle
(
'
is-checked
'
,
isOn
);
}
function
onToggleClicked
(
toggle
,
input
,
clickCallback
)
{
const
previousIsOn
=
convertPermissionToBoolean
(
input
.
value
);
// Visually change the toggle and start loading
updatetoggle
(
toggle
,
!
previousIsOn
);
toggle
.
setAttribute
(
'
disabled
'
,
true
);
toggle
.
classList
.
toggle
(
'
is-loading
'
,
true
);
Promise
.
resolve
(
clickCallback
(
!
previousIsOn
,
toggle
))
.
then
(()
=>
{
// Actually change the input value
input
.
setAttribute
(
'
value
'
,
!
previousIsOn
);
})
.
catch
(()
=>
{
// Revert the visuals if something goes wrong
updatetoggle
(
toggle
,
previousIsOn
);
})
.
then
(()
=>
{
// Remove the loading indicator in any case
toggle
.
removeAttribute
(
'
disabled
'
);
toggle
.
classList
.
toggle
(
'
is-loading
'
,
false
);
$
(
input
).
trigger
(
'
trigger-change
'
);
})
.
catch
(()
=>
{
Flash
(
__
(
'
Something went wrong when toggling the button
'
));
});
}
export
default
function
setupToggleButtons
(
container
,
clickCallback
=
()
=>
{})
{
const
toggles
=
container
.
querySelectorAll
(
'
.js-project-feature-toggle
'
);
toggles
.
forEach
((
toggle
)
=>
{
const
input
=
toggle
.
querySelector
(
'
.js-project-feature-toggle-input
'
);
const
isOn
=
convertPermissionToBoolean
(
input
.
value
);
// Get the visible toggle in sync with the hidden input
updatetoggle
(
toggle
,
isOn
);
toggle
.
addEventListener
(
'
click
'
,
onToggleClicked
.
bind
(
null
,
toggle
,
input
,
clickCallback
));
});
}
app/models/project.rb
View file @
d77181d5
...
@@ -568,6 +568,9 @@ class Project < ActiveRecord::Base
...
@@ -568,6 +568,9 @@ class Project < ActiveRecord::Base
RepositoryForkWorker
.
perform_async
(
id
,
RepositoryForkWorker
.
perform_async
(
id
,
forked_from_project
.
repository_storage_path
,
forked_from_project
.
repository_storage_path
,
forked_from_project
.
disk_path
)
forked_from_project
.
disk_path
)
elsif
gitlab_project_import?
# Do not retry on Import/Export until https://gitlab.com/gitlab-org/gitlab-ce/issues/26189 is solved.
RepositoryImportWorker
.
set
(
retry:
false
).
perform_async
(
self
.
id
)
else
else
RepositoryImportWorker
.
perform_async
(
self
.
id
)
RepositoryImportWorker
.
perform_async
(
self
.
id
)
end
end
...
...
app/models/project_services/emails_on_push_service.rb
View file @
d77181d5
...
@@ -2,7 +2,7 @@ class EmailsOnPushService < Service
...
@@ -2,7 +2,7 @@ class EmailsOnPushService < Service
boolean_accessor
:send_from_committer_email
boolean_accessor
:send_from_committer_email
boolean_accessor
:disable_diffs
boolean_accessor
:disable_diffs
prop_accessor
:recipients
prop_accessor
:recipients
validates
:recipients
,
presence:
true
,
if: :
activated
?
validates
:recipients
,
presence:
true
,
if: :
valid_recipients
?
def
title
def
title
'Emails on push'
'Emails on push'
...
...
app/models/project_services/irker_service.rb
View file @
d77181d5
...
@@ -4,7 +4,7 @@ class IrkerService < Service
...
@@ -4,7 +4,7 @@ class IrkerService < Service
prop_accessor
:server_host
,
:server_port
,
:default_irc_uri
prop_accessor
:server_host
,
:server_port
,
:default_irc_uri
prop_accessor
:recipients
,
:channels
prop_accessor
:recipients
,
:channels
boolean_accessor
:colorize_messages
boolean_accessor
:colorize_messages
validates
:recipients
,
presence:
true
,
if: :
activated
?
validates
:recipients
,
presence:
true
,
if: :
valid_recipients
?
before_validation
:get_channels
before_validation
:get_channels
...
...
app/models/project_services/pipelines_email_service.rb
View file @
d77181d5
class
PipelinesEmailService
<
Service
class
PipelinesEmailService
<
Service
prop_accessor
:recipients
prop_accessor
:recipients
boolean_accessor
:notify_only_broken_pipelines
boolean_accessor
:notify_only_broken_pipelines
validates
:recipients
,
presence:
true
,
if: :
activated
?
validates
:recipients
,
presence:
true
,
if: :
valid_recipients
?
def
initialize_properties
def
initialize_properties
self
.
properties
||=
{
notify_only_broken_pipelines:
true
}
self
.
properties
||=
{
notify_only_broken_pipelines:
true
}
...
...
app/models/service.rb
View file @
d77181d5
...
@@ -2,6 +2,8 @@
...
@@ -2,6 +2,8 @@
# and implement a set of methods
# and implement a set of methods
class
Service
<
ActiveRecord
::
Base
class
Service
<
ActiveRecord
::
Base
include
Sortable
include
Sortable
include
Importable
serialize
:properties
,
JSON
# rubocop:disable Cop/ActiveRecordSerialize
serialize
:properties
,
JSON
# rubocop:disable Cop/ActiveRecordSerialize
default_value_for
:active
,
false
default_value_for
:active
,
false
...
@@ -295,4 +297,8 @@ class Service < ActiveRecord::Base
...
@@ -295,4 +297,8 @@ class Service < ActiveRecord::Base
project
.
cache_has_external_wiki
project
.
cache_has_external_wiki
end
end
end
end
def
valid_recipients?
activated?
&&
!
importing?
end
end
end
app/views/help/index.html.haml
View file @
d77181d5
...
@@ -5,15 +5,16 @@
...
@@ -5,15 +5,16 @@
=
markdown_field
(
current_application_settings
,
:help_page_text
)
=
markdown_field
(
current_application_settings
,
:help_page_text
)
%hr
%hr
-
unless
current_application_settings
.
help_page_hide_commercial_content?
%h1
%h1
GitLab
GitLab
Community Edition
Community Edition
-
if
user_signed_in?
-
if
user_signed_in?
%span
=
Gitlab
::
VERSION
%span
=
Gitlab
::
VERSION
%small
=
link_to
Gitlab
::
REVISION
,
Gitlab
::
COM_URL
+
namespace_project_commits_path
(
'gitlab-org'
,
'gitlab-ce'
,
Gitlab
::
REVISION
)
%small
=
link_to
Gitlab
::
REVISION
,
Gitlab
::
COM_URL
+
namespace_project_commits_path
(
'gitlab-org'
,
'gitlab-ce'
,
Gitlab
::
REVISION
)
=
version_status_badge
=
version_status_badge
%hr
-
unless
current_application_settings
.
help_page_hide_commercial_content?
%p
.slead
%p
.slead
GitLab is open source software to collaborate on code.
GitLab is open source software to collaborate on code.
%br
%br
...
...
app/views/projects/clusters/_cluster.html.haml
View file @
d77181d5
...
@@ -12,11 +12,12 @@
...
@@ -12,11 +12,12 @@
.table-section.section-10
.table-section.section-10
.table-mobile-header
{
role:
"rowheader"
}
.table-mobile-header
{
role:
"rowheader"
}
.table-mobile-content
.table-mobile-content
%button
{
type:
"button"
,
%button
.js-project-feature-toggle.project-feature-toggle
{
type:
"button"
,
class:
"
js-toggle-cluster-list project-feature-toggle
#{'is-checked' if cluster.enabled?} #{'is-disabled' if !cluster.can_toggle_cluster?}"
,
class:
"#{'is-checked' if cluster.enabled?} #{'is-disabled' if !cluster.can_toggle_cluster?}"
,
"aria-label"
:
s_
(
"ClusterIntegration|Toggle Cluster"
),
"aria-label"
:
s_
(
"ClusterIntegration|Toggle Cluster"
),
disabled:
!
cluster
.
can_toggle_cluster?
,
disabled:
!
cluster
.
can_toggle_cluster?
,
data:
{
endpoint:
namespace_project_cluster_path
(
@project
.
namespace
,
@project
,
cluster
,
format: :json
)
}
}
data:
{
endpoint:
namespace_project_cluster_path
(
@project
.
namespace
,
@project
,
cluster
,
format: :json
)
}
}
%input
.js-project-feature-toggle-input
{
type:
"hidden"
,
value:
cluster
.
enabled?
}
=
icon
(
"spinner spin"
,
class:
"loading-icon"
)
=
icon
(
"spinner spin"
,
class:
"loading-icon"
)
%span
.toggle-icon
%span
.toggle-icon
=
sprite_icon
(
'status_success_borderless'
,
size:
16
,
css_class:
'toggle-icon-svg toggle-status-checked'
)
=
sprite_icon
(
'status_success_borderless'
,
size:
16
,
css_class:
'toggle-icon-svg toggle-status-checked'
)
...
...
app/views/projects/clusters/_integration_form.html.haml
View file @
d77181d5
...
@@ -10,13 +10,12 @@
...
@@ -10,13 +10,12 @@
=
s_
(
'ClusterIntegration|Cluster integration is enabled for this project.'
)
=
s_
(
'ClusterIntegration|Cluster integration is enabled for this project.'
)
-
else
-
else
=
s_
(
'ClusterIntegration|Cluster integration is disabled for this project.'
)
=
s_
(
'ClusterIntegration|Cluster integration is disabled for this project.'
)
%label
.append-bottom-10
%label
.append-bottom-10.js-cluster-enable-toggle-area
=
field
.
hidden_field
:enabled
,
{
class:
'js-toggle-input'
}
%button
{
type:
'button'
,
%button
{
type:
'button'
,
class:
"js-
toggle-cluster project-feature-toggle #{'is-checked' unless !
@cluster.enabled?} #{'is-disabled' unless can?(current_user, :update_cluster, @cluster)}"
,
class:
"js-
project-feature-toggle project-feature-toggle #{'is-checked' if
@cluster.enabled?} #{'is-disabled' unless can?(current_user, :update_cluster, @cluster)}"
,
"aria-label"
:
s_
(
"ClusterIntegration|Toggle Cluster"
),
"aria-label"
:
s_
(
"ClusterIntegration|Toggle Cluster"
),
disabled:
!
can?
(
current_user
,
:update_cluster
,
@cluster
)
}
disabled:
!
can?
(
current_user
,
:update_cluster
,
@cluster
)
}
=
field
.
hidden_field
:enabled
,
{
class:
'js-project-feature-toggle-input'
}
%span
.toggle-icon
%span
.toggle-icon
=
sprite_icon
(
'status_success_borderless'
,
size:
16
,
css_class:
'toggle-icon-svg toggle-status-checked'
)
=
sprite_icon
(
'status_success_borderless'
,
size:
16
,
css_class:
'toggle-icon-svg toggle-status-checked'
)
=
sprite_icon
(
'status_failed_borderless'
,
size:
16
,
css_class:
'toggle-icon-svg toggle-status-unchecked'
)
=
sprite_icon
(
'status_failed_borderless'
,
size:
16
,
css_class:
'toggle-icon-svg toggle-status-unchecked'
)
...
...
app/workers/repository_import_worker.rb
View file @
d77181d5
...
@@ -20,7 +20,11 @@ class RepositoryImportWorker
...
@@ -20,7 +20,11 @@ class RepositoryImportWorker
# to those importers to mark the import process as complete.
# to those importers to mark the import process as complete.
return
if
service
.
async?
return
if
service
.
async?
raise
result
[
:message
]
if
result
[
:status
]
==
:error
if
result
[
:status
]
==
:error
fail_import
(
project
,
result
[
:message
])
if
project
.
gitlab_project_import?
raise
result
[
:message
]
end
project
.
after_import
project
.
after_import
end
end
...
@@ -33,4 +37,8 @@ class RepositoryImportWorker
...
@@ -33,4 +37,8 @@ class RepositoryImportWorker
Rails
.
logger
.
info
(
"Project
#{
project
.
full_path
}
was in inconsistent state (
#{
project
.
import_status
}
) while importing."
)
Rails
.
logger
.
info
(
"Project
#{
project
.
full_path
}
was in inconsistent state (
#{
project
.
import_status
}
) while importing."
)
false
false
end
end
def
fail_import
(
project
,
message
)
project
.
mark_import_as_failed
(
message
)
end
end
end
changelogs/unreleased/42327-import-from-gitlab-com-fails-destination-already-exists-and-is-not-an-empty-directory-error.yml
0 → 100644
View file @
d77181d5
---
title
:
Fixes destination already exists, and some particular service errors on Import/Export
error
merge_request
:
16714
author
:
type
:
fixed
changelogs/unreleased/cs-fix-commercial-content-check.yml
0 → 100644
View file @
d77181d5
---
title
:
Fix version information not showing on help page if commercial content display
was disabled.
merge_request
:
16743
author
:
type
:
fixed
lib/gitlab/import_export/shared.rb
View file @
d77181d5
...
@@ -19,8 +19,13 @@ module Gitlab
...
@@ -19,8 +19,13 @@ module Gitlab
def
error
(
error
)
def
error
(
error
)
error_out
(
error
.
message
,
caller
[
0
].
dup
)
error_out
(
error
.
message
,
caller
[
0
].
dup
)
@errors
<<
error
.
message
@errors
<<
error
.
message
# Debug:
# Debug:
Rails
.
logger
.
error
(
error
.
backtrace
.
join
(
"
\n
"
))
if
error
.
backtrace
Rails
.
logger
.
error
(
"Import/Export backtrace:
#{
error
.
backtrace
.
join
(
"
\n
"
)
}
"
)
else
Rails
.
logger
.
error
(
"No backtrace found"
)
end
end
end
private
private
...
...
spec/features/projects/clusters/gcp_spec.rb
View file @
d77181d5
...
@@ -95,7 +95,7 @@ feature 'Gcp Cluster', :js do
...
@@ -95,7 +95,7 @@ feature 'Gcp Cluster', :js do
context
'when user disables the cluster'
do
context
'when user disables the cluster'
do
before
do
before
do
page
.
find
(
:css
,
'.js-
toggle-cluster
'
).
click
page
.
find
(
:css
,
'.js-
cluster-enable-toggle-area .js-project-feature-toggle
'
).
click
page
.
within
(
'#cluster-integration'
)
{
click_button
'Save changes'
}
page
.
within
(
'#cluster-integration'
)
{
click_button
'Save changes'
}
end
end
...
...
spec/features/projects/clusters/user_spec.rb
View file @
d77181d5
...
@@ -62,7 +62,7 @@ feature 'User Cluster', :js do
...
@@ -62,7 +62,7 @@ feature 'User Cluster', :js do
context
'when user disables the cluster'
do
context
'when user disables the cluster'
do
before
do
before
do
page
.
find
(
:css
,
'.js-
toggle-cluster
'
).
click
page
.
find
(
:css
,
'.js-
cluster-enable-toggle-area .js-project-feature-toggle
'
).
click
fill_in
'cluster_name'
,
with:
'dev-cluster'
fill_in
'cluster_name'
,
with:
'dev-cluster'
page
.
within
(
'#cluster-integration'
)
{
click_button
'Save changes'
}
page
.
within
(
'#cluster-integration'
)
{
click_button
'Save changes'
}
end
end
...
...
spec/features/projects/clusters_spec.rb
View file @
d77181d5
...
@@ -37,13 +37,13 @@ feature 'Clusters', :js do
...
@@ -37,13 +37,13 @@ feature 'Clusters', :js do
context
'inline update of cluster'
do
context
'inline update of cluster'
do
it
'user can update cluster'
do
it
'user can update cluster'
do
expect
(
page
).
to
have_selector
(
'.js-
toggle-cluster-list
'
)
expect
(
page
).
to
have_selector
(
'.js-
project-feature-toggle
'
)
end
end
context
'with sucessfull request'
do
context
'with sucessfull request'
do
it
'user sees updated cluster'
do
it
'user sees updated cluster'
do
expect
do
expect
do
page
.
find
(
'.js-
toggle-cluster-list
'
).
click
page
.
find
(
'.js-
project-feature-toggle
'
).
click
wait_for_requests
wait_for_requests
end
.
to
change
{
cluster
.
reload
.
enabled
}
end
.
to
change
{
cluster
.
reload
.
enabled
}
...
@@ -57,7 +57,7 @@ feature 'Clusters', :js do
...
@@ -57,7 +57,7 @@ feature 'Clusters', :js do
expect_any_instance_of
(
Clusters
::
UpdateService
).
to
receive
(
:execute
).
and_call_original
expect_any_instance_of
(
Clusters
::
UpdateService
).
to
receive
(
:execute
).
and_call_original
allow_any_instance_of
(
Clusters
::
Cluster
).
to
receive
(
:valid?
)
{
false
}
allow_any_instance_of
(
Clusters
::
Cluster
).
to
receive
(
:valid?
)
{
false
}
page
.
find
(
'.js-
toggle-cluster-list
'
).
click
page
.
find
(
'.js-
project-feature-toggle
'
).
click
expect
(
page
).
to
have_content
(
'Something went wrong on our end.'
)
expect
(
page
).
to
have_content
(
'Something went wrong on our end.'
)
expect
(
page
).
to
have_selector
(
'.is-checked'
)
expect
(
page
).
to
have_selector
(
'.is-checked'
)
...
...
spec/javascripts/clusters/clusters_bundle_spec.js
View file @
d77181d5
...
@@ -23,16 +23,24 @@ describe('Clusters', () => {
...
@@ -23,16 +23,24 @@ describe('Clusters', () => {
});
});
describe
(
'
toggle
'
,
()
=>
{
describe
(
'
toggle
'
,
()
=>
{
it
(
'
should update the button and the input field on click
'
,
()
=>
{
it
(
'
should update the button and the input field on click
'
,
(
done
)
=>
{
cluster
.
toggleButton
.
click
();
const
toggleButton
=
document
.
querySelector
(
'
.js-cluster-enable-toggle-area .js-project-feature-toggle
'
);
const
toggleInput
=
document
.
querySelector
(
'
.js-cluster-enable-toggle-area .js-project-feature-toggle-input
'
);
expect
(
toggleButton
.
click
();
cluster
.
toggleButton
.
classList
,
).
not
.
toContain
(
'
is-checked
'
);
expect
(
getSetTimeoutPromise
()
cluster
.
toggleInput
.
getAttribute
(
'
value
'
),
.
then
(()
=>
{
).
toEqual
(
'
false
'
);
expect
(
toggleButton
.
classList
,
).
not
.
toContain
(
'
is-checked
'
);
expect
(
toggleInput
.
getAttribute
(
'
value
'
),
).
toEqual
(
'
false
'
);
})
.
then
(
done
)
.
catch
(
done
.
fail
);
});
});
});
});
...
...
spec/javascripts/clusters/clusters_index_spec.js
deleted
100644 → 0
View file @
860c7c4b
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
setClusterTableToggles
from
'
~/clusters/clusters_index
'
;
import
{
setTimeout
}
from
'
core-js/library/web/timers
'
;
describe
(
'
Clusters table
'
,
()
=>
{
preloadFixtures
(
'
clusters/index_cluster.html.raw
'
);
let
mock
;
beforeEach
(()
=>
{
loadFixtures
(
'
clusters/index_cluster.html.raw
'
);
mock
=
new
MockAdapter
(
axios
);
setClusterTableToggles
();
});
describe
(
'
update cluster
'
,
()
=>
{
it
(
'
renders loading state while request is made
'
,
()
=>
{
const
button
=
document
.
querySelector
(
'
.js-toggle-cluster-list
'
);
button
.
click
();
expect
(
button
.
classList
).
toContain
(
'
is-loading
'
);
expect
(
button
.
getAttribute
(
'
disabled
'
)).
toEqual
(
'
true
'
);
});
afterEach
(()
=>
{
mock
.
restore
();
});
it
(
'
shows updated state after sucessfull request
'
,
(
done
)
=>
{
mock
.
onPut
().
reply
(
200
,
{},
{});
const
button
=
document
.
querySelector
(
'
.js-toggle-cluster-list
'
);
button
.
click
();
expect
(
button
.
classList
).
toContain
(
'
is-loading
'
);
setTimeout
(()
=>
{
expect
(
button
.
classList
).
not
.
toContain
(
'
is-loading
'
);
expect
(
button
.
classList
).
not
.
toContain
(
'
is-checked
'
);
done
();
},
0
);
});
it
(
'
shows inital state after failed request
'
,
(
done
)
=>
{
mock
.
onPut
().
reply
(
500
,
{},
{});
const
button
=
document
.
querySelector
(
'
.js-toggle-cluster-list
'
);
button
.
click
();
expect
(
button
.
classList
).
toContain
(
'
is-loading
'
);
setTimeout
(()
=>
{
expect
(
button
.
classList
).
not
.
toContain
(
'
is-loading
'
);
expect
(
button
.
classList
).
toContain
(
'
is-checked
'
);
done
();
},
0
);
});
});
});
spec/javascripts/fixtures/clusters.rb
View file @
d77181d5
...
@@ -31,19 +31,4 @@ describe Projects::ClustersController, '(JavaScript fixtures)', type: :controlle
...
@@ -31,19 +31,4 @@ describe Projects::ClustersController, '(JavaScript fixtures)', type: :controlle
expect
(
response
).
to
be_success
expect
(
response
).
to
be_success
store_frontend_fixture
(
response
,
example
.
description
)
store_frontend_fixture
(
response
,
example
.
description
)
end
end
context
'rendering non-empty state'
do
before
do
cluster
end
it
'clusters/index_cluster.html.raw'
do
|
example
|
get
:index
,
namespace_id:
namespace
,
project_id:
project
expect
(
response
).
to
be_success
store_frontend_fixture
(
response
,
example
.
description
)
end
end
end
end
spec/javascripts/toggle_buttons_spec.js
0 → 100644
View file @
d77181d5
import
setupToggleButtons
from
'
~/toggle_buttons
'
;
import
getSetTimeoutPromise
from
'
./helpers/set_timeout_promise_helper
'
;
function
generateMarkup
(
isChecked
=
true
)
{
return
`
<button type="button" class="
${
isChecked
?
'
is-checked
'
:
''
}
js-project-feature-toggle">
<input type="hidden" class="js-project-feature-toggle-input" value="
${
isChecked
}
" />
</button>
`
;
}
function
setupFixture
(
isChecked
,
clickCallback
)
{
const
wrapper
=
document
.
createElement
(
'
div
'
);
wrapper
.
innerHTML
=
generateMarkup
(
isChecked
);
setupToggleButtons
(
wrapper
,
clickCallback
);
return
wrapper
;
}
describe
(
'
ToggleButtons
'
,
()
=>
{
describe
(
'
when input value is true
'
,
()
=>
{
it
(
'
should initialize as checked
'
,
()
=>
{
const
wrapper
=
setupFixture
(
true
);
expect
(
wrapper
.
querySelector
(
'
.js-project-feature-toggle
'
).
classList
.
contains
(
'
is-checked
'
)).
toEqual
(
true
);
expect
(
wrapper
.
querySelector
(
'
.js-project-feature-toggle-input
'
).
value
).
toEqual
(
'
true
'
);
});
it
(
'
should toggle to unchecked when clicked
'
,
(
done
)
=>
{
const
wrapper
=
setupFixture
(
true
);
const
toggleButton
=
wrapper
.
querySelector
(
'
.js-project-feature-toggle
'
);
toggleButton
.
click
();
getSetTimeoutPromise
()
.
then
(()
=>
{
expect
(
toggleButton
.
classList
.
contains
(
'
is-checked
'
)).
toEqual
(
false
);
expect
(
wrapper
.
querySelector
(
'
.js-project-feature-toggle-input
'
).
value
).
toEqual
(
'
false
'
);
})
.
then
(
done
)
.
catch
(
done
.
fail
);
});
});
describe
(
'
when input value is false
'
,
()
=>
{
it
(
'
should initialize as unchecked
'
,
()
=>
{
const
wrapper
=
setupFixture
(
false
);
expect
(
wrapper
.
querySelector
(
'
.js-project-feature-toggle
'
).
classList
.
contains
(
'
is-checked
'
)).
toEqual
(
false
);
expect
(
wrapper
.
querySelector
(
'
.js-project-feature-toggle-input
'
).
value
).
toEqual
(
'
false
'
);
});
it
(
'
should toggle to checked when clicked
'
,
(
done
)
=>
{
const
wrapper
=
setupFixture
(
false
);
const
toggleButton
=
wrapper
.
querySelector
(
'
.js-project-feature-toggle
'
);
toggleButton
.
click
();
getSetTimeoutPromise
()
.
then
(()
=>
{
expect
(
toggleButton
.
classList
.
contains
(
'
is-checked
'
)).
toEqual
(
true
);
expect
(
wrapper
.
querySelector
(
'
.js-project-feature-toggle-input
'
).
value
).
toEqual
(
'
true
'
);
})
.
then
(
done
)
.
catch
(
done
.
fail
);
});
});
it
(
'
should emit `trigger-change` event
'
,
(
done
)
=>
{
const
changeSpy
=
jasmine
.
createSpy
(
'
changeEventHandler
'
);
const
wrapper
=
setupFixture
(
false
);
const
toggleButton
=
wrapper
.
querySelector
(
'
.js-project-feature-toggle
'
);
const
input
=
wrapper
.
querySelector
(
'
.js-project-feature-toggle-input
'
);
$
(
input
).
on
(
'
trigger-change
'
,
changeSpy
);
toggleButton
.
click
();
getSetTimeoutPromise
()
.
then
(()
=>
{
expect
(
changeSpy
).
toHaveBeenCalled
();
})
.
then
(
done
)
.
catch
(
done
.
fail
);
});
describe
(
'
clickCallback
'
,
()
=>
{
it
(
'
should show loading indicator while waiting
'
,
(
done
)
=>
{
const
isChecked
=
true
;
const
clickCallback
=
(
newValue
,
toggleButton
)
=>
{
const
input
=
toggleButton
.
querySelector
(
'
.js-project-feature-toggle-input
'
);
expect
(
newValue
).
toEqual
(
false
);
// Check for the loading state
expect
(
toggleButton
.
classList
.
contains
(
'
is-checked
'
)).
toEqual
(
false
);
expect
(
toggleButton
.
classList
.
contains
(
'
is-loading
'
)).
toEqual
(
true
);
expect
(
toggleButton
.
disabled
).
toEqual
(
true
);
expect
(
input
.
value
).
toEqual
(
'
true
'
);
// After the callback finishes, check that the loading state is gone
getSetTimeoutPromise
()
.
then
(()
=>
{
expect
(
toggleButton
.
classList
.
contains
(
'
is-checked
'
)).
toEqual
(
false
);
expect
(
toggleButton
.
classList
.
contains
(
'
is-loading
'
)).
toEqual
(
false
);
expect
(
toggleButton
.
disabled
).
toEqual
(
false
);
expect
(
input
.
value
).
toEqual
(
'
false
'
);
})
.
then
(
done
)
.
catch
(
done
.
fail
);
};
const
wrapper
=
setupFixture
(
isChecked
,
clickCallback
);
const
toggleButton
=
wrapper
.
querySelector
(
'
.js-project-feature-toggle
'
);
toggleButton
.
click
();
});
});
});
spec/lib/gitlab/import_export/project.json
View file @
d77181d5
...
@@ -7096,7 +7096,7 @@
...
@@ -7096,7 +7096,7 @@
"project_id"
:
5
,
"project_id"
:
5
,
"created_at"
:
"2016-06-14T15:01:51.232Z"
,
"created_at"
:
"2016-06-14T15:01:51.232Z"
,
"updated_at"
:
"2016-06-14T15:01:51.232Z"
,
"updated_at"
:
"2016-06-14T15:01:51.232Z"
,
"active"
:
fals
e
,
"active"
:
tru
e
,
"properties"
:
{
"properties"
:
{
},
},
...
...
spec/lib/gitlab/import_export/project_tree_saver_spec.rb
View file @
d77181d5
...
@@ -164,6 +164,10 @@ describe Gitlab::ImportExport::ProjectTreeSaver do
...
@@ -164,6 +164,10 @@ describe Gitlab::ImportExport::ProjectTreeSaver do
expect
(
saved_project_json
[
'services'
].
first
[
'type'
]).
to
eq
(
'CustomIssueTrackerService'
)
expect
(
saved_project_json
[
'services'
].
first
[
'type'
]).
to
eq
(
'CustomIssueTrackerService'
)
end
end
it
'saves the properties for a service'
do
expect
(
saved_project_json
[
'services'
].
first
[
'properties'
]).
to
eq
(
'one'
=>
'value'
)
end
it
'has project feature'
do
it
'has project feature'
do
project_feature
=
saved_project_json
[
'project_feature'
]
project_feature
=
saved_project_json
[
'project_feature'
]
expect
(
project_feature
).
not_to
be_empty
expect
(
project_feature
).
not_to
be_empty
...
@@ -279,7 +283,7 @@ describe Gitlab::ImportExport::ProjectTreeSaver do
...
@@ -279,7 +283,7 @@ describe Gitlab::ImportExport::ProjectTreeSaver do
commit_id:
ci_build
.
pipeline
.
sha
)
commit_id:
ci_build
.
pipeline
.
sha
)
create
(
:event
,
:created
,
target:
milestone
,
project:
project
,
author:
user
)
create
(
:event
,
:created
,
target:
milestone
,
project:
project
,
author:
user
)
create
(
:service
,
project:
project
,
type:
'CustomIssueTrackerService'
,
category:
'issue_tracker'
)
create
(
:service
,
project:
project
,
type:
'CustomIssueTrackerService'
,
category:
'issue_tracker'
,
properties:
{
one:
'value'
}
)
create
(
:project_custom_attribute
,
project:
project
)
create
(
:project_custom_attribute
,
project:
project
)
create
(
:project_custom_attribute
,
project:
project
)
create
(
:project_custom_attribute
,
project:
project
)
...
...
spec/requests/api/issues_spec.rb
View file @
d77181d5
...
@@ -1441,7 +1441,7 @@ describe API::Issues, :mailer do
...
@@ -1441,7 +1441,7 @@ describe API::Issues, :mailer do
context
'when source project does not exist'
do
context
'when source project does not exist'
do
it
'returns 404 when trying to move an issue'
do
it
'returns 404 when trying to move an issue'
do
post
api
(
"/projects/123/issues/
#{
issue
.
iid
}
/move"
,
user
),
post
api
(
"/projects/123
45
/issues/
#{
issue
.
iid
}
/move"
,
user
),
to_project_id:
target_project
.
id
to_project_id:
target_project
.
id
expect
(
response
).
to
have_gitlab_http_status
(
404
)
expect
(
response
).
to
have_gitlab_http_status
(
404
)
...
@@ -1452,7 +1452,7 @@ describe API::Issues, :mailer do
...
@@ -1452,7 +1452,7 @@ describe API::Issues, :mailer do
context
'when target project does not exist'
do
context
'when target project does not exist'
do
it
'returns 404 when trying to move an issue'
do
it
'returns 404 when trying to move an issue'
do
post
api
(
"/projects/
#{
project
.
id
}
/issues/
#{
issue
.
iid
}
/move"
,
user
),
post
api
(
"/projects/
#{
project
.
id
}
/issues/
#{
issue
.
iid
}
/move"
,
user
),
to_project_id:
123
to_project_id:
123
45
expect
(
response
).
to
have_gitlab_http_status
(
404
)
expect
(
response
).
to
have_gitlab_http_status
(
404
)
end
end
...
...
spec/workers/repository_import_worker_spec.rb
View file @
d77181d5
...
@@ -49,9 +49,22 @@ describe RepositoryImportWorker do
...
@@ -49,9 +49,22 @@ describe RepositoryImportWorker do
expect
do
expect
do
subject
.
perform
(
project
.
id
)
subject
.
perform
(
project
.
id
)
end
.
to
raise_error
(
Standard
Error
,
error
)
end
.
to
raise_error
(
Runtime
Error
,
error
)
expect
(
project
.
reload
.
import_jid
).
not_to
be_nil
expect
(
project
.
reload
.
import_jid
).
not_to
be_nil
end
end
it
'updates the error on Import/Export'
do
error
=
%q{remote: Not Found fatal: repository 'https://user:pass@test.com/root/repoC.git/' not found }
project
.
update_attributes
(
import_jid:
'123'
,
import_type:
'gitlab_project'
)
expect_any_instance_of
(
Projects
::
ImportService
).
to
receive
(
:execute
).
and_return
({
status: :error
,
message:
error
})
expect
do
subject
.
perform
(
project
.
id
)
end
.
to
raise_error
(
RuntimeError
,
error
)
expect
(
project
.
reload
.
import_error
).
not_to
be_nil
end
end
end
context
'when using an asynchronous importer'
do
context
'when using an asynchronous importer'
do
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment