summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilipa Lacerda <filipa@gitlab.com>2016-12-19 23:15:50 +0000
committerFilipa Lacerda <filipa@gitlab.com>2016-12-19 23:15:50 +0000
commit1b449ba0735531df406b4fbe6e021eae2f8bf770 (patch)
tree3945740c8a5bc7e2d4b77daf96c2f5e1c140e8bf
parent34e317d21ce49c122beb73d2eb695311b75d0b89 (diff)
parentd1d1e7c6d70b23d614e6e6ba482e6fa5fa96f582 (diff)
downloadgitlab-ce-1b449ba0735531df406b4fbe6e021eae2f8bf770.tar.gz
Merge branch 'master' into 19703-direct-link-pipelines
* master: (32 commits) Update CHANGELOG.md for 8.13.10 Update CHANGELOG.md for 8.14.5 Add Wiki import to BB importer Make CI badge hitboxes better match container Move admin broadcast messages spinach feature to rspec Move Admin Appearance spinach feature to rspec Fix MR issue to do with merge user Check if selected object is valid before passing to calback Fix for missing service when importing from EE to CE Fix tests because now we don't convert values Spaces for literal hash updated spec Keep the value type for YAML variables Test if expanded_environment_name could expand var Fix duplicated build token problem and added relevant spec Just implement it in the block Move admin labels spinach test to rspec Bring back "notification-dropdown" class for styling and use "js-notification-dropdown" for JavaScript Fix 500 error for invalid path when visiting blame page Add sentence casing, fix groups page buttons, fix dark gray variable ...
-rw-r--r--CHANGELOG.md22
-rw-r--r--GITLAB_SHELL_VERSION2
-rw-r--r--app/assets/javascripts/gl_dropdown.js8
-rw-r--r--app/assets/javascripts/notifications_dropdown.js2
-rw-r--r--app/assets/stylesheets/framework/mobile.scss2
-rw-r--r--app/assets/stylesheets/framework/variables.scss1
-rw-r--r--app/assets/stylesheets/pages/groups.scss6
-rw-r--r--app/assets/stylesheets/pages/pipelines.scss90
-rw-r--r--app/assets/stylesheets/pages/projects.scss17
-rw-r--r--app/assets/stylesheets/pages/tree.scss2
-rw-r--r--app/controllers/projects/blame_controller.rb3
-rw-r--r--app/models/ci/build.rb2
-rw-r--r--app/models/merge_request.rb2
-rw-r--r--app/views/ci/status/_graph_badge.html.haml9
-rw-r--r--app/views/projects/_home_panel.html.haml16
-rw-r--r--app/views/projects/buttons/_download.html.haml2
-rw-r--r--app/views/projects/buttons/_dropdown.html.haml2
-rw-r--r--app/views/projects/buttons/_koding.html.haml10
-rw-r--r--app/views/projects/show.html.haml17
-rw-r--r--app/views/projects/stage/_graph.html.haml11
-rw-r--r--app/views/projects/stage/_in_stage_group.html.haml4
-rw-r--r--app/views/shared/members/_access_request_buttons.html.haml29
-rw-r--r--app/views/shared/notifications/_button.html.haml2
-rw-r--r--changelogs/unreleased/23305-leave-project-and-leave-group-should-be-buttons.yml5
-rw-r--r--changelogs/unreleased/25171-fix-mr-features-settings-hidden-when-builds-are-disabled.yml4
-rw-r--r--changelogs/unreleased/fix-blame-500.yml4
-rw-r--r--changelogs/unreleased/fix-import-export-build-token.yml4
-rw-r--r--changelogs/unreleased/fix-import-export-ee-services.yml4
-rw-r--r--changelogs/unreleased/fix-import-export-mr-error.yml4
-rw-r--r--changelogs/unreleased/fix-milestone-summary.yml4
-rw-r--r--changelogs/unreleased/fix-yaml-variables.yml4
-rw-r--r--changelogs/unreleased/group-members-in-project-members-view.yml4
-rw-r--r--changelogs/unreleased/issue_24020.yml4
-rw-r--r--changelogs/unreleased/issue_25030.yml4
-rw-r--r--changelogs/unreleased/ldap_maint_task.yml4
-rw-r--r--changelogs/unreleased/leave-project-btn.yml4
-rw-r--r--changelogs/unreleased/pipeline-build-hitbox.yml4
-rw-r--r--changelogs/unreleased/timeago-perf-fix.yml4
-rw-r--r--changelogs/unreleased/unescape-relative-path.yml4
-rw-r--r--doc/administration/raketasks/check.md23
-rw-r--r--doc/administration/raketasks/ldap.md120
-rw-r--r--doc/integration/bitbucket.md3
-rw-r--r--doc/integration/img/bitbucket_oauth_settings_page.pngbin5607 -> 28719 bytes
-rw-r--r--doc/raketasks/README.md3
-rw-r--r--doc/update/8.14-to-8.15.md2
-rw-r--r--doc/workflow/importing/import_projects_from_bitbucket.md1
-rw-r--r--features/admin/appearance.feature37
-rw-r--r--features/admin/broadcast_messages.feature33
-rw-r--r--features/admin/labels.feature38
-rw-r--r--features/steps/admin/appearance.rb72
-rw-r--r--features/steps/admin/broadcast_messages.rb66
-rw-r--r--features/steps/admin/labels.rb117
-rw-r--r--features/steps/shared/paths.rb4
-rw-r--r--lib/bitbucket/representation/repo.rb4
-rw-r--r--lib/ci/gitlab_ci_yaml_processor.rb2
-rw-r--r--lib/gitlab/bitbucket_import/importer.rb13
-rw-r--r--lib/gitlab/bitbucket_import/project_creator.rb9
-rw-r--r--lib/gitlab/import_export/project_tree_restorer.rb2
-rw-r--r--lib/gitlab/import_export/relation_factory.rb11
-rw-r--r--lib/gitlab/serialize/ci/variables.rb27
-rw-r--r--lib/tasks/gitlab/ldap.rake40
-rw-r--r--spec/controllers/projects/blame_controller_spec.rb5
-rw-r--r--spec/factories/ci/builds.rb2
-rw-r--r--spec/features/admin/admin_appearance_spec.rb76
-rw-r--r--spec/features/admin/admin_broadcast_messages_spec.rb51
-rw-r--r--spec/features/admin/admin_labels_spec.rb99
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb33
-rw-r--r--spec/javascripts/fixtures/pipeline_graph.html.haml9
-rw-r--r--spec/lib/bitbucket/representation/repo_spec.rb49
-rw-r--r--spec/lib/ci/gitlab_ci_yaml_processor_spec.rb24
-rw-r--r--spec/lib/gitlab/bitbucket_import/importer_spec.rb12
-rw-r--r--spec/lib/gitlab/bitbucket_import/project_creator_spec.rb3
-rw-r--r--spec/lib/gitlab/import_export/project.json28
-rw-r--r--spec/lib/gitlab/import_export/project_tree_restorer_spec.rb8
-rw-r--r--spec/lib/gitlab/serialize/ci/variables_spec.rb18
-rw-r--r--spec/models/build_spec.rb20
-rw-r--r--spec/tasks/gitlab/ldap_rake_spec.rb13
77 files changed, 835 insertions, 568 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fb13db4dd1c..786b0128aac 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,21 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
+## 8.14.5 (2016-12-14)
+
+- Moved Leave Project and Leave Group buttons to access_request_buttons from the settings dropdown. !7600
+- fix display hook error message. !7775 (basyura)
+- Remove wrong '.builds-feature' class from the MR settings fieldset. !7930
+- Avoid escaping relative links in Markdown twice. !7940 (winniehell)
+- API: Memoize the current_user so that sudo can work properly. !8017
+- Displays milestone remaining days only when it's present.
+- Allow branch names with dots on API endpoint.
+- Issue#visible_to_user moved to IssuesFinder to prevent accidental use.
+- Shows group members in project members list.
+- Encode input when migrating ProcessCommitWorker jobs to prevent migration errors.
+- Fixed timeago re-rendering every timeago.
+- Fix missing Note access checks by moving Note#search to updated NoteFinder.
+
## 8.14.4 (2016-12-08)
- Fix diff view permalink highlighting. !7090
@@ -264,6 +279,13 @@ entry.
- Fix "Without projects" filter. !6611 (Ben Bodenmiller)
- Fix 404 when visit /projects page
+## 8.13.10 (2016-12-14)
+
+- API: Memoize the current_user so that sudo can work properly. !8017
+- Filter `authentication_token`, `incoming_email_token` and `runners_token` parameters.
+- Issue#visible_to_user moved to IssuesFinder to prevent accidental use.
+- Fix missing Note access checks by moving Note#search to updated NoteFinder.
+
## 8.13.9 (2016-12-08)
- Reenables /user API request to return private-token if user is admin and request is made with sudo. !7615
diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION
index ee74734aa22..627a3f43a64 100644
--- a/GITLAB_SHELL_VERSION
+++ b/GITLAB_SHELL_VERSION
@@ -1 +1 @@
-4.1.0
+4.1.1
diff --git a/app/assets/javascripts/gl_dropdown.js b/app/assets/javascripts/gl_dropdown.js
index 57dabfe05e4..bb516b3d2df 100644
--- a/app/assets/javascripts/gl_dropdown.js
+++ b/app/assets/javascripts/gl_dropdown.js
@@ -343,16 +343,18 @@
selector = ".dropdown-page-one .dropdown-content a";
}
this.dropdown.on("click", selector, function(e) {
- var $el, selected;
+ var $el, selected, selectedObj, isMarking;
$el = $(this);
selected = self.rowClicked($el);
+ selectedObj = selected ? selected[0] : null;
+ isMarking = selected ? selected[1] : null;
if (self.options.clicked) {
- self.options.clicked(selected[0], $el, e, selected[1]);
+ self.options.clicked(selectedObj, $el, e, isMarking);
}
// Update label right after all modifications in dropdown has been done
if (self.options.toggleLabel) {
- self.updateLabel(selected[0], $el, self);
+ self.updateLabel(selectedObj, $el, self);
}
$el.trigger('blur');
diff --git a/app/assets/javascripts/notifications_dropdown.js b/app/assets/javascripts/notifications_dropdown.js
index 324b68a7efc..5d0d594073d 100644
--- a/app/assets/javascripts/notifications_dropdown.js
+++ b/app/assets/javascripts/notifications_dropdown.js
@@ -19,7 +19,7 @@
});
$(document).off('ajax:success', '.notification-form').on('ajax:success', '.notification-form', function(e, data) {
if (data.saved) {
- return $(e.currentTarget).closest('.notification-dropdown').replaceWith(data.html);
+ return $(e.currentTarget).closest('.js-notification-dropdown').replaceWith(data.html);
} else {
return new Flash('Failed to save new settings', 'alert');
}
diff --git a/app/assets/stylesheets/framework/mobile.scss b/app/assets/stylesheets/framework/mobile.scss
index abfdd7a759d..7eb9962ba33 100644
--- a/app/assets/stylesheets/framework/mobile.scss
+++ b/app/assets/stylesheets/framework/mobile.scss
@@ -54,7 +54,7 @@
}
// Display Star and Fork buttons without counters on mobile.
- .project-action-buttons {
+ .project-repo-buttons {
display: block;
.count-buttons .btn {
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index d0c27d64239..460c5d995be 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -24,6 +24,7 @@ $gray-lightest: #fdfdfd;
$gray-light: #fafafa;
$gray-lighter: #f9f9f9;
$gray-normal: #f5f5f5;
+$gray-dark: darken($gray-light, $darken-dark-factor);
$gray-darker: #eee;
$gray-darkest: #c4c4c4;
diff --git a/app/assets/stylesheets/pages/groups.scss b/app/assets/stylesheets/pages/groups.scss
index a9af7af59e2..16bff5f1e03 100644
--- a/app/assets/stylesheets/pages/groups.scss
+++ b/app/assets/stylesheets/pages/groups.scss
@@ -27,12 +27,6 @@
}
}
-.group-buttons {
- .notification-dropdown {
- display: inline-block;
- }
-}
-
.groups-header {
@media (min-width: $screen-sm-min) {
.nav-links {
diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss
index ae7b40a9416..bb320da619f 100644
--- a/app/assets/stylesheets/pages/pipelines.scss
+++ b/app/assets/stylesheets/pages/pipelines.scss
@@ -429,7 +429,7 @@
width: 21px;
height: 25px;
position: absolute;
- top: -32px;
+ top: -31px;
border-top: 2px solid $border-color;
}
@@ -457,15 +457,13 @@
}
.build {
- border: 1px solid $border-color;
- border-radius: 30px;
- background-color: $white-light;
position: relative;
- padding: 8px 4px 9px 10px;
width: 186px;
margin-bottom: 10px;
white-space: normal;
+ color: $gl-text-color-light;
+<<<<<<< HEAD
.dropdown-menu-toggle {
background-color: transparent;
@@ -491,20 +489,27 @@
&:hover {
background-color: $stage-hover-bg;
border: 1px solid $stage-hover-border;
+=======
+ > .build-content {
+ display: inline-block;
+ padding: 8px 10px 9px;
+ width: 100%;
+ border: 1px solid $border-color;
+ border-radius: 30px;
+ background-color: $white-light;
+>>>>>>> master
- a,
- .dropdown-counter-badge,
- .dropdown-menu-toggle {
+ &:hover {
+ background-color: $stage-hover-bg;
+ border: 1px solid $stage-hover-border;
color: $gl-text-color;
}
+ }
- .grouped-pipeline-dropdown a {
- color: $gl-text-color-light;
-
- &:hover {
- color: $gl-text-color;
- }
- }
+ > .ci-action-icon-container {
+ position: absolute;
+ right: 4px;
+ top: 5px;
}
.ci-status-icon {
@@ -601,10 +606,19 @@
// Position in the pipeline graph
.grouped-pipeline-dropdown {
+<<<<<<< HEAD
right: -206px;
top: -11px;
}
}
+=======
+ padding: 0;
+ width: 191px;
+ left: auto;
+ right: -195px;
+ top: -4px;
+ box-shadow: 0 1px 5px $black-transparent;
+>>>>>>> master
.dropdown-counter-badge {
float: right;
@@ -630,10 +644,53 @@
}
}
+<<<<<<< HEAD
ul {
max-height: 245px;
overflow: auto;
margin: 5px 0;
+=======
+ .dropdown-build {
+ color: $gl-text-color-light;
+
+ .build-content {
+ width: 100%;
+ }
+
+ .ci-action-icon-container {
+ font-size: 11px;
+ position: absolute;
+ right: 4px;
+
+ i {
+ width: 25px;
+ height: 25px;
+ font-size: 11px;
+ margin-top: 0;
+
+ &::before {
+ top: 1px;
+ left: 1px;
+ }
+ }
+ }
+
+ &:hover {
+ background-color: $stage-hover-bg;
+ border-radius: 3px;
+ color: $gl-text-color;
+ }
+
+ .stage {
+ max-width: 100px;
+ width: 100px;
+ }
+
+ .ci-status-icon svg {
+ height: 18px;
+ width: 18px;
+ }
+>>>>>>> master
li {
padding-top: 2px;
@@ -659,9 +716,6 @@
// Action Icons
.ci-action-icon-container .ci-action-icon-wrapper {
- float: right;
- margin-top: -4px;
-
i {
color: $border-color;
border-radius: 100%;
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index 3b1b375133d..a443b6a37b3 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -145,8 +145,6 @@
.project-repo-buttons,
.group-buttons {
- margin-top: 15px;
-
.btn {
@include btn-gray;
padding: 3px 10px;
@@ -175,11 +173,9 @@
}
}
- .download-button,
- .dropdown-toggle,
- .notification-dropdown,
- .project-dropdown {
- margin-left: 10px;
+ .project-action-button {
+ margin: 15px 5px 0;
+ vertical-align: top;
}
.notification-dropdown .dropdown-menu {
@@ -195,13 +191,15 @@
.count-buttons {
display: inline-block;
vertical-align: top;
+ margin-top: 15px;
}
.project-clone-holder {
display: inline-block;
+ margin: 15px 5px 0 0;
input {
- height: 29px;
+ height: 28px;
}
}
@@ -255,7 +253,7 @@
line-height: 13px;
padding: $gl-vert-padding $gl-padding;
letter-spacing: .4px;
- padding: 7px 14px;
+ padding: 6px 14px;
text-align: center;
vertical-align: middle;
touch-action: manipulation;
@@ -492,6 +490,7 @@ a.deploy-project-label {
.project-stats {
font-size: 0;
+ text-align: center;
border-bottom: 1px solid $border-color;
.nav {
diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss
index c0341db7289..05c0a4c29f4 100644
--- a/app/assets/stylesheets/pages/tree.scss
+++ b/app/assets/stylesheets/pages/tree.scss
@@ -172,7 +172,7 @@
position: relative;
z-index: 2;
- .download-button {
+ .project-action-button {
margin-left: $btn-side-margin;
}
}
diff --git a/app/controllers/projects/blame_controller.rb b/app/controllers/projects/blame_controller.rb
index f576d0be1fc..863a766a255 100644
--- a/app/controllers/projects/blame_controller.rb
+++ b/app/controllers/projects/blame_controller.rb
@@ -8,6 +8,9 @@ class Projects::BlameController < Projects::ApplicationController
def show
@blob = @repository.blob_at(@commit.id, @path)
+
+ return render_404 unless @blob
+
@blame_groups = Gitlab::Blame.new(@blob, @commit).groups
end
end
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 591aba6bdc9..cb76cdf5981 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -18,7 +18,7 @@ module Ci
end
serialize :options
- serialize :yaml_variables
+ serialize :yaml_variables, Gitlab::Serialize::Ci::Variables
validates :coverage, numericality: true, allow_blank: true
validates_presence_of :ref
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index b7c775777c7..5ce20cc43d6 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -97,7 +97,7 @@ class MergeRequest < ActiveRecord::Base
validates :source_branch, presence: true
validates :target_project, presence: true
validates :target_branch, presence: true
- validates :merge_user, presence: true, if: :merge_when_build_succeeds?
+ validates :merge_user, presence: true, if: :merge_when_build_succeeds?, unless: :importing?
validate :validate_branches, unless: [:allow_broken, :importing?, :closed_without_fork?]
validate :validate_fork, unless: :closed_without_fork?
diff --git a/app/views/ci/status/_graph_badge.html.haml b/app/views/ci/status/_graph_badge.html.haml
index 9f3a9c0c6b2..52b4d77d074 100644
--- a/app/views/ci/status/_graph_badge.html.haml
+++ b/app/views/ci/status/_graph_badge.html.haml
@@ -5,12 +5,13 @@
- klass = "ci-status-icon ci-status-icon-#{status.group}"
- if status.has_details?
- = link_to status.details_path, data: { toggle: 'tooltip', title: "#{subject.name} - #{status.label}" } do
+ = link_to status.details_path, class: 'build-content' do
%span{ class: klass }= custom_icon(status.icon)
- .ci-status-text= subject.name
+ .ci-status-text{ 'data-toggle' => 'tooltip', 'data-title' => "#{subject.name} - #{status.label}" }= subject.name
- else
- %span{ class: klass }= custom_icon(status.icon)
- .ci-status-text= subject.name
+ .build-content
+ %span{ class: klass }= custom_icon(status.icon)
+ .ci-status-text{ 'data-toggle' => 'tooltip', 'data-title' => "#{subject.name} - #{status.label}" }= subject.name
- if status.has_action?
= link_to status.action_path, method: status.action_method,
diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml
index 5a04c3318cf..0d1f2b70018 100644
--- a/app/views/projects/_home_panel.html.haml
+++ b/app/views/projects/_home_panel.html.haml
@@ -18,11 +18,19 @@
= link_to project_path(forked_from_project) do
= forked_from_project.namespace.try(:name)
- .project-repo-buttons.project-action-buttons
+ .project-repo-buttons
.count-buttons
= render 'projects/buttons/star'
= render 'projects/buttons/fork'
- - if @project.feature_available?(:repository, current_user)
- .project-clone-holder
- = render "shared/clone_panel"
+ %span.hidden-xs
+ - if @project.feature_available?(:repository, current_user)
+ .project-clone-holder
+ = render "shared/clone_panel"
+
+ - if current_user && can?(current_user, :download_code, @project)
+ = render 'projects/buttons/download', project: @project, ref: @ref
+ = render 'projects/buttons/dropdown'
+ = render 'shared/notifications/button', notification_setting: @notification_setting
+ = render 'projects/buttons/koding'
+ = render 'shared/members/access_request_buttons', source: @project
diff --git a/app/views/projects/buttons/_download.html.haml b/app/views/projects/buttons/_download.html.haml
index 40bfa01a45a..324a7f8cd3f 100644
--- a/app/views/projects/buttons/_download.html.haml
+++ b/app/views/projects/buttons/_download.html.haml
@@ -1,5 +1,5 @@
- if !project.empty_repo? && can?(current_user, :download_code, project)
- .dropdown.inline.download-button
+ .project-action-button.dropdown.inline
%button.btn{ 'data-toggle' => 'dropdown' }
= icon('download')
= icon("caret-down")
diff --git a/app/views/projects/buttons/_dropdown.html.haml b/app/views/projects/buttons/_dropdown.html.haml
index d3ccebbe290..f5659be25f0 100644
--- a/app/views/projects/buttons/_dropdown.html.haml
+++ b/app/views/projects/buttons/_dropdown.html.haml
@@ -1,5 +1,5 @@
- if current_user
- .dropdown.inline
+ .project-action-button.dropdown.inline
%a.btn.dropdown-toggle{href: '#', "data-toggle" => "dropdown"}
= icon('plus')
= icon("caret-down")
diff --git a/app/views/projects/buttons/_koding.html.haml b/app/views/projects/buttons/_koding.html.haml
index fdc80d44253..5d9a776da89 100644
--- a/app/views/projects/buttons/_koding.html.haml
+++ b/app/views/projects/buttons/_koding.html.haml
@@ -1,7 +1,3 @@
-- if koding_enabled? && current_user && can_push_branch?(@project, @project.default_branch)
- - if @repository.koding_yml
- = link_to koding_project_url(@project), class: 'btn', target: '_blank' do
- Run in IDE (Koding)
- - else
- = link_to add_koding_stack_path(@project), class: 'btn' do
- Set Up Koding
+- if koding_enabled? && current_user && @repository.koding_yml && can_push_branch?(@project, @project.default_branch)
+ = link_to koding_project_url(@project), class: 'btn project-action-button inline', target: '_blank' do
+ Run in IDE (Koding)
diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml
index c50093cf47c..8a214e1de58 100644
--- a/app/views/projects/show.html.haml
+++ b/app/views/projects/show.html.haml
@@ -64,20 +64,11 @@
- unless @repository.gitlab_ci_yml
%li.missing
= link_to add_special_file_path(@project, file_name: '.gitlab-ci.yml') do
- Set Up CI
-
- %li.project-repo-buttons.right
- .project-right-buttons
- - if current_user
- = render 'shared/members/access_request_buttons', source: @project
- = render "projects/buttons/koding"
-
- .btn-group.project-repo-btn-group
- = render 'projects/buttons/download', project: @project, ref: @ref
- = render 'projects/buttons/dropdown'
+ Set up CI
+ - if koding_enabled? && @repository.koding_yml.blank?
+ %li.missing
+ = link_to 'Set up Koding', add_koding_stack_path(@project)
- .pull-right
- = render 'shared/notifications/button', notification_setting: @notification_setting
- if @repository.commit
.project-last-commit{ class: container_class }
= render 'projects/last_commit', commit: @repository.commit, ref: current_ref, project: @project
diff --git a/app/views/projects/stage/_graph.html.haml b/app/views/projects/stage/_graph.html.haml
index b70b574e687..6919b210a00 100644
--- a/app/views/projects/stage/_graph.html.haml
+++ b/app/views/projects/stage/_graph.html.haml
@@ -10,12 +10,11 @@
- status_groups.each do |group_name, grouped_statuses|
- if grouped_statuses.one?
- status = grouped_statuses.first
- %li.build
+ %li.build{ 'id' => "ci-badge-#{group_name}" }
.curve
- .build-content
- = render 'ci/status/graph_badge', subject: status
+ = render 'ci/status/graph_badge', subject: status
- else
- %li.build
+ %li.build{ 'id' => "ci-badge-#{group_name}" }
.curve
- .dropdown.inline.build-content
- = render 'projects/stage/in_stage_group', name: group_name, subject: grouped_statuses
+ = render 'projects/stage/in_stage_group', name: group_name, subject: grouped_statuses
+
diff --git a/app/views/projects/stage/_in_stage_group.html.haml b/app/views/projects/stage/_in_stage_group.html.haml
index b03837d1211..b15f7eaeab2 100644
--- a/app/views/projects/stage/_in_stage_group.html.haml
+++ b/app/views/projects/stage/_in_stage_group.html.haml
@@ -1,8 +1,8 @@
- group_status = CommitStatus.where(id: subject).status
-%button.dropdown-menu-toggle.has-tooltip{ type: 'button', data: { toggle: 'dropdown', title: "#{name} - #{group_status}" } }
+%button.dropdown-menu-toggle.build-content.has-tooltip{ type: 'button', data: { toggle: 'dropdown'} }
%span{class: "ci-status-icon ci-status-icon-#{group_status}"}
= ci_icon_for_status(group_status)
- %span.ci-status-text
+ %span.ci-status-text{ 'data-toggle' => 'tooltip', 'data-title' => "#{name} - #{group_status}" }
= name
%span.dropdown-counter-badge= subject.size
.dropdown-menu.grouped-pipeline-dropdown
diff --git a/app/views/shared/members/_access_request_buttons.html.haml b/app/views/shared/members/_access_request_buttons.html.haml
index e166dfab710..fb795ad1c72 100644
--- a/app/views/shared/members/_access_request_buttons.html.haml
+++ b/app/views/shared/members/_access_request_buttons.html.haml
@@ -1,16 +1,17 @@
- model_name = source.model_name.to_s.downcase
-- if can?(current_user, :"destroy_#{model_name}_member", source.members.find_by(user_id: current_user.id))
- = link_to "Leave #{model_name}", polymorphic_path([:leave, source, :members]),
- method: :delete,
- data: { confirm: leave_confirmation_message(source) },
- class: 'btn'
-- elsif requester = source.requesters.find_by(user_id: current_user.id)
- = link_to 'Withdraw Access Request', polymorphic_path([:leave, source, :members]),
- method: :delete,
- data: { confirm: remove_member_message(requester) },
- class: 'btn'
-- elsif source.request_access_enabled && can?(current_user, :request_access, source)
- = link_to 'Request Access', polymorphic_path([:request_access, source, :members]),
- method: :post,
- class: 'btn'
+.project-action-button.inline
+ - if can?(current_user, :"destroy_#{model_name}_member", source.members.find_by(user_id: current_user.id))
+ = link_to "Leave #{model_name}", polymorphic_path([:leave, source, :members]),
+ method: :delete,
+ data: { confirm: leave_confirmation_message(source) },
+ class: 'btn'
+ - elsif requester = source.requesters.find_by(user_id: current_user.id)
+ = link_to 'Withdraw Access Request', polymorphic_path([:leave, source, :members]),
+ method: :delete,
+ data: { confirm: remove_member_message(requester) },
+ class: 'btn'
+ - elsif source.request_access_enabled && can?(current_user, :request_access, source)
+ = link_to 'Request Access', polymorphic_path([:request_access, source, :members]),
+ method: :post,
+ class: 'btn'
diff --git a/app/views/shared/notifications/_button.html.haml b/app/views/shared/notifications/_button.html.haml
index fbad0d05de3..1d072c16b32 100644
--- a/app/views/shared/notifications/_button.html.haml
+++ b/app/views/shared/notifications/_button.html.haml
@@ -1,5 +1,5 @@
- if notification_setting
- .dropdown.notification-dropdown
+ .js-notification-dropdown.notification-dropdown.project-action-button.dropdown.inline
= form_for notification_setting, remote: true, html: { class: "inline notification-form" } do |f|
= hidden_setting_source_input(notification_setting)
= f.hidden_field :level, class: "notification_setting_level"
diff --git a/changelogs/unreleased/23305-leave-project-and-leave-group-should-be-buttons.yml b/changelogs/unreleased/23305-leave-project-and-leave-group-should-be-buttons.yml
deleted file mode 100644
index 99dbe4a32a0..00000000000
--- a/changelogs/unreleased/23305-leave-project-and-leave-group-should-be-buttons.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Moved Leave Project and Leave Group buttons to access_request_buttons from
- the settings dropdown
-merge_request: 7600
-author:
diff --git a/changelogs/unreleased/25171-fix-mr-features-settings-hidden-when-builds-are-disabled.yml b/changelogs/unreleased/25171-fix-mr-features-settings-hidden-when-builds-are-disabled.yml
deleted file mode 100644
index a7576e2cbdb..00000000000
--- a/changelogs/unreleased/25171-fix-mr-features-settings-hidden-when-builds-are-disabled.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Remove wrong '.builds-feature' class from the MR settings fieldset
-merge_request: 7930
-author:
diff --git a/changelogs/unreleased/fix-blame-500.yml b/changelogs/unreleased/fix-blame-500.yml
new file mode 100644
index 00000000000..379d81aaa44
--- /dev/null
+++ b/changelogs/unreleased/fix-blame-500.yml
@@ -0,0 +1,4 @@
+---
+title: Fix blame 500 error on invalid path.
+merge_request: 25761
+author: Jeff Stubler
diff --git a/changelogs/unreleased/fix-import-export-build-token.yml b/changelogs/unreleased/fix-import-export-build-token.yml
new file mode 100644
index 00000000000..622487e6829
--- /dev/null
+++ b/changelogs/unreleased/fix-import-export-build-token.yml
@@ -0,0 +1,4 @@
+---
+title: Fix Import/Export duplicated builds error
+merge_request:
+author:
diff --git a/changelogs/unreleased/fix-import-export-ee-services.yml b/changelogs/unreleased/fix-import-export-ee-services.yml
new file mode 100644
index 00000000000..c0aacbc96f8
--- /dev/null
+++ b/changelogs/unreleased/fix-import-export-ee-services.yml
@@ -0,0 +1,4 @@
+---
+title: Fix missing service error importing from EE to CE
+merge_request: 8144
+author:
diff --git a/changelogs/unreleased/fix-import-export-mr-error.yml b/changelogs/unreleased/fix-import-export-mr-error.yml
new file mode 100644
index 00000000000..e1137bca131
--- /dev/null
+++ b/changelogs/unreleased/fix-import-export-mr-error.yml
@@ -0,0 +1,4 @@
+---
+title: Fix Import/Export merge requests error while importing
+merge_request:
+author:
diff --git a/changelogs/unreleased/fix-milestone-summary.yml b/changelogs/unreleased/fix-milestone-summary.yml
deleted file mode 100644
index 3045a15054c..00000000000
--- a/changelogs/unreleased/fix-milestone-summary.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Displays milestone remaining days only when it's present
-merge_request:
-author:
diff --git a/changelogs/unreleased/fix-yaml-variables.yml b/changelogs/unreleased/fix-yaml-variables.yml
new file mode 100644
index 00000000000..3abff1e3b08
--- /dev/null
+++ b/changelogs/unreleased/fix-yaml-variables.yml
@@ -0,0 +1,4 @@
+---
+title: Convert CI YAML variables keys into strings
+merge_request: 8088
+author:
diff --git a/changelogs/unreleased/group-members-in-project-members-view.yml b/changelogs/unreleased/group-members-in-project-members-view.yml
deleted file mode 100644
index 415e2b6b1e2..00000000000
--- a/changelogs/unreleased/group-members-in-project-members-view.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Shows group members in project members list
-merge_request:
-author:
diff --git a/changelogs/unreleased/issue_24020.yml b/changelogs/unreleased/issue_24020.yml
deleted file mode 100644
index 87310b75296..00000000000
--- a/changelogs/unreleased/issue_24020.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: "fix display hook error message"
-merge_request: 7775
-author: basyura
diff --git a/changelogs/unreleased/issue_25030.yml b/changelogs/unreleased/issue_25030.yml
deleted file mode 100644
index e18b8d6a79b..00000000000
--- a/changelogs/unreleased/issue_25030.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Allow branch names with dots on API endpoint
-merge_request:
-author:
diff --git a/changelogs/unreleased/ldap_maint_task.yml b/changelogs/unreleased/ldap_maint_task.yml
new file mode 100644
index 00000000000..8acffba0ce5
--- /dev/null
+++ b/changelogs/unreleased/ldap_maint_task.yml
@@ -0,0 +1,4 @@
+---
+title: Add LDAP Rake task to rename a provider
+merge_request: 2181
+author:
diff --git a/changelogs/unreleased/leave-project-btn.yml b/changelogs/unreleased/leave-project-btn.yml
new file mode 100644
index 00000000000..2aa553d7b97
--- /dev/null
+++ b/changelogs/unreleased/leave-project-btn.yml
@@ -0,0 +1,4 @@
+---
+title: Move all action buttons to project header
+merge_request:
+author:
diff --git a/changelogs/unreleased/pipeline-build-hitbox.yml b/changelogs/unreleased/pipeline-build-hitbox.yml
new file mode 100644
index 00000000000..051b538a9a3
--- /dev/null
+++ b/changelogs/unreleased/pipeline-build-hitbox.yml
@@ -0,0 +1,4 @@
+---
+title: Make CI badge hitboxes match parent
+merge_request:
+author:
diff --git a/changelogs/unreleased/timeago-perf-fix.yml b/changelogs/unreleased/timeago-perf-fix.yml
deleted file mode 100644
index 265e7db29a9..00000000000
--- a/changelogs/unreleased/timeago-perf-fix.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fixed timeago re-rendering every timeago
-merge_request:
-author:
diff --git a/changelogs/unreleased/unescape-relative-path.yml b/changelogs/unreleased/unescape-relative-path.yml
deleted file mode 100644
index 755b0379a16..00000000000
--- a/changelogs/unreleased/unescape-relative-path.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Avoid escaping relative links in Markdown twice
-merge_request: 7940
-author: winniehell
diff --git a/doc/administration/raketasks/check.md b/doc/administration/raketasks/check.md
index d1d2fed4861..c8b5434c068 100644
--- a/doc/administration/raketasks/check.md
+++ b/doc/administration/raketasks/check.md
@@ -74,24 +74,5 @@ Example output:
The LDAP check Rake task will test the bind_dn and password credentials
(if configured) and will list a sample of LDAP users. This task is also
-executed as part of the `gitlab:check` task, but can run independently
-using the command below.
-
-**Omnibus Installation**
-
-```
-sudo gitlab-rake gitlab:ldap:check
-```
-
-**Source Installation**
-
-```bash
-sudo -u git -H bundle exec rake gitlab:ldap:check RAILS_ENV=production
-```
-
-By default, the task will return a sample of 100 LDAP users. Change this
-limit by passing a number to the check task:
-
-```bash
-rake gitlab:ldap:check[50]
-```
+executed as part of the `gitlab:check` task, but can run independently.
+See [LDAP Rake Tasks - LDAP Check](ldap.md#check) for details.
diff --git a/doc/administration/raketasks/ldap.md b/doc/administration/raketasks/ldap.md
new file mode 100644
index 00000000000..91fc0133d56
--- /dev/null
+++ b/doc/administration/raketasks/ldap.md
@@ -0,0 +1,120 @@
+# LDAP Rake Tasks
+
+## Check
+
+The LDAP check Rake task will test the `bind_dn` and `password` credentials
+(if configured) and will list a sample of LDAP users. This task is also
+executed as part of the `gitlab:check` task, but can run independently
+using the command below.
+
+**Omnibus Installation**
+
+```
+sudo gitlab-rake gitlab:ldap:check
+```
+
+**Source Installation**
+
+```bash
+sudo -u git -H bundle exec rake gitlab:ldap:check RAILS_ENV=production
+```
+
+------
+
+By default, the task will return a sample of 100 LDAP users. Change this
+limit by passing a number to the check task:
+
+```bash
+rake gitlab:ldap:check[50]
+```
+
+## Rename a provider
+
+If you change the LDAP server ID in `gitlab.yml` or `gitlab.rb` you will need
+to update all user identities or users will be unable to sign in. Input the
+old and new provider and this task will update all matching identities in the
+database.
+
+`old_provider` and `new_provider` are derived from the prefix `ldap` plus the
+LDAP server ID from the configuration file. For example, in `gitlab.yml` or
+`gitlab.rb` you may see LDAP configuration like this:
+
+```yaml
+main:
+ label: 'LDAP'
+ host: '_your_ldap_server'
+ port: 389
+ uid: 'sAMAccountName'
+ ...
+```
+
+`main` is the LDAP server ID. Together, the unique provider is `ldapmain`.
+
+> **Warning**: If you input an incorrect new provider users will be unable
+to sign in. If this happens, run the task again with the incorrect provider
+as the `old_provider` and the correct provider as the `new_provider`.
+
+**Omnibus Installation**
+
+```bash
+sudo gitlab-rake gitlab:ldap:rename_provider[old_provider,new_provider]
+```
+
+**Source Installation**
+
+```bash
+bundle exec rake gitlab:ldap:rename_provider[old_provider,new_provider] RAILS_ENV=production
+```
+
+### Example
+
+Consider beginning with the default server ID `main` (full provider `ldapmain`).
+If we change `main` to `mycompany`, the `new_provider` is `ldapmycompany`.
+To rename all user identities run the following command:
+
+```bash
+sudo gitlab-rake gitlab:ldap:rename_provider[ldapmain,ldapmycompany]
+```
+
+Example output:
+
+```
+100 users with provider 'ldapmain' will be updated to 'ldapmycompany'.
+If the new provider is incorrect, users will be unable to sign in.
+Do you want to continue (yes/no)? yes
+
+User identities were successfully updated
+```
+
+### Other options
+
+If you do not specify an `old_provider` and `new_provider` you will be prompted
+for them:
+
+**Omnibus Installation**
+
+```bash
+sudo gitlab-rake gitlab:ldap:rename_provider
+```
+
+**Source Installation**
+
+```bash
+bundle exec rake gitlab:ldap:rename_provider RAILS_ENV=production
+```
+
+**Example output:**
+
+```
+What is the old provider? Ex. 'ldapmain': ldapmain
+What is the new provider? Ex. 'ldapcustom': ldapmycompany
+```
+
+------
+
+This tasks also accepts the `force` environment variable which will skip the
+confirmation dialog:
+
+```bash
+sudo gitlab-rake gitlab:ldap:rename_provider[old_provider,new_provider] force=yes
+```
diff --git a/doc/integration/bitbucket.md b/doc/integration/bitbucket.md
index 5df6e103f42..1dfc985eaea 100644
--- a/doc/integration/bitbucket.md
+++ b/doc/integration/bitbucket.md
@@ -5,7 +5,7 @@ Bitbucket.org account.
## Overview
-You can set up Bitbucket.org as an OAuth provider so that you can use your
+You can set up Bitbucket.org as an OAuth2 provider so that you can use your
credentials to authenticate into GitLab or import your projects from
Bitbucket.org.
@@ -50,6 +50,7 @@ you to use.
Repositories: Read
Pull Requests: Read
Issues: Read
+ Wiki: Read and Write
```
![Bitbucket OAuth settings page](img/bitbucket_oauth_settings_page.png)
diff --git a/doc/integration/img/bitbucket_oauth_settings_page.png b/doc/integration/img/bitbucket_oauth_settings_page.png
index 21ce82a6074..3e6dea6cfe9 100644
--- a/doc/integration/img/bitbucket_oauth_settings_page.png
+++ b/doc/integration/img/bitbucket_oauth_settings_page.png
Binary files differ
diff --git a/doc/raketasks/README.md b/doc/raketasks/README.md
index a49c43b8ef2..2b81ebc9c59 100644
--- a/doc/raketasks/README.md
+++ b/doc/raketasks/README.md
@@ -4,7 +4,8 @@
- [Check](check.md)
- [Cleanup](cleanup.md)
- [Features](features.md)
-- [Maintenance](maintenance.md) and self-checks
+- [LDAP Maintenance](../administration/raketasks/ldap.md)
+- [General Maintenance](maintenance.md) and self-checks
- [User management](user_management.md)
- [Webhooks](web_hooks.md)
- [Import](import.md) of git repositories in bulk
diff --git a/doc/update/8.14-to-8.15.md b/doc/update/8.14-to-8.15.md
index 4eacab0c890..8d4bfd913bd 100644
--- a/doc/update/8.14-to-8.15.md
+++ b/doc/update/8.14-to-8.15.md
@@ -72,7 +72,7 @@ sudo -u git -H git checkout 8-15-stable-ee
```bash
cd /home/git/gitlab-shell
sudo -u git -H git fetch --all --tags
-sudo -u git -H git checkout v4.1.0
+sudo -u git -H git checkout v4.1.1
```
### 6. Update gitlab-workhorse
diff --git a/doc/workflow/importing/import_projects_from_bitbucket.md b/doc/workflow/importing/import_projects_from_bitbucket.md
index b6d47e5afa2..97380bce172 100644
--- a/doc/workflow/importing/import_projects_from_bitbucket.md
+++ b/doc/workflow/importing/import_projects_from_bitbucket.md
@@ -17,6 +17,7 @@ to enable this if not already.
- the pull requests (GitLab 8.4+)
- the pull request comments (GitLab 8.15+)
- the milestones (GitLab 8.15+)
+ - the wiki (GitLab 8.15+)
- References to pull requests and issues are preserved (GitLab 8.7+)
- Repository public access is retained. If a repository is private in Bitbucket
it will be created as private in GitLab as well.
diff --git a/features/admin/appearance.feature b/features/admin/appearance.feature
deleted file mode 100644
index 5c1dd7531c1..00000000000
--- a/features/admin/appearance.feature
+++ /dev/null
@@ -1,37 +0,0 @@
-Feature: Admin Appearance
- Scenario: Create new appearance
- Given I sign in as an admin
- And I visit admin appearance page
- When submit form with new appearance
- Then I should be redirected to admin appearance page
- And I should see newly created appearance
-
- Scenario: Preview appearance
- Given application has custom appearance
- And I sign in as an admin
- When I visit admin appearance page
- And I click preview button
- Then I should see a customized appearance
-
- Scenario: Custom sign-in page
- Given application has custom appearance
- When I visit login page
- Then I should see a customized appearance
-
- Scenario: Appearance logo
- Given application has custom appearance
- And I sign in as an admin
- And I visit admin appearance page
- When I attach a logo
- Then I should see a logo
- And I remove the logo
- Then I should see logo removed
-
- Scenario: Header logos
- Given application has custom appearance
- And I sign in as an admin
- And I visit admin appearance page
- When I attach header logos
- Then I should see header logos
- And I remove the header logos
- Then I should see header logos removed
diff --git a/features/admin/broadcast_messages.feature b/features/admin/broadcast_messages.feature
deleted file mode 100644
index 4f9c651561e..00000000000
--- a/features/admin/broadcast_messages.feature
+++ /dev/null
@@ -1,33 +0,0 @@
-@admin
-Feature: Admin Broadcast Messages
- Background:
- Given I sign in as an admin
- And application already has a broadcast message
- And I visit admin messages page
-
- Scenario: See broadcast messages list
- Then I should see all broadcast messages
-
- Scenario: Create a customized broadcast message
- When submit form with new customized broadcast message
- Then I should be redirected to admin messages page
- And I should see newly created broadcast message
- Then I visit dashboard page
- And I should see a customized broadcast message
-
- Scenario: Edit an existing broadcast message
- When I edit an existing broadcast message
- And I change the broadcast message text
- Then I should be redirected to admin messages page
- And I should see the updated broadcast message
-
- Scenario: Remove an existing broadcast message
- When I remove an existing broadcast message
- Then I should be redirected to admin messages page
- And I should not see the removed broadcast message
-
- @javascript
- Scenario: Live preview a customized broadcast message
- When I visit admin messages page
- And I enter a broadcast message with Markdown
- Then I should see a live preview of the rendered broadcast message
diff --git a/features/admin/labels.feature b/features/admin/labels.feature
deleted file mode 100644
index 1af0e700bd4..00000000000
--- a/features/admin/labels.feature
+++ /dev/null
@@ -1,38 +0,0 @@
-Feature: Admin Issues Labels
- Background:
- Given I sign in as an admin
- And I have labels: "bug", "feature", "enhancement"
- Given I visit admin labels page
-
- Scenario: I should see labels list
- Then I should see label 'bug'
- And I should see label 'feature'
-
- Scenario: I create new label
- Given I submit new label 'support'
- Then I should see label 'support'
-
- Scenario: I edit label
- Given I visit 'bug' label edit page
- When I change label 'bug' to 'fix'
- Then I should not see label 'bug'
- Then I should see label 'fix'
-
- Scenario: I remove label
- When I remove label 'bug'
- Then I should not see label 'bug'
-
- @javascript
- Scenario: I delete all labels
- When I delete all labels
- Then I should see labels help message
-
- Scenario: I create a label with invalid color
- Given I visit admin new label page
- When I submit new label with invalid color
- Then I should see label color error message
-
- Scenario: I create a label that already exists
- Given I visit admin new label page
- When I submit new label 'bug'
- Then I should see label exist error message
diff --git a/features/steps/admin/appearance.rb b/features/steps/admin/appearance.rb
deleted file mode 100644
index 0d1be46d11d..00000000000
--- a/features/steps/admin/appearance.rb
+++ /dev/null
@@ -1,72 +0,0 @@
-class Spinach::Features::AdminAppearance < Spinach::FeatureSteps
- include SharedAuthentication
- include SharedPaths
-
- step 'submit form with new appearance' do
- fill_in 'appearance_title', with: 'MyCompany'
- fill_in 'appearance_description', with: 'dev server'
- click_button 'Save'
- end
-
- step 'I should be redirected to admin appearance page' do
- expect(current_path).to eq admin_appearances_path
- expect(page).to have_content 'Appearance settings'
- end
-
- step 'I should see newly created appearance' do
- expect(page).to have_field('appearance_title', with: 'MyCompany')
- expect(page).to have_field('appearance_description', with: 'dev server')
- expect(page).to have_content 'Last edit'
- end
-
- step 'I click preview button' do
- click_link "Preview"
- end
-
- step 'application has custom appearance' do
- create(:appearance)
- end
-
- step 'I should see a customized appearance' do
- expect(page).to have_content appearance.title
- expect(page).to have_content appearance.description
- end
-
- step 'I attach a logo' do
- attach_file(:appearance_logo, Rails.root.join('spec', 'fixtures', 'dk.png'))
- click_button 'Save'
- end
-
- step 'I attach header logos' do
- attach_file(:appearance_header_logo, Rails.root.join('spec', 'fixtures', 'dk.png'))
- click_button 'Save'
- end
-
- step 'I should see a logo' do
- expect(page).to have_xpath('//img[@src="/uploads/appearance/logo/1/dk.png"]')
- end
-
- step 'I should see header logos' do
- expect(page).to have_xpath('//img[@src="/uploads/appearance/header_logo/1/dk.png"]')
- end
-
- step 'I remove the logo' do
- click_link 'Remove logo'
- end
-
- step 'I remove the header logos' do
- click_link 'Remove header logo'
- end
-
- step 'I should see logo removed' do
- expect(page).not_to have_xpath('//img[@src="/uploads/appearance/logo/1/gitlab_logo.png"]')
- end
-
- step 'I should see header logos removed' do
- expect(page).not_to have_xpath('//img[@src="/uploads/appearance/header_logo/1/header_logo_light.png"]')
- end
-
- def appearance
- Appearance.last
- end
-end
diff --git a/features/steps/admin/broadcast_messages.rb b/features/steps/admin/broadcast_messages.rb
deleted file mode 100644
index af2b4a29313..00000000000
--- a/features/steps/admin/broadcast_messages.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-class Spinach::Features::AdminBroadcastMessages < Spinach::FeatureSteps
- include SharedAuthentication
- include SharedPaths
-
- step 'application already has a broadcast message' do
- FactoryGirl.create(:broadcast_message, :expired, message: "Migration to new server")
- end
-
- step 'I should see all broadcast messages' do
- expect(page).to have_content "Migration to new server"
- end
-
- step 'I should be redirected to admin messages page' do
- expect(current_path).to eq admin_broadcast_messages_path
- end
-
- step 'I should see newly created broadcast message' do
- expect(page).to have_content 'Application update from 4:00 CST to 5:00 CST'
- end
-
- step 'submit form with new customized broadcast message' do
- fill_in 'broadcast_message_message', with: 'Application update from **4:00 CST to 5:00 CST**'
- fill_in 'broadcast_message_color', with: '#f2dede'
- fill_in 'broadcast_message_font', with: '#b94a48'
- select Date.today.next_year.year, from: "broadcast_message_ends_at_1i"
- click_button "Add broadcast message"
- end
-
- step 'I should see a customized broadcast message' do
- expect(page).to have_content 'Application update from 4:00 CST to 5:00 CST'
- expect(page).to have_selector 'strong', text: '4:00 CST to 5:00 CST'
- expect(page).to have_selector %(div[style="background-color: #f2dede; color: #b94a48"])
- end
-
- step 'I edit an existing broadcast message' do
- click_link 'Edit'
- end
-
- step 'I change the broadcast message text' do
- fill_in 'broadcast_message_message', with: 'Application update RIGHT NOW'
- click_button 'Update broadcast message'
- end
-
- step 'I should see the updated broadcast message' do
- expect(page).to have_content "Application update RIGHT NOW"
- end
-
- step 'I remove an existing broadcast message' do
- click_link 'Remove'
- end
-
- step 'I should not see the removed broadcast message' do
- expect(page).not_to have_content 'Migration to new server'
- end
-
- step 'I enter a broadcast message with Markdown' do
- fill_in 'broadcast_message_message', with: "Live **Markdown** previews. :tada:"
- end
-
- step 'I should see a live preview of the rendered broadcast message' do
- page.within('.broadcast-message-preview') do
- expect(page).to have_selector('strong', text: 'Markdown')
- expect(page).to have_selector('img.emoji')
- end
- end
-end
diff --git a/features/steps/admin/labels.rb b/features/steps/admin/labels.rb
deleted file mode 100644
index 55ddcc25085..00000000000
--- a/features/steps/admin/labels.rb
+++ /dev/null
@@ -1,117 +0,0 @@
-class Spinach::Features::AdminIssuesLabels < Spinach::FeatureSteps
- include SharedAuthentication
- include SharedProject
- include SharedPaths
-
- step 'I visit \'bug\' label edit page' do
- visit edit_admin_label_path(bug_label)
- end
-
- step 'I visit admin new label page' do
- visit new_admin_label_path
- end
-
- step 'I visit admin labels page' do
- visit admin_labels_path
- end
-
- step 'I remove label \'bug\'' do
- page.within "#label_#{bug_label.id}" do
- click_link 'Delete'
- end
- end
-
- step 'I have labels: "bug", "feature", "enhancement"' do
- ["bug", "feature", "enhancement"].each do |title|
- Label.create(title: title, template: true)
- end
- end
-
- step 'I delete all labels' do
- page.within '.labels' do
- page.all('.btn-remove').each do |remove|
- remove.click
- sleep 0.05
- end
- end
- end
-
- step 'I should see labels help message' do
- page.within '.labels' do
- expect(page).to have_content 'There are no labels yet'
- end
- end
-
- step 'I submit new label \'support\'' do
- visit new_admin_label_path
- fill_in 'Title', with: 'support'
- fill_in 'Background color', with: '#F95610'
- click_button 'Save'
- end
-
- step 'I submit new label \'bug\'' do
- visit new_admin_label_path
- fill_in 'Title', with: 'bug'
- fill_in 'Background color', with: '#F95610'
- click_button 'Save'
- end
-
- step 'I submit new label with invalid color' do
- visit new_admin_label_path
- fill_in 'Title', with: 'support'
- fill_in 'Background color', with: '#12'
- click_button 'Save'
- end
-
- step 'I should see label exist error message' do
- page.within '.label-form' do
- expect(page).to have_content 'Title has already been taken'
- end
- end
-
- step 'I should see label color error message' do
- page.within '.label-form' do
- expect(page).to have_content 'Color must be a valid color code'
- end
- end
-
- step 'I should see label \'feature\'' do
- page.within '.manage-labels-list' do
- expect(page).to have_content 'feature'
- end
- end
-
- step 'I should see label \'bug\'' do
- page.within '.manage-labels-list' do
- expect(page).to have_content 'bug'
- end
- end
-
- step 'I should not see label \'bug\'' do
- page.within '.manage-labels-list' do
- expect(page).not_to have_content 'bug'
- end
- end
-
- step 'I should see label \'support\'' do
- page.within '.manage-labels-list' do
- expect(page).to have_content 'support'
- end
- end
-
- step 'I change label \'bug\' to \'fix\'' do
- fill_in 'Title', with: 'fix'
- fill_in 'Background color', with: '#F15610'
- click_button 'Save'
- end
-
- step 'I should see label \'fix\'' do
- page.within '.manage-labels-list' do
- expect(page).to have_content 'fix'
- end
- end
-
- def bug_label
- Label.templates.find_or_create_by(title: 'bug')
- end
-end
diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb
index a78d0a775ba..15b81fa529b 100644
--- a/features/steps/shared/paths.rb
+++ b/features/steps/shared/paths.rb
@@ -195,10 +195,6 @@ module SharedPaths
visit admin_groups_path
end
- step 'I visit admin appearance page' do
- visit admin_appearances_path
- end
-
step 'I visit admin teams page' do
visit admin_teams_path
end
diff --git a/lib/bitbucket/representation/repo.rb b/lib/bitbucket/representation/repo.rb
index 8969ecd1c19..423eff8f2a5 100644
--- a/lib/bitbucket/representation/repo.rb
+++ b/lib/bitbucket/representation/repo.rb
@@ -51,6 +51,10 @@ module Bitbucket
raw['scm'] == 'git'
end
+ def has_wiki?
+ raw['has_wiki']
+ end
+
def visibility_level
if raw['is_private']
Gitlab::VisibilityLevel::PRIVATE
diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb
index fef652cb975..7463bd719d5 100644
--- a/lib/ci/gitlab_ci_yaml_processor.rb
+++ b/lib/ci/gitlab_ci_yaml_processor.rb
@@ -118,7 +118,7 @@ module Ci
.merge(job_variables(name))
variables.map do |key, value|
- { key: key, value: value, public: true }
+ { key: key.to_s, value: value, public: true }
end
end
diff --git a/lib/gitlab/bitbucket_import/importer.rb b/lib/gitlab/bitbucket_import/importer.rb
index 7d2f92d577a..44323b47dca 100644
--- a/lib/gitlab/bitbucket_import/importer.rb
+++ b/lib/gitlab/bitbucket_import/importer.rb
@@ -1,6 +1,8 @@
module Gitlab
module BitbucketImport
class Importer
+ include Gitlab::ShellAdapter
+
LABELS = [{ title: 'bug', color: '#FF0000' },
{ title: 'enhancement', color: '#428BCA' },
{ title: 'proposal', color: '#69D100' },
@@ -18,6 +20,7 @@ module Gitlab
end
def execute
+ import_wiki
import_issues
import_pull_requests
handle_errors
@@ -55,6 +58,16 @@ module Gitlab
@repo ||= client.repo(project.import_source)
end
+ def import_wiki
+ return if project.wiki.repository_exists?
+
+ path_with_namespace = "#{project.path_with_namespace}.wiki"
+ import_url = project.import_url.sub(/\.git\z/, ".git/wiki")
+ gitlab_shell.import_repository(project.repository_storage_path, path_with_namespace, import_url)
+ rescue StandardError => e
+ errors << { type: :wiki, errors: e.message }
+ end
+
def import_issues
return unless repo.issues_enabled?
diff --git a/lib/gitlab/bitbucket_import/project_creator.rb b/lib/gitlab/bitbucket_import/project_creator.rb
index eb03882ab26..d94f70fd1fb 100644
--- a/lib/gitlab/bitbucket_import/project_creator.rb
+++ b/lib/gitlab/bitbucket_import/project_creator.rb
@@ -22,9 +22,16 @@ module Gitlab
import_type: 'bitbucket',
import_source: repo.full_name,
import_url: repo.clone_url(session_data[:token]),
- import_data: { credentials: session_data }
+ import_data: { credentials: session_data },
+ skip_wiki: skip_wiki
).execute
end
+
+ private
+
+ def skip_wiki
+ repo.has_wiki?
+ end
end
end
end
diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb
index c551321c18d..cda6ddf0443 100644
--- a/lib/gitlab/import_export/project_tree_restorer.rb
+++ b/lib/gitlab/import_export/project_tree_restorer.rb
@@ -120,7 +120,7 @@ module Gitlab
members_mapper: members_mapper,
user: @user,
project_id: restored_project.id)
- end
+ end.compact
relation_hash_list.is_a?(Array) ? relation_array : relation_array.first
end
diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb
index a0e80fccad9..65b229ca8ff 100644
--- a/lib/gitlab/import_export/relation_factory.rb
+++ b/lib/gitlab/import_export/relation_factory.rb
@@ -14,7 +14,7 @@ module Gitlab
priorities: :label_priorities,
label: :project_label }.freeze
- USER_REFERENCES = %w[author_id assignee_id updated_by_id user_id created_by_id].freeze
+ USER_REFERENCES = %w[author_id assignee_id updated_by_id user_id created_by_id merge_user_id].freeze
PROJECT_REFERENCES = %w[project_id source_project_id gl_project_id target_project_id].freeze
@@ -40,6 +40,8 @@ module Gitlab
# the relation_hash, updating references with new object IDs, mapping users using
# the "members_mapper" object, also updating notes if required.
def create
+ return nil if unknown_service?
+
setup_models
generate_imported_object
@@ -99,6 +101,8 @@ module Gitlab
def generate_imported_object
if BUILD_MODELS.include?(@relation_name) # call #trace= method after assigning the other attributes
trace = @relation_hash.delete('trace')
+ @relation_hash.delete('token')
+
imported_object do |object|
object.trace = trace
object.commit_id = nil
@@ -215,6 +219,11 @@ module Gitlab
existing_object
end
end
+
+ def unknown_service?
+ @relation_name == :services && parsed_relation_hash['type'] &&
+ !Object.const_defined?(parsed_relation_hash['type'])
+ end
end
end
end
diff --git a/lib/gitlab/serialize/ci/variables.rb b/lib/gitlab/serialize/ci/variables.rb
new file mode 100644
index 00000000000..3a9443bfcd9
--- /dev/null
+++ b/lib/gitlab/serialize/ci/variables.rb
@@ -0,0 +1,27 @@
+module Gitlab
+ module Serialize
+ module Ci
+ # This serializer could make sure our YAML variables' keys and values
+ # are always strings. This is more for legacy build data because
+ # from now on we convert them into strings before saving to database.
+ module Variables
+ extend self
+
+ def load(string)
+ return unless string
+
+ object = YAML.safe_load(string, [Symbol])
+
+ object.map do |variable|
+ variable[:key] = variable[:key].to_s
+ variable
+ end
+ end
+
+ def dump(object)
+ YAML.dump(object)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/tasks/gitlab/ldap.rake b/lib/tasks/gitlab/ldap.rake
new file mode 100644
index 00000000000..c66a2a263dc
--- /dev/null
+++ b/lib/tasks/gitlab/ldap.rake
@@ -0,0 +1,40 @@
+namespace :gitlab do
+ namespace :ldap do
+ desc 'GitLab | LDAP | Rename provider'
+ task :rename_provider, [:old_provider, :new_provider] => :environment do |_, args|
+ old_provider = args[:old_provider] ||
+ prompt('What is the old provider? Ex. \'ldapmain\': '.color(:blue))
+ new_provider = args[:new_provider] ||
+ prompt('What is the new provider ID? Ex. \'ldapcustom\': '.color(:blue))
+ puts '' # Add some separation in the output
+
+ identities = Identity.where(provider: old_provider)
+ identity_count = identities.count
+
+ if identities.empty?
+ puts "Found no user identities with '#{old_provider}' provider."
+ puts 'Please check the provider name and try again.'
+ exit 1
+ end
+
+ plural_id_count = ActionController::Base.helpers.pluralize(identity_count, 'user')
+
+ unless ENV['force'] == 'yes'
+ puts "#{plural_id_count} with provider '#{old_provider}' will be updated to '#{new_provider}'"
+ puts 'If the new provider is incorrect, users will be unable to sign in'
+ ask_to_continue
+ puts ''
+ end
+
+ updated_count = identities.update_all(provider: new_provider)
+
+ if updated_count == identity_count
+ puts 'User identities were successfully updated'.color(:green)
+ else
+ plural_updated_count = ActionController::Base.helpers.pluralize(updated_count, 'user')
+ puts 'Some user identities could not be updated'.color(:red)
+ puts "Successfully updated #{plural_updated_count} out of #{plural_id_count} total"
+ end
+ end
+ end
+end
diff --git a/spec/controllers/projects/blame_controller_spec.rb b/spec/controllers/projects/blame_controller_spec.rb
index 25f06299a29..4402ca43c65 100644
--- a/spec/controllers/projects/blame_controller_spec.rb
+++ b/spec/controllers/projects/blame_controller_spec.rb
@@ -25,5 +25,10 @@ describe Projects::BlameController do
let(:id) { 'master/files/ruby/popen.rb' }
it { is_expected.to respond_with(:success) }
end
+
+ context "invalid file" do
+ let(:id) { 'master/files/ruby/missing_file.rb'}
+ it { expect(response).to have_http_status(404) }
+ end
end
end
diff --git a/spec/factories/ci/builds.rb b/spec/factories/ci/builds.rb
index 62466c06194..0397d5d4001 100644
--- a/spec/factories/ci/builds.rb
+++ b/spec/factories/ci/builds.rb
@@ -22,7 +22,7 @@ FactoryGirl.define do
yaml_variables do
[
- { key: :DB_NAME, value: 'postgres', public: true }
+ { key: 'DB_NAME', value: 'postgres', public: true }
]
end
diff --git a/spec/features/admin/admin_appearance_spec.rb b/spec/features/admin/admin_appearance_spec.rb
new file mode 100644
index 00000000000..96d715ef383
--- /dev/null
+++ b/spec/features/admin/admin_appearance_spec.rb
@@ -0,0 +1,76 @@
+require 'spec_helper'
+
+feature 'Admin Appearance', feature: true do
+ let!(:appearance) { create(:appearance) }
+
+ scenario 'Create new appearance' do
+ login_as :admin
+ visit admin_appearances_path
+
+ fill_in 'appearance_title', with: 'MyCompany'
+ fill_in 'appearance_description', with: 'dev server'
+ click_button 'Save'
+
+ expect(current_path).to eq admin_appearances_path
+ expect(page).to have_content 'Appearance settings'
+
+ expect(page).to have_field('appearance_title', with: 'MyCompany')
+ expect(page).to have_field('appearance_description', with: 'dev server')
+ expect(page).to have_content 'Last edit'
+ end
+
+ scenario 'Preview appearance' do
+ login_as :admin
+
+ visit admin_appearances_path
+ click_link "Preview"
+
+ expect_page_has_custom_appearance(appearance)
+ end
+
+ scenario 'Custom sign-in page' do
+ visit new_user_session_path
+ expect_page_has_custom_appearance(appearance)
+ end
+
+ scenario 'Appearance logo' do
+ login_as :admin
+ visit admin_appearances_path
+
+ attach_file(:appearance_logo, logo_fixture)
+ click_button 'Save'
+ expect(page).to have_css(logo_selector)
+
+ click_link 'Remove logo'
+ expect(page).not_to have_css(logo_selector)
+ end
+
+ scenario 'Header logos' do
+ login_as :admin
+ visit admin_appearances_path
+
+ attach_file(:appearance_header_logo, logo_fixture)
+ click_button 'Save'
+ expect(page).to have_css(header_logo_selector)
+
+ click_link 'Remove header logo'
+ expect(page).not_to have_css(header_logo_selector)
+ end
+
+ def expect_page_has_custom_appearance(appearance)
+ expect(page).to have_content appearance.title
+ expect(page).to have_content appearance.description
+ end
+
+ def logo_selector
+ '//img[@src^="/uploads/appearance/logo"]'
+ end
+
+ def header_logo_selector
+ '//img[@src^="/uploads/appearance/header_logo"]'
+ end
+
+ def logo_fixture
+ Rails.root.join('spec', 'fixtures', 'dk.png')
+ end
+end
diff --git a/spec/features/admin/admin_broadcast_messages_spec.rb b/spec/features/admin/admin_broadcast_messages_spec.rb
new file mode 100644
index 00000000000..bc957ec72e1
--- /dev/null
+++ b/spec/features/admin/admin_broadcast_messages_spec.rb
@@ -0,0 +1,51 @@
+require 'spec_helper'
+
+feature 'Admin Broadcast Messages', feature: true do
+ before do
+ login_as :admin
+ create(:broadcast_message, :expired, message: 'Migration to new server')
+ visit admin_broadcast_messages_path
+ end
+
+ scenario 'See broadcast messages list' do
+ expect(page).to have_content 'Migration to new server'
+ end
+
+ scenario 'Create a customized broadcast message' do
+ fill_in 'broadcast_message_message', with: 'Application update from **4:00 CST to 5:00 CST**'
+ fill_in 'broadcast_message_color', with: '#f2dede'
+ fill_in 'broadcast_message_font', with: '#b94a48'
+ select Date.today.next_year.year, from: 'broadcast_message_ends_at_1i'
+ click_button 'Add broadcast message'
+
+ expect(current_path).to eq admin_broadcast_messages_path
+ expect(page).to have_content 'Application update from 4:00 CST to 5:00 CST'
+ expect(page).to have_selector 'strong', text: '4:00 CST to 5:00 CST'
+ expect(page).to have_selector %(div[style="background-color: #f2dede; color: #b94a48"])
+ end
+
+ scenario 'Edit an existing broadcast message' do
+ click_link 'Edit'
+ fill_in 'broadcast_message_message', with: 'Application update RIGHT NOW'
+ click_button 'Update broadcast message'
+
+ expect(current_path).to eq admin_broadcast_messages_path
+ expect(page).to have_content 'Application update RIGHT NOW'
+ end
+
+ scenario 'Remove an existing broadcast message' do
+ click_link 'Remove'
+
+ expect(current_path).to eq admin_broadcast_messages_path
+ expect(page).not_to have_content 'Migration to new server'
+ end
+
+ scenario 'Live preview a customized broadcast message', js: true do
+ fill_in 'broadcast_message_message', with: "Live **Markdown** previews. :tada:"
+
+ page.within('.broadcast-message-preview') do
+ expect(page).to have_selector('strong', text: 'Markdown')
+ expect(page).to have_selector('img.emoji')
+ end
+ end
+end
diff --git a/spec/features/admin/admin_labels_spec.rb b/spec/features/admin/admin_labels_spec.rb
new file mode 100644
index 00000000000..eaa42aad0a7
--- /dev/null
+++ b/spec/features/admin/admin_labels_spec.rb
@@ -0,0 +1,99 @@
+require 'spec_helper'
+
+RSpec.describe 'admin issues labels' do
+ include WaitForAjax
+
+ let!(:bug_label) { Label.create(title: 'bug', template: true) }
+ let!(:feature_label) { Label.create(title: 'feature', template: true) }
+
+ before do
+ login_as :admin
+ end
+
+ describe 'list' do
+ before do
+ visit admin_labels_path
+ end
+
+ it 'renders labels list' do
+ page.within '.manage-labels-list' do
+ expect(page).to have_content('bug')
+ expect(page).to have_content('feature')
+ end
+ end
+
+ it 'deletes label' do
+ page.within "#label_#{bug_label.id}" do
+ click_link 'Delete'
+ end
+
+ page.within '.manage-labels-list' do
+ expect(page).not_to have_content('bug')
+ end
+ end
+
+ it 'deletes all labels', js: true do
+ page.within '.labels' do
+ page.all('.btn-remove').each do |remove|
+ wait_for_ajax
+ remove.click
+ end
+ end
+
+ page.within '.manage-labels-list' do
+ expect(page).not_to have_content('bug')
+ expect(page).not_to have_content('feature_label')
+ end
+ end
+ end
+
+ describe 'create' do
+ before do
+ visit new_admin_label_path
+ end
+
+ it 'creates new label' do
+ fill_in 'Title', with: 'support'
+ fill_in 'Background color', with: '#F95610'
+ click_button 'Save'
+
+ page.within '.manage-labels-list' do
+ expect(page).to have_content('support')
+ end
+ end
+
+ it 'does not creates label with invalid color' do
+ fill_in 'Title', with: 'support'
+ fill_in 'Background color', with: '#12'
+ click_button 'Save'
+
+ page.within '.label-form' do
+ expect(page).to have_content('Color must be a valid color code')
+ end
+ end
+
+ it 'does not creates label if label already exists' do
+ fill_in 'Title', with: 'bug'
+ fill_in 'Background color', with: '#F95610'
+ click_button 'Save'
+
+ page.within '.label-form' do
+ expect(page).to have_content 'Title has already been taken'
+ end
+ end
+ end
+
+ describe 'edit' do
+ it 'changes bug label' do
+ visit edit_admin_label_path(bug_label)
+
+ fill_in 'Title', with: 'fix'
+ fill_in 'Background color', with: '#F15610'
+ click_button 'Save'
+
+ page.within '.manage-labels-list' do
+ expect(page).to have_content('fix')
+ end
+ end
+ end
+end
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index 57f1e75ea2c..1210e2745db 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -19,7 +19,7 @@ describe "Pipelines", feature: true, js: true do
@success = create(:ci_build, :success, pipeline: pipeline, stage: 'build', name: 'build')
@failed = create(:ci_build, :failed, pipeline: pipeline, stage: 'test', name: 'test', commands: 'test')
@running = create(:ci_build, :running, pipeline: pipeline, stage: 'deploy', name: 'deploy')
- @manual = create(:ci_build, :manual, pipeline: pipeline, stage: 'deploy', name: 'manual build')
+ @manual = create(:ci_build, :manual, pipeline: pipeline, stage: 'deploy', name: 'manual-build')
@external = create(:generic_commit_status, status: 'success', pipeline: pipeline, name: 'jenkins', stage: 'external')
end
@@ -41,37 +41,34 @@ describe "Pipelines", feature: true, js: true do
describe 'pipeline graph' do
context 'when pipeline has running builds' do
it 'shows a running icon and a cancel action for the running build' do
- page.within('a[data-title="deploy - running"]') do
+ page.within('#ci-badge-deploy') do
expect(page).to have_selector('.ci-status-icon-running')
- expect(page).to have_content('deploy')
- end
-
- page.within('a[data-title="deploy - running"] + .ci-action-icon-container') do
expect(page).to have_selector('.ci-action-icon-container .fa-ban')
+ expect(page).to have_content('deploy')
end
end
it 'should be possible to cancel the running build' do
- find('a[data-title="deploy - running"] + .ci-action-icon-container').trigger('click')
+ find('#ci-badge-deploy .ci-action-icon-container').trigger('click')
expect(page).not_to have_content('Cancel running')
end
end
context 'when pipeline has successful builds' do
- it 'shows the success icon and a retry action for the successfull build' do
- page.within('a[data-title="build - passed"]') do
+ it 'shows the success icon and a retry action for the successful build' do
+ page.within('#ci-badge-build') do
expect(page).to have_selector('.ci-status-icon-success')
expect(page).to have_content('build')
end
- page.within('a[data-title="build - passed"] + .ci-action-icon-container') do
+ page.within('#ci-badge-build .ci-action-icon-container') do
expect(page).to have_selector('.ci-action-icon-container .fa-refresh')
end
end
it 'should be possible to retry the success build' do
- find('a[data-title="build - passed"] + .ci-action-icon-container').trigger('click')
+ find('#ci-badge-build .ci-action-icon-container').trigger('click')
expect(page).not_to have_content('Retry build')
end
@@ -79,18 +76,18 @@ describe "Pipelines", feature: true, js: true do
context 'when pipeline has failed builds' do
it 'shows the failed icon and a retry action for the failed build' do
- page.within('a[data-title="test - failed"]') do
+ page.within('#ci-badge-test') do
expect(page).to have_selector('.ci-status-icon-failed')
expect(page).to have_content('test')
end
- page.within('a[data-title="test - failed"] + .ci-action-icon-container') do
+ page.within('#ci-badge-test .ci-action-icon-container') do
expect(page).to have_selector('.ci-action-icon-container .fa-refresh')
end
end
it 'should be possible to retry the failed build' do
- find('a[data-title="test - failed"] + .ci-action-icon-container').trigger('click')
+ find('#ci-badge-test .ci-action-icon-container').trigger('click')
expect(page).not_to have_content('Retry build')
end
@@ -98,18 +95,18 @@ describe "Pipelines", feature: true, js: true do
context 'when pipeline has manual builds' do
it 'shows the skipped icon and a play action for the manual build' do
- page.within('a[data-title="manual build - manual play action"]') do
+ page.within('#ci-badge-manual-build') do
expect(page).to have_selector('.ci-status-icon-manual')
expect(page).to have_content('manual')
end
- page.within('a[data-title="manual build - manual play action"] + .ci-action-icon-container') do
+ page.within('#ci-badge-manual-build .ci-action-icon-container') do
expect(page).to have_selector('.ci-action-icon-container .fa-play')
end
end
it 'should be possible to play the manual build' do
- find('a[data-title="manual build - manual play action"] + .ci-action-icon-container').trigger('click')
+ find('#ci-badge-manual-build .ci-action-icon-container').trigger('click')
expect(page).not_to have_content('Play build')
end
@@ -167,7 +164,7 @@ describe "Pipelines", feature: true, js: true do
@success = create(:ci_build, :success, pipeline: pipeline, stage: 'build', name: 'build')
@failed = create(:ci_build, :failed, pipeline: pipeline, stage: 'test', name: 'test', commands: 'test')
@running = create(:ci_build, :running, pipeline: pipeline, stage: 'deploy', name: 'deploy')
- @manual = create(:ci_build, :manual, pipeline: pipeline, stage: 'deploy', name: 'manual build')
+ @manual = create(:ci_build, :manual, pipeline: pipeline, stage: 'deploy', name: 'manual-build')
@external = create(:generic_commit_status, status: 'success', pipeline: pipeline, name: 'jenkins', stage: 'external')
end
diff --git a/spec/javascripts/fixtures/pipeline_graph.html.haml b/spec/javascripts/fixtures/pipeline_graph.html.haml
index deca50ceaa7..c0b5ab4411e 100644
--- a/spec/javascripts/fixtures/pipeline_graph.html.haml
+++ b/spec/javascripts/fixtures/pipeline_graph.html.haml
@@ -8,8 +8,7 @@
%ul
%li.build
.curve
- .build-content
- %a
- %svg
- .ci-status-text
- stop_review
+ %a
+ %svg
+ .ci-status-text
+ stop_review
diff --git a/spec/lib/bitbucket/representation/repo_spec.rb b/spec/lib/bitbucket/representation/repo_spec.rb
new file mode 100644
index 00000000000..adcd978e1b3
--- /dev/null
+++ b/spec/lib/bitbucket/representation/repo_spec.rb
@@ -0,0 +1,49 @@
+require 'spec_helper'
+
+describe Bitbucket::Representation::Repo do
+ describe '#has_wiki?' do
+ it { expect(described_class.new({ 'has_wiki' => false }).has_wiki?).to be_falsey }
+ it { expect(described_class.new({ 'has_wiki' => true }).has_wiki?).to be_truthy }
+ end
+
+ describe '#name' do
+ it { expect(described_class.new({ 'name' => 'test' }).name).to eq('test') }
+ end
+
+ describe '#valid?' do
+ it { expect(described_class.new({ 'scm' => 'hg' }).valid?).to be_falsey }
+ it { expect(described_class.new({ 'scm' => 'git' }).valid?).to be_truthy }
+ end
+
+ describe '#full_name' do
+ it { expect(described_class.new({ 'full_name' => 'test_full' }).full_name).to eq('test_full') }
+ end
+
+ describe '#description' do
+ it { expect(described_class.new({ 'description' => 'desc' }).description).to eq('desc') }
+ end
+
+ describe '#issues_enabled?' do
+ it { expect(described_class.new({ 'has_issues' => false }).issues_enabled?).to be_falsey }
+ it { expect(described_class.new({ 'has_issues' => true }).issues_enabled?).to be_truthy }
+ end
+
+ describe '#owner_and_slug' do
+ it { expect(described_class.new({ 'full_name' => 'ben/test' }).owner_and_slug).to eq(['ben', 'test']) }
+ end
+
+ describe '#owner' do
+ it { expect(described_class.new({ 'full_name' => 'ben/test' }).owner).to eq('ben') }
+ end
+
+ describe '#slug' do
+ it { expect(described_class.new({ 'full_name' => 'ben/test' }).slug).to eq('test') }
+ end
+
+ describe '#clone_url' do
+ it 'builds url' do
+ data = { 'links' => { 'clone' => [ { 'name' => 'https', 'href' => 'https://bibucket.org/test/test.git' }] } }
+ expect(described_class.new(data).clone_url('abc')).to eq('https://x-token-auth:abc@bibucket.org/test/test.git')
+ end
+ end
+end
diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
index ff5dcc06ab3..62d68721574 100644
--- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
+++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
@@ -483,7 +483,7 @@ module Ci
context 'when global variables are defined' do
let(:variables) do
- { VAR1: 'value1', VAR2: 'value2' }
+ { 'VAR1' => 'value1', 'VAR2' => 'value2' }
end
let(:config) do
{
@@ -495,18 +495,18 @@ module Ci
it 'returns global variables' do
expect(subject).to contain_exactly(
- { key: :VAR1, value: 'value1', public: true },
- { key: :VAR2, value: 'value2', public: true }
+ { key: 'VAR1', value: 'value1', public: true },
+ { key: 'VAR2', value: 'value2', public: true }
)
end
end
context 'when job and global variables are defined' do
let(:global_variables) do
- { VAR1: 'global1', VAR3: 'global3' }
+ { 'VAR1' => 'global1', 'VAR3' => 'global3' }
end
let(:job_variables) do
- { VAR1: 'value1', VAR2: 'value2' }
+ { 'VAR1' => 'value1', 'VAR2' => 'value2' }
end
let(:config) do
{
@@ -518,9 +518,9 @@ module Ci
it 'returns all unique variables' do
expect(subject).to contain_exactly(
- { key: :VAR3, value: 'global3', public: true },
- { key: :VAR1, value: 'value1', public: true },
- { key: :VAR2, value: 'value2', public: true }
+ { key: 'VAR3', value: 'global3', public: true },
+ { key: 'VAR1', value: 'value1', public: true },
+ { key: 'VAR2', value: 'value2', public: true }
)
end
end
@@ -535,13 +535,13 @@ module Ci
context 'when syntax is correct' do
let(:variables) do
- { VAR1: 'value1', VAR2: 'value2' }
+ { 'VAR1' => 'value1', 'VAR2' => 'value2' }
end
it 'returns job variables' do
expect(subject).to contain_exactly(
- { key: :VAR1, value: 'value1', public: true },
- { key: :VAR2, value: 'value2', public: true }
+ { key: 'VAR1', value: 'value1', public: true },
+ { key: 'VAR2', value: 'value2', public: true }
)
end
end
@@ -549,7 +549,7 @@ module Ci
context 'when syntax is incorrect' do
context 'when variables defined but invalid' do
let(:variables) do
- [ :VAR1, 'value1', :VAR2, 'value2' ]
+ [ 'VAR1', 'value1', 'VAR2', 'value2' ]
end
it 'raises error' do
diff --git a/spec/lib/gitlab/bitbucket_import/importer_spec.rb b/spec/lib/gitlab/bitbucket_import/importer_spec.rb
index 53f3c73ade4..72b1ba36b58 100644
--- a/spec/lib/gitlab/bitbucket_import/importer_spec.rb
+++ b/spec/lib/gitlab/bitbucket_import/importer_spec.rb
@@ -69,6 +69,9 @@ describe Gitlab::BitbucketImport::Importer, lib: true do
context 'issues statuses' do
before do
+ # HACK: Bitbucket::Representation.const_get('Issue') seems to return ::Issue without this
+ Bitbucket::Representation::Issue.new({})
+
stub_request(
:get,
"https://api.bitbucket.org/2.0/repositories/#{project_identifier}"
@@ -108,13 +111,16 @@ describe Gitlab::BitbucketImport::Importer, lib: true do
body: {}.to_json)
end
- it 'map statuses to open or closed' do
- # HACK: Bitbucket::Representation.const_get('Issue') seems to return ::Issue without this
- Bitbucket::Representation::Issue.new({})
+ it 'maps statuses to open or closed' do
importer.execute
expect(project.issues.where(state: "closed").size).to eq(5)
expect(project.issues.where(state: "opened").size).to eq(2)
end
+
+ it 'calls import_wiki' do
+ expect(importer).to receive(:import_wiki)
+ importer.execute
+ end
end
end
diff --git a/spec/lib/gitlab/bitbucket_import/project_creator_spec.rb b/spec/lib/gitlab/bitbucket_import/project_creator_spec.rb
index b6d052a4612..773d0d4d288 100644
--- a/spec/lib/gitlab/bitbucket_import/project_creator_spec.rb
+++ b/spec/lib/gitlab/bitbucket_import/project_creator_spec.rb
@@ -11,7 +11,8 @@ describe Gitlab::BitbucketImport::ProjectCreator, lib: true do
owner: "asd",
full_name: 'Vim repo',
visibility_level: Gitlab::VisibilityLevel::PRIVATE,
- clone_url: 'ssh://git@bitbucket.org/asd/vim.git')
+ clone_url: 'ssh://git@bitbucket.org/asd/vim.git',
+ has_wiki?: false)
end
let(:namespace){ create(:group, owner: user) }
diff --git a/spec/lib/gitlab/import_export/project.json b/spec/lib/gitlab/import_export/project.json
index ed9df468ced..931d426c87f 100644
--- a/spec/lib/gitlab/import_export/project.json
+++ b/spec/lib/gitlab/import_export/project.json
@@ -2517,7 +2517,7 @@
"merge_params": {
"force_remove_source_branch": null
},
- "merge_when_build_succeeds": false,
+ "merge_when_build_succeeds": true,
"merge_user_id": null,
"merge_commit_sha": null,
"deleted_at": null,
@@ -6548,7 +6548,9 @@
"url": null
},
"erased_by_id": null,
- "erased_at": null
+ "erased_at": null,
+ "type": "Ci::Build",
+ "token": "abcd"
},
{
"id": 72,
@@ -7409,6 +7411,28 @@
"category": "common",
"default": false,
"wiki_page_events": true
+ },
+ {
+ "id": 101,
+ "title": "JenkinsDeprecated",
+ "project_id": 5,
+ "created_at": "2016-06-14T15:01:51.031Z",
+ "updated_at": "2016-06-14T15:01:51.031Z",
+ "active": false,
+ "properties": {
+
+ },
+ "template": false,
+ "push_events": true,
+ "issues_events": true,
+ "merge_requests_events": true,
+ "tag_push_events": true,
+ "note_events": true,
+ "build_events": true,
+ "category": "common",
+ "default": false,
+ "wiki_page_events": true,
+ "type": "JenkinsDeprecatedService"
}
],
"hooks": [
diff --git a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
index 3038ab53ad8..4b07fa53bf5 100644
--- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
@@ -189,6 +189,14 @@ describe Gitlab::ImportExport::ProjectTreeRestorer, services: true do
end
end
end
+
+ context 'when there is an existing build with build token' do
+ it 'restores project json correctly' do
+ create(:ci_build, token: 'abcd')
+
+ expect(restored_project_json).to be true
+ end
+ end
end
end
end
diff --git a/spec/lib/gitlab/serialize/ci/variables_spec.rb b/spec/lib/gitlab/serialize/ci/variables_spec.rb
new file mode 100644
index 00000000000..7ea74da5252
--- /dev/null
+++ b/spec/lib/gitlab/serialize/ci/variables_spec.rb
@@ -0,0 +1,18 @@
+require 'spec_helper'
+
+describe Gitlab::Serialize::Ci::Variables do
+ subject do
+ described_class.load(described_class.dump(object))
+ end
+
+ let(:object) do
+ [{ key: :key, value: 'value', public: true },
+ { key: 'wee', value: 1, public: false }]
+ end
+
+ it 'converts keys into strings' do
+ is_expected.to eq([
+ { key: 'key', value: 'value', public: true },
+ { key: 'wee', value: 1, public: false }])
+ end
+end
diff --git a/spec/models/build_spec.rb b/spec/models/build_spec.rb
index 6f1c2ae0fd8..cd3b6d51545 100644
--- a/spec/models/build_spec.rb
+++ b/spec/models/build_spec.rb
@@ -458,7 +458,7 @@ describe Ci::Build, models: true do
})
end
let(:variables) do
- [{ key: :KEY, value: 'value', public: true }]
+ [{ key: 'KEY', value: 'value', public: true }]
end
it { is_expected.to eq(predefined_variables + variables) }
@@ -1306,11 +1306,25 @@ describe Ci::Build, models: true do
describe '#expanded_environment_name' do
subject { build.expanded_environment_name }
- context 'when environment uses variables' do
- let(:build) { create(:ci_build, ref: 'master', environment: 'review/$CI_BUILD_REF_NAME') }
+ context 'when environment uses $CI_BUILD_REF_NAME' do
+ let(:build) do
+ create(:ci_build,
+ ref: 'master',
+ environment: 'review/$CI_BUILD_REF_NAME')
+ end
it { is_expected.to eq('review/master') }
end
+
+ context 'when environment uses yaml_variables containing symbol keys' do
+ let(:build) do
+ create(:ci_build,
+ yaml_variables: [{ key: :APP_HOST, value: 'host' }],
+ environment: 'review/$APP_HOST')
+ end
+
+ it { is_expected.to eq('review/host') }
+ end
end
describe '#detailed_status' do
diff --git a/spec/tasks/gitlab/ldap_rake_spec.rb b/spec/tasks/gitlab/ldap_rake_spec.rb
new file mode 100644
index 00000000000..12d442b9820
--- /dev/null
+++ b/spec/tasks/gitlab/ldap_rake_spec.rb
@@ -0,0 +1,13 @@
+require 'rake_helper'
+
+describe 'gitlab:ldap:rename_provider rake task' do
+ it 'completes without error' do
+ Rake.application.rake_require 'tasks/gitlab/ldap'
+ stub_warn_user_is_not_gitlab
+ ENV['force'] = 'yes'
+
+ create(:identity) # Necessary to prevent `exit 1` from the task.
+
+ run_rake_task('gitlab:ldap:rename_provider', 'ldapmain', 'ldapfoo')
+ end
+end