diff options
author | Lin Jen-Shin <godfat@godfat.org> | 2017-08-28 15:36:29 +0800 |
---|---|---|
committer | Lin Jen-Shin <godfat@godfat.org> | 2017-08-28 15:36:29 +0800 |
commit | ed4f5b97d38ced5cac47d94064ef713b72a8c88d (patch) | |
tree | 9efa51991e78c374b3eec69d84a2a8702c5c1c53 | |
parent | 45aa23a6d142c0cd5e77146057c20d4ffd652c3b (diff) | |
parent | ef8eb3f6f7c1af167017ecc854e9fe385cee9354 (diff) | |
download | gitlab-ce-ed4f5b97d38ced5cac47d94064ef713b72a8c88d.tar.gz |
Merge remote-tracking branch 'upstream/master' into 35642-add-owner-to-triggers-factory35642-add-owner-to-triggers-factory
* upstream/master: (49 commits)
Fire system hooks when a user is created via LDAP or OAuth
Common Docker Documentation Location in `gitlab-ce`
fix deprecation warning present during webpack compiles
Enable 5 lines of Sidekiq backtrace lines to aid in debugging
Add support for copying permalink to notes via more actions dropdown
Docs: update - fix headers
Handle creating a nested group on MySQL correctly
Decrease statuses batch size even more in a migration
Fix failure when issue author is nil
Fix searching for files by path
Fix invite by email address duplication
Revert "Merge branch 'mk-reenable-mysql-tests-on-all-branches' into 'master'"
Fix repo editor scrollbar
Revert "Merge branch 'sh-sidekiq-backtrace' into 'master'"
Replace 'source/search_code.feature' spinach test with an rspec analog
Add missing third argument to `Git::Repository#initialize` in spec
New doc: how to install GitLab on Azure
Authorizations regarding OAuth - style confirmation
Enable 5 lines of Sidekiq backtrace lines to aid in debugging
Reenable MySQL tests on all branches
...
222 files changed, 1615 insertions, 678 deletions
@@ -207,9 +207,6 @@ gem 'kubeclient', '~> 2.2.0' # d3 gem 'd3_rails', '~> 3.5.0' -# underscore-rails -gem 'underscore-rails', '~> 1.8.0' - # Sanitize user input gem 'sanitize', '~> 2.0' gem 'babosa', '~> 1.0.2' @@ -401,7 +398,7 @@ group :ed25519 do end # Gitaly GRPC client -gem 'gitaly', '~> 0.30.0' +gem 'gitaly-proto', '~> 0.31.0', require: 'gitaly' gem 'toml-rb', '~> 0.3.15', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 7d3c53ee010..0fd52337b23 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -275,7 +275,7 @@ GEM po_to_json (>= 1.0.0) rails (>= 3.2.0) gherkin-ruby (0.3.2) - gitaly (0.30.0) + gitaly-proto (0.31.0) google-protobuf (~> 3.1) grpc (~> 1.0) github-linguist (4.7.6) @@ -899,7 +899,6 @@ GEM uglifier (2.7.2) execjs (>= 0.3.0) json (>= 1.8.0) - underscore-rails (1.8.3) unf (0.1.4) unf_ext unf_ext (0.0.7.2) @@ -1019,7 +1018,7 @@ DEPENDENCIES gettext (~> 3.2.2) gettext_i18n_rails (~> 1.8.0) gettext_i18n_rails_js (~> 1.2.0) - gitaly (~> 0.30.0) + gitaly-proto (~> 0.31.0) github-linguist (~> 4.7.0) gitlab-flowdock-git-hook (~> 1.0.1) gitlab-markup (~> 1.5.1) @@ -1163,7 +1162,6 @@ DEPENDENCIES truncato (~> 0.7.8) u2f (~> 0.2.1) uglifier (~> 2.7.2) - underscore-rails (~> 1.8.0) unf (~> 0.1.4) unicorn (~> 5.1.0) unicorn-worker-killer (~> 0.4.4) diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js index 4319bfcc57f..78cb3def879 100644 --- a/app/assets/javascripts/api.js +++ b/app/assets/javascripts/api.js @@ -55,13 +55,18 @@ const Api = { // Return projects list. Filtered by query projects(query, options, callback) { const url = Api.buildUrl(Api.projectsPath); + const defaults = { + search: query, + per_page: 20, + }; + + if (gon.current_user_id) { + defaults.membership = true; + } + return $.ajax({ url, - data: Object.assign({ - search: query, - per_page: 20, - membership: true, - }, options), + data: Object.assign(defaults, options), dataType: 'json', }) .done(projects => callback(projects)); diff --git a/app/assets/javascripts/copy_to_clipboard.js b/app/assets/javascripts/copy_to_clipboard.js index ab9a8e43dd1..1f3c7e1772d 100644 --- a/app/assets/javascripts/copy_to_clipboard.js +++ b/app/assets/javascripts/copy_to_clipboard.js @@ -29,12 +29,14 @@ showTooltip = function(target, title) { var $target = $(target); var originalTitle = $target.data('original-title'); - $target - .attr('title', 'Copied') - .tooltip('fixTitle') - .tooltip('show') - .attr('title', originalTitle) - .tooltip('fixTitle'); + if (!$target.data('hideTooltip')) { + $target + .attr('title', 'Copied') + .tooltip('fixTitle') + .tooltip('show') + .attr('title', originalTitle) + .tooltip('fixTitle'); + } }; $(function() { diff --git a/app/assets/javascripts/users_select.js b/app/assets/javascripts/users_select.js index 16ebf5916dc..a31fedee021 100644 --- a/app/assets/javascripts/users_select.js +++ b/app/assets/javascripts/users_select.js @@ -588,9 +588,10 @@ function UsersSelect(currentUser, els) { if (showEmailUser && data.results.length === 0 && query.term.match(/^[^@]+@[^@]+$/)) { var trimmed = query.term.trim(); emailUser = { - name: "Invite \"" + query.term + "\"", + name: "Invite \"" + query.term + "\" by email", username: trimmed, - id: trimmed + id: trimmed, + invite: true }; data.results.unshift(emailUser); } @@ -642,7 +643,7 @@ UsersSelect.prototype.formatResult = function(user) { } else { avatar = gon.default_avatar_url; } - return "<div class='user-result " + (!user.username ? 'no-username' : void 0) + "'> <div class='user-image'><img class='avatar avatar-inline s32' src='" + avatar + "'></div> <div class='user-name dropdown-menu-user-full-name'>" + user.name + "</div> <div class='user-username dropdown-menu-user-username'>" + ("@" + user.username || "") + "</div> </div>"; + return "<div class='user-result " + (!user.username ? 'no-username' : void 0) + "'> <div class='user-image'><img class='avatar avatar-inline s32' src='" + avatar + "'></div> <div class='user-name dropdown-menu-user-full-name'>" + user.name + "</div> <div class='user-username dropdown-menu-user-username'>" + (!user.invite ? "@" + _.escape(user.username) : "") + "</div> </div>"; }; UsersSelect.prototype.formatSelection = function(user) { diff --git a/app/assets/stylesheets/framework/avatar.scss b/app/assets/stylesheets/framework/avatar.scss index 486d88efbc5..bdcbd4021b3 100644 --- a/app/assets/stylesheets/framework/avatar.scss +++ b/app/assets/stylesheets/framework/avatar.scss @@ -78,7 +78,7 @@ &.s60 { font-size: 32px; line-height: 58px; } &.s70 { font-size: 34px; line-height: 70px; } &.s90 { font-size: 36px; line-height: 88px; } - &.s110 { font-size: 40px; line-height: 108px; font-weight: 300; } + &.s110 { font-size: 40px; line-height: 108px; font-weight: $gl-font-weight-normal; } &.s140 { font-size: 72px; line-height: 138px; } &.s160 { font-size: 96px; line-height: 158px; } } diff --git a/app/assets/stylesheets/framework/badges.scss b/app/assets/stylesheets/framework/badges.scss index 47a8f44c709..6bbe32df772 100644 --- a/app/assets/stylesheets/framework/badges.scss +++ b/app/assets/stylesheets/framework/badges.scss @@ -1,5 +1,5 @@ .badge { - font-weight: normal; + font-weight: $gl-font-weight-normal; background-color: $badge-bg; color: $badge-color; vertical-align: baseline; diff --git a/app/assets/stylesheets/framework/blocks.scss b/app/assets/stylesheets/framework/blocks.scss index 95a08c960ea..b575ec9de18 100644 --- a/app/assets/stylesheets/framework/blocks.scss +++ b/app/assets/stylesheets/framework/blocks.scss @@ -8,7 +8,7 @@ text-align: center; padding: 20px; color: $gl-text-color; - font-weight: normal; + font-weight: $gl-font-weight-normal; font-size: 14px; line-height: 36px; @@ -213,7 +213,7 @@ h1 { display: inline; - font-weight: normal; + font-weight: $gl-font-weight-normal; font-size: 24px; color: $gl-text-color; } diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss index 6eabdc63d9e..b4a6b214e98 100644 --- a/app/assets/stylesheets/framework/buttons.scss +++ b/app/assets/stylesheets/framework/buttons.scss @@ -1,7 +1,7 @@ @mixin btn-default { border-radius: 3px; font-size: $gl-font-size; - font-weight: 400; + font-weight: $gl-font-weight-normal; padding: $gl-vert-padding $gl-btn-padding; &:focus, diff --git a/app/assets/stylesheets/framework/calendar.scss b/app/assets/stylesheets/framework/calendar.scss index 0ded4a3b423..4ce767e4cc4 100644 --- a/app/assets/stylesheets/framework/calendar.scss +++ b/app/assets/stylesheets/framework/calendar.scss @@ -52,13 +52,13 @@ .pika-label { color: $gl-text-color-secondary; font-size: 14px; - font-weight: normal; + font-weight: $gl-font-weight-normal; } th { padding: 2px 0; color: $note-disabled-comment-color; - font-weight: normal; + font-weight: $gl-font-weight-normal; text-transform: lowercase; border-top: 1px solid $calendar-border-color; } @@ -88,7 +88,7 @@ .is-today { .pika-day { color: inherit; - font-weight: normal; + font-weight: $gl-font-weight-normal; } } diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss index 293aa194528..e16fbbf43b5 100644 --- a/app/assets/stylesheets/framework/common.scss +++ b/app/assets/stylesheets/framework/common.scss @@ -36,12 +36,12 @@ color: $common-gray; font-size: 14px; margin-bottom: 12px; - font-weight: normal; + font-weight: $gl-font-weight-normal; line-height: 24px; } .bold { - font-weight: 600; + font-weight: $gl-font-weight-bold; } .tab-content { @@ -89,7 +89,7 @@ hr { } } -.item-title { font-weight: 600; } +.item-title { font-weight: $gl-font-weight-bold; } /** FLASH message **/ .author_link, @@ -118,18 +118,18 @@ table a code { span.update-author { display: block; color: $update-author-color; - font-weight: normal; + font-weight: $gl-font-weight-normal; font-style: italic; strong { - font-weight: bold; + font-weight: $gl-font-weight-bold; font-style: normal; } } .user-mention { color: $user-mention-color; - font-weight: bold; + font-weight: $gl-font-weight-bold; } .field_with_errors { @@ -222,7 +222,7 @@ li.note { text-align: center; background: $error-bg; color: $white-light; - font-weight: bold; + font-weight: $gl-font-weight-bold; a { color: $white-light; @@ -339,7 +339,7 @@ table { .header-with-avatar { h3 { margin: 0; - font-weight: bold; + font-weight: $gl-font-weight-bold; } .username { diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss index 5f270e288ae..a45d5a6dca0 100644 --- a/app/assets/stylesheets/framework/dropdowns.scss +++ b/app/assets/stylesheets/framework/dropdowns.scss @@ -195,7 +195,7 @@ margin-top: 2px; margin-bottom: 0; font-size: 14px; - font-weight: normal; + font-weight: $gl-font-weight-normal; padding: 8px 0; background-color: $white-light; border: 1px solid $dropdown-border-color; @@ -268,7 +268,7 @@ } .dropdown-bold-header { - font-weight: 600; + font-weight: $gl-font-weight-bold; line-height: 22px; padding: 0 16px; } @@ -432,7 +432,7 @@ .dropdown-menu-user-full-name { display: block; - font-weight: 500; + font-weight: $gl-font-weight-normal; line-height: 16px; text-overflow: ellipsis; overflow: hidden; @@ -468,7 +468,7 @@ &.is-indeterminate, &.is-active { - font-weight: 600; + font-weight: $gl-font-weight-bold; color: $gl-text-color; &::before { @@ -502,7 +502,7 @@ position: relative; padding: 2px 25px 10px; margin: 0 10px 10px; - font-weight: 600; + font-weight: $gl-font-weight-bold; line-height: 1; text-align: center; text-overflow: ellipsis; @@ -685,7 +685,7 @@ .dropdown-menu-inner-title { display: block; color: $gl-text-color; - font-weight: 600; + font-weight: $gl-font-weight-bold; } .dropdown-menu-inner-content { diff --git a/app/assets/stylesheets/framework/filters.scss b/app/assets/stylesheets/framework/filters.scss index 8dcaa879b3f..a5d33d410fb 100644 --- a/app/assets/stylesheets/framework/filters.scss +++ b/app/assets/stylesheets/framework/filters.scss @@ -371,7 +371,7 @@ } > .value { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } @@ -452,7 +452,7 @@ .dropdown-light-content { font-size: 14px; - font-weight: 400; + font-weight: $gl-font-weight-normal; } .dropdown-user { diff --git a/app/assets/stylesheets/framework/flash.scss b/app/assets/stylesheets/framework/flash.scss index 38d884bc7eb..e1b086ebb2b 100644 --- a/app/assets/stylesheets/framework/flash.scss +++ b/app/assets/stylesheets/framework/flash.scss @@ -25,7 +25,7 @@ a.flash-action { margin-left: 5px; text-decoration: none; - font-weight: normal; + font-weight: $gl-font-weight-normal; border-bottom: 1px solid; &:hover { diff --git a/app/assets/stylesheets/framework/forms.scss b/app/assets/stylesheets/framework/forms.scss index 61e3897f369..be96c8ee964 100644 --- a/app/assets/stylesheets/framework/forms.scss +++ b/app/assets/stylesheets/framework/forms.scss @@ -32,7 +32,7 @@ label { } &.label-light { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } @@ -73,7 +73,7 @@ label { margin-right: 0; .control-label { - font-weight: bold; + font-weight: $gl-font-weight-bold; padding-top: 4px; } @@ -157,7 +157,7 @@ label { .form-group .control-label, .form-group .control-label-full-width { - font-weight: normal; + font-weight: $gl-font-weight-normal; } .form-control::-webkit-input-placeholder { diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss index b677882eba4..35bd97980e2 100644 --- a/app/assets/stylesheets/framework/header.scss +++ b/app/assets/stylesheets/framework/header.scss @@ -160,7 +160,7 @@ header { li { &.active a { - font-weight: bold; + font-weight: $gl-font-weight-bold; } } } @@ -250,7 +250,7 @@ header { font-size: 18px; line-height: 22px; display: inline-block; - font-weight: normal; + font-weight: $gl-font-weight-normal; color: $gl-text-color; vertical-align: top; white-space: nowrap; @@ -326,7 +326,7 @@ header { .badge { position: inherit; top: -8px; - font-weight: normal; + font-weight: $gl-font-weight-normal; margin-left: -11px; font-size: 11px; color: $white-light; diff --git a/app/assets/stylesheets/framework/lists.scss b/app/assets/stylesheets/framework/lists.scss index df2bf561194..0fb19344510 100644 --- a/app/assets/stylesheets/framework/lists.scss +++ b/app/assets/stylesheets/framework/lists.scss @@ -113,7 +113,7 @@ ul.content-list { } .title { - font-weight: 600; + font-weight: $gl-font-weight-bold; } a { @@ -212,7 +212,7 @@ ul.content-list { } .row-title { - font-weight: 600; + font-weight: $gl-font-weight-bold; } .row-second-line { diff --git a/app/assets/stylesheets/framework/mixins.scss b/app/assets/stylesheets/framework/mixins.scss index 6f91d11b369..d40b65bb2cc 100644 --- a/app/assets/stylesheets/framework/mixins.scss +++ b/app/assets/stylesheets/framework/mixins.scss @@ -43,7 +43,7 @@ background: $gray-light; a { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } diff --git a/app/assets/stylesheets/framework/modal.scss b/app/assets/stylesheets/framework/modal.scss index a28f54936be..5b581780447 100644 --- a/app/assets/stylesheets/framework/modal.scss +++ b/app/assets/stylesheets/framework/modal.scss @@ -8,7 +8,7 @@ } .text-danger { - font-weight: bold; + font-weight: $gl-font-weight-bold; } } @@ -16,6 +16,14 @@ body.modal-open { overflow: hidden; } +.modal-no-backdrop { + @extend .modal-dialog; + + .modal-content { + box-shadow: none; + } +} + @media (min-width: $screen-md-min) { .modal-dialog { width: 860px; diff --git a/app/assets/stylesheets/framework/nav.scss b/app/assets/stylesheets/framework/nav.scss index 071f20fc457..e20108b171b 100644 --- a/app/assets/stylesheets/framework/nav.scss +++ b/app/assets/stylesheets/framework/nav.scss @@ -70,7 +70,7 @@ &.active a { border-bottom: 2px solid $link-underline-blue; color: $black; - font-weight: 600; + font-weight: $gl-font-weight-bold; .badge { color: $black; @@ -352,7 +352,7 @@ z-index: 300; li.active { - font-weight: bold; + font-weight: $gl-font-weight-bold; } } } diff --git a/app/assets/stylesheets/framework/page-header.scss b/app/assets/stylesheets/framework/page-header.scss index f1ecd050a0a..0c879f40930 100644 --- a/app/assets/stylesheets/framework/page-header.scss +++ b/app/assets/stylesheets/framework/page-header.scss @@ -43,7 +43,7 @@ .commit-committer-link, .commit-author-link { color: $gl-text-color; - font-weight: bold; + font-weight: $gl-font-weight-bold; } .commit-info { diff --git a/app/assets/stylesheets/framework/selects.scss b/app/assets/stylesheets/framework/selects.scss index f7a0b355bf1..d93722e2174 100644 --- a/app/assets/stylesheets/framework/selects.scss +++ b/app/assets/stylesheets/framework/selects.scss @@ -76,7 +76,7 @@ } .select2-results li.select2-result-with-children > .select2-result-label { - font-weight: 600; + font-weight: $gl-font-weight-bold; color: $gl-text-color; } @@ -227,7 +227,7 @@ } .group-name { - font-weight: bold; + font-weight: $gl-font-weight-bold; } .group-path { @@ -252,12 +252,12 @@ .namespace-result { .namespace-kind { color: $namespace-kind-color; - font-weight: normal; + font-weight: $gl-font-weight-normal; } .namespace-path { margin-left: 10px; - font-weight: bolder; + font-weight: $gl-font-weight-bold; } } @@ -283,7 +283,7 @@ padding: 0 1px; .select2-match { - font-weight: bold; + font-weight: $gl-font-weight-bold; text-decoration: none; } diff --git a/app/assets/stylesheets/framework/snippets.scss b/app/assets/stylesheets/framework/snippets.scss index 5f7e1b17cc7..30c15c231d5 100644 --- a/app/assets/stylesheets/framework/snippets.scss +++ b/app/assets/stylesheets/framework/snippets.scss @@ -30,7 +30,7 @@ .snippet-title { font-size: 24px; - font-weight: 600; + font-weight: $gl-font-weight-bold; } .snippet-edited-ago { diff --git a/app/assets/stylesheets/framework/tables.scss b/app/assets/stylesheets/framework/tables.scss index 6d9fa74a030..4dd31bf28cd 100644 --- a/app/assets/stylesheets/framework/tables.scss +++ b/app/assets/stylesheets/framework/tables.scss @@ -32,7 +32,7 @@ table { th { background-color: $gray-light; - font-weight: normal; + font-weight: $gl-font-weight-normal; border-bottom: none; &.wide { diff --git a/app/assets/stylesheets/framework/tw_bootstrap.scss b/app/assets/stylesheets/framework/tw_bootstrap.scss index e54cc2866a7..d5c6ddbb4a5 100644 --- a/app/assets/stylesheets/framework/tw_bootstrap.scss +++ b/app/assets/stylesheets/framework/tw_bootstrap.scss @@ -103,7 +103,7 @@ summary { padding: 4px 5px; font-size: 12px; font-style: normal; - font-weight: normal; + font-weight: $gl-font-weight-normal; display: inline-block; &.label-gray { @@ -165,7 +165,7 @@ summary { .panel-heading { padding: 6px 15px; font-size: 13px; - font-weight: normal; + font-weight: $gl-font-weight-normal; a { color: $panel-heading-link-color; diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss index d13f9996518..71eec0e1a5e 100644 --- a/app/assets/stylesheets/framework/typography.scss +++ b/app/assets/stylesheets/framework/typography.scss @@ -74,7 +74,7 @@ h1 { font-size: 1.75em; - font-weight: 600; + font-weight: $gl-font-weight-bold; margin: 24px 0 16px; padding-bottom: 0.3em; border-bottom: 1px solid $white-dark; @@ -87,7 +87,7 @@ h2 { font-size: 1.5em; - font-weight: 600; + font-weight: $gl-font-weight-bold; margin: 24px 0 16px; padding-bottom: 0.3em; border-bottom: 1px solid $white-dark; @@ -280,7 +280,7 @@ body { margin-top: $gl-padding; line-height: 1.3; font-size: 1.25em; - font-weight: 600; + font-weight: $gl-font-weight-bold; &:last-child { margin-bottom: 0; @@ -291,7 +291,7 @@ body { margin-top: 0; line-height: 1.3; font-size: 1.25em; - font-weight: 600; + font-weight: $gl-font-weight-bold; margin: 12px 7px; } @@ -302,11 +302,11 @@ h4, h5, h6 { color: $gl-text-color; - font-weight: 600; + font-weight: $gl-font-weight-bold; } .light-header { - font-weight: 600; + font-weight: $gl-font-weight-bold; } /** CODE **/ diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index 225d116e9c7..8a2e64f7bf5 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -111,6 +111,8 @@ $well-light-text-color: #5b6169; * Text */ $gl-font-size: 14px; +$gl-font-weight-normal: 400; +$gl-font-weight-bold: 600; $gl-text-color: #2e2e2e; $gl-text-color-secondary: #707070; $gl-text-color-tertiary: #949494; diff --git a/app/assets/stylesheets/framework/wells.scss b/app/assets/stylesheets/framework/wells.scss index b1ff2659131..5f9756bf58a 100644 --- a/app/assets/stylesheets/framework/wells.scss +++ b/app/assets/stylesheets/framework/wells.scss @@ -69,7 +69,7 @@ .well-centered { h1 { - font-weight: normal; + font-weight: $gl-font-weight-normal; text-align: center; font-size: 48px; } diff --git a/app/assets/stylesheets/highlight/dark.scss b/app/assets/stylesheets/highlight/dark.scss index 6e3829d994f..f0ac9b46f91 100644 --- a/app/assets/stylesheets/highlight/dark.scss +++ b/app/assets/stylesheets/highlight/dark.scss @@ -204,11 +204,11 @@ $dark-il: #de935f; .cs { color: $dark-cs; } /* Comment.Special */ .gd { color: $dark-gd; } /* Generic.Deleted */ .ge { font-style: italic; } /* Generic.Emph */ - .gh { color: $dark-gh; font-weight: bold; } /* Generic.Heading */ + .gh { color: $dark-gh; font-weight: $gl-font-weight-bold; } /* Generic.Heading */ .gi { color: $dark-gi; } /* Generic.Inserted */ - .gp { color: $dark-gp; font-weight: bold; } /* Generic.Prompt */ - .gs { font-weight: bold; } /* Generic.Strong */ - .gu { color: $dark-gu; font-weight: bold; } /* Generic.Subheading */ + .gp { color: $dark-gp; font-weight: $gl-font-weight-bold; } /* Generic.Prompt */ + .gs { font-weight: $gl-font-weight-bold; } /* Generic.Strong */ + .gu { color: $dark-gu; font-weight: $gl-font-weight-bold; } /* Generic.Subheading */ .kc { color: $dark-kc; } /* Keyword.Constant */ .kd { color: $dark-kd; } /* Keyword.Declaration */ .kn { color: $dark-kn; } /* Keyword.Namespace */ diff --git a/app/assets/stylesheets/highlight/monokai.scss b/app/assets/stylesheets/highlight/monokai.scss index 68eb0c7720f..eba7919ada9 100644 --- a/app/assets/stylesheets/highlight/monokai.scss +++ b/app/assets/stylesheets/highlight/monokai.scss @@ -203,7 +203,7 @@ $monokai-gi: #a6e22e; .c1 { color: $monokai-c1; } /* Comment.Single */ .cs { color: $monokai-cs; } /* Comment.Special */ .ge { font-style: italic; } /* Generic.Emph */ - .gs { font-weight: bold; } /* Generic.Strong */ + .gs { font-weight: $gl-font-weight-bold; } /* Generic.Strong */ .kc { color: $monokai-kc; } /* Keyword.Constant */ .kd { color: $monokai-kd; } /* Keyword.Declaration */ .kn { color: $monokai-kn; } /* Keyword.Namespace */ diff --git a/app/assets/stylesheets/highlight/solarized_dark.scss b/app/assets/stylesheets/highlight/solarized_dark.scss index 2cc968c32f2..ba53ef0352b 100644 --- a/app/assets/stylesheets/highlight/solarized_dark.scss +++ b/app/assets/stylesheets/highlight/solarized_dark.scss @@ -231,7 +231,7 @@ $solarized-dark-il: #2aa198; .gi { color: $solarized-dark-gi; } /* Generic.Inserted */ .go { color: $solarized-dark-go; } /* Generic.Output */ .gp { color: $solarized-dark-gp; } /* Generic.Prompt */ - .gs { color: $solarized-dark-gs; font-weight: bold; } /* Generic.Strong */ + .gs { color: $solarized-dark-gs; font-weight: $gl-font-weight-bold; } /* Generic.Strong */ .gu { color: $solarized-dark-gu; } /* Generic.Subheading */ .gt { color: $solarized-dark-gt; } /* Generic.Traceback */ .kc { color: $solarized-dark-kc; } /* Keyword.Constant */ diff --git a/app/assets/stylesheets/highlight/solarized_light.scss b/app/assets/stylesheets/highlight/solarized_light.scss index b61b85a2cd1..e9fccf1b58a 100644 --- a/app/assets/stylesheets/highlight/solarized_light.scss +++ b/app/assets/stylesheets/highlight/solarized_light.scss @@ -239,7 +239,7 @@ $solarized-light-il: #2aa198; .gi { color: $solarized-light-gi; } /* Generic.Inserted */ .go { color: $solarized-light-go; } /* Generic.Output */ .gp { color: $solarized-light-gp; } /* Generic.Prompt */ - .gs { color: $solarized-light-gs; font-weight: bold; } /* Generic.Strong */ + .gs { color: $solarized-light-gs; font-weight: $gl-font-weight-bold; } /* Generic.Strong */ .gu { color: $solarized-light-gu; } /* Generic.Subheading */ .gt { color: $solarized-light-gt; } /* Generic.Traceback */ .kc { color: $solarized-light-kc; } /* Keyword.Constant */ diff --git a/app/assets/stylesheets/highlight/white.scss b/app/assets/stylesheets/highlight/white.scss index 578f1902cce..65b140cd7f8 100644 --- a/app/assets/stylesheets/highlight/white.scss +++ b/app/assets/stylesheets/highlight/white.scss @@ -211,12 +211,12 @@ $white-gc-bg: #eaf2f5; .hll { background-color: $white-hll-bg; } .c { color: $white-c; font-style: italic; } .err { color: $white-err; background-color: $white-err-bg; } - .k { font-weight: bold; } - .o { font-weight: bold; } + .k { font-weight: $gl-font-weight-bold; } + .o { font-weight: $gl-font-weight-bold; } .cm { color: $white-cm; font-style: italic; } - .cp { color: $white-cp; font-weight: bold; } + .cp { color: $white-cp; font-weight: $gl-font-weight-bold; } .c1 { color: $white-c1; font-style: italic; } - .cs { color: $white-cs; font-weight: bold; font-style: italic; } + .cs { color: $white-cs; font-weight: $gl-font-weight-bold; font-style: italic; } .gd { color: $white-gd; background-color: $white-gd-bg; } .gd .x { color: $white-gd-x; background-color: $white-gd-x-bg; } .ge { font-style: italic; } @@ -226,29 +226,29 @@ $white-gc-bg: #eaf2f5; .gi .x { color: $white-gi-x; background-color: $white-gi-x-bg; } .go { color: $white-go; } .gp { color: $white-gp; } - .gs { font-weight: bold; } - .gu { color: $white-gu; font-weight: bold; } + .gs { font-weight: $gl-font-weight-bold; } + .gu { color: $white-gu; font-weight: $gl-font-weight-bold; } .gt { color: $white-gt; } - .kc { font-weight: bold; } - .kd { font-weight: bold; } - .kn { font-weight: bold; } - .kp { font-weight: bold; } - .kr { font-weight: bold; } - .kt { color: $white-kt; font-weight: bold; } + .kc { font-weight: $gl-font-weight-bold; } + .kd { font-weight: $gl-font-weight-bold; } + .kn { font-weight: $gl-font-weight-bold; } + .kp { font-weight: $gl-font-weight-bold; } + .kr { font-weight: $gl-font-weight-bold; } + .kt { color: $white-kt; font-weight: $gl-font-weight-bold; } .m { color: $white-m; } .s { color: $white-s; } .n { color: $white-n; } .na { color: $white-na; } .nb { color: $white-nb; } - .nc { color: $white-nc; font-weight: bold; } + .nc { color: $white-nc; font-weight: $gl-font-weight-bold; } .no { color: $white-no; } .ni { color: $white-ni; } - .ne { color: $white-ne; font-weight: bold; } - .nf { color: $white-nf; font-weight: bold; } + .ne { color: $white-ne; font-weight: $gl-font-weight-bold; } + .nf { color: $white-nf; font-weight: $gl-font-weight-bold; } .nn { color: $white-nn; } .nt { color: $white-nt; } .nv { color: $white-nv; } - .ow { font-weight: bold; } + .ow { font-weight: $gl-font-weight-bold; } .w { color: $white-w; } .mf { color: $white-mf; } .mh { color: $white-mh; } diff --git a/app/assets/stylesheets/mailers/highlighted_diff_email.scss b/app/assets/stylesheets/mailers/highlighted_diff_email.scss index ea40f449134..fbe538ad1d7 100644 --- a/app/assets/stylesheets/mailers/highlighted_diff_email.scss +++ b/app/assets/stylesheets/mailers/highlighted_diff_email.scss @@ -152,12 +152,12 @@ span.highlight_word { .hll { background-color: $highlighted-hll-bg; } .c { color: $highlighted-c; font-style: italic; } .err { color: $highlighted-err; background-color: $highlighted-err-bg; } -.k { font-weight: bold; } -.o { font-weight: bold; } +.k { font-weight: $gl-font-weight-bold; } +.o { font-weight: $gl-font-weight-bold; } .cm { color: $highlighted-cm; font-style: italic; } -.cp { color: $highlighted-cp; font-weight: bold; } +.cp { color: $highlighted-cp; font-weight: $gl-font-weight-bold; } .c1 { color: $highlighted-c1; font-style: italic; } -.cs { color: $highlighted-cs; font-weight: bold; font-style: italic; } +.cs { color: $highlighted-cs; font-weight: $gl-font-weight-bold; font-style: italic; } .gd { color: $highlighted-gd; background-color: $highlighted-gd-bg; } .gd .x { color: $highlighted-gd; background-color: $highlighted-gd-x-bg; } .ge { font-style: italic; } @@ -167,29 +167,29 @@ span.highlight_word { .gi .x { color: $highlighted-gi; background-color: $highlighted-gi-x-bg; } .go { color: $highlighted-go; } .gp { color: $highlighted-gp; } -.gs { font-weight: bold; } -.gu { color: $highlighted-gu; font-weight: bold; } +.gs { font-weight: $gl-font-weight-bold; } +.gu { color: $highlighted-gu; font-weight: $gl-font-weight-bold; } .gt { color: $highlighted-gt; } -.kc { font-weight: bold; } -.kd { font-weight: bold; } -.kn { font-weight: bold; } -.kp { font-weight: bold; } -.kr { font-weight: bold; } -.kt { color: $highlighted-kt; font-weight: bold; } +.kc { font-weight: $gl-font-weight-bold; } +.kd { font-weight: $gl-font-weight-bold; } +.kn { font-weight: $gl-font-weight-bold; } +.kp { font-weight: $gl-font-weight-bold; } +.kr { font-weight: $gl-font-weight-bold; } +.kt { color: $highlighted-kt; font-weight: $gl-font-weight-bold; } .m { color: $highlighted-m; } .s { color: $highlighted-s; } .n { color: $highlighted-n; } .na { color: $highlighted-na; } .nb { color: $highlighted-nb; } -.nc { color: $highlighted-nc; font-weight: bold; } +.nc { color: $highlighted-nc; font-weight: $gl-font-weight-bold; } .no { color: $highlighted-no; } .ni { color: $highlighted-ni; } -.ne { color: $highlighted-ne; font-weight: bold; } -.nf { color: $highlighted-nf; font-weight: bold; } +.ne { color: $highlighted-ne; font-weight: $gl-font-weight-bold; } +.nf { color: $highlighted-nf; font-weight: $gl-font-weight-bold; } .nn { color: $highlighted-nn; } .nt { color: $highlighted-nt; } .nv { color: $highlighted-nv; } -.ow { font-weight: bold; } +.ow { font-weight: $gl-font-weight-bold; } .w { color: $highlighted-w; } .mf { color: $highlighted-mf; } .mh { color: $highlighted-mh; } diff --git a/app/assets/stylesheets/new_nav.scss b/app/assets/stylesheets/new_nav.scss index 3e2f23e6b2a..54fa4109f8b 100644 --- a/app/assets/stylesheets/new_nav.scss +++ b/app/assets/stylesheets/new_nav.scss @@ -134,7 +134,7 @@ header.navbar-gitlab-new { li { .badge { box-shadow: none; - font-weight: 600; + font-weight: $gl-font-weight-bold; } } } @@ -193,7 +193,7 @@ header.navbar-gitlab-new { &.active > a { box-shadow: inset 0 -3px 0 $indigo-500; color: $white-light; - font-weight: 700; + font-weight: $gl-font-weight-bold; } > a { @@ -371,7 +371,7 @@ header.navbar-gitlab-new { > a { &:last-of-type:not(:first-child) { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } } @@ -411,7 +411,7 @@ header.navbar-gitlab-new { .breadcrumbs-sub-title { margin: 2px 0; font-size: 16px; - font-weight: normal; + font-weight: $gl-font-weight-normal; line-height: 1; ul { @@ -430,7 +430,7 @@ header.navbar-gitlab-new { } &:last-child a { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } diff --git a/app/assets/stylesheets/new_sidebar.scss b/app/assets/stylesheets/new_sidebar.scss index cee5b22adb9..f624b130e19 100644 --- a/app/assets/stylesheets/new_sidebar.scss +++ b/app/assets/stylesheets/new_sidebar.scss @@ -46,7 +46,7 @@ $new-sidebar-collapsed-width: 50px; a { border-bottom: 1px solid $border-color; - font-weight: 600; + font-weight: $gl-font-weight-bold; display: flex; align-items: center; padding: 10px 16px 10px 10px; @@ -70,8 +70,7 @@ $new-sidebar-collapsed-width: 50px; background-color: $white-light; } - .project-title, - .group-title { + .sidebar-context-title { overflow: hidden; text-overflow: ellipsis; } @@ -109,7 +108,7 @@ $new-sidebar-collapsed-width: 50px; } .badge, - .project-title { + .sidebar-context-title { display: none; } @@ -160,7 +159,7 @@ $new-sidebar-collapsed-width: 50px; > a { color: $active-color; - font-weight: 700; + font-weight: $gl-font-weight-bold; } svg { @@ -308,7 +307,7 @@ $new-sidebar-collapsed-width: 50px; .badge { color: $active-color; - font-weight: 600; + font-weight: $gl-font-weight-bold; } .sidebar-sub-level-items { @@ -474,6 +473,6 @@ $new-sidebar-collapsed-width: 50px; border-bottom-color: $active-border; .badge { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss index e5b467a2691..0f3074076ce 100644 --- a/app/assets/stylesheets/pages/boards.scss +++ b/app/assets/stylesheets/pages/boards.scss @@ -471,7 +471,7 @@ padding-right: 35px; > strong { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } } diff --git a/app/assets/stylesheets/pages/builds.scss b/app/assets/stylesheets/pages/builds.scss index 486424fb729..3d04df8d820 100644 --- a/app/assets/stylesheets/pages/builds.scss +++ b/app/assets/stylesheets/pages/builds.scss @@ -277,7 +277,7 @@ } .trigger-build-variable { - font-weight: normal; + font-weight: $gl-font-weight-normal; color: $code-color; } @@ -378,7 +378,7 @@ } &.active { - font-weight: bold; + font-weight: $gl-font-weight-bold; .fa-arrow-right { display: block; diff --git a/app/assets/stylesheets/pages/ci_projects.scss b/app/assets/stylesheets/pages/ci_projects.scss index 7b4eb689f1b..bf6a48889bf 100644 --- a/app/assets/stylesheets/pages/ci_projects.scss +++ b/app/assets/stylesheets/pages/ci_projects.scss @@ -22,7 +22,7 @@ vertical-align: middle !important; a { - font-weight: normal; + font-weight: $gl-font-weight-normal; text-decoration: none; } } diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss index d0d11b4d71c..c051d37aad6 100644 --- a/app/assets/stylesheets/pages/commits.scss +++ b/app/assets/stylesheets/pages/commits.scss @@ -213,7 +213,7 @@ .commit-sha { font-size: 14px; - font-weight: 600; + font-weight: $gl-font-weight-bold; } } @@ -306,7 +306,7 @@ .gpg-popover-status { display: flex; align-items: center; - font-weight: normal; + font-weight: $gl-font-weight-normal; line-height: 1.5; } diff --git a/app/assets/stylesheets/pages/convdev_index.scss b/app/assets/stylesheets/pages/convdev_index.scss index 0413114c279..16702442f50 100644 --- a/app/assets/stylesheets/pages/convdev_index.scss +++ b/app/assets/stylesheets/pages/convdev_index.scss @@ -23,7 +23,7 @@ $space-between-cards: 8px; line-height: 1; color: $gl-text-color-secondary; margin-left: 8px; - font-weight: 500; + font-weight: $gl-font-weight-normal; a { font-size: 18px; @@ -139,7 +139,7 @@ $space-between-cards: 8px; .card-score-value { font-size: 16px; color: $gl-text-color; - font-weight: 500; + font-weight: $gl-font-weight-normal; } .card-score-big { @@ -147,7 +147,7 @@ $space-between-cards: 8px; border-bottom: 1px solid $border-color; font-size: 22px; padding: 10px 0; - font-weight: 500; + font-weight: $gl-font-weight-normal; } .card-buttons { diff --git a/app/assets/stylesheets/pages/cycle_analytics.scss b/app/assets/stylesheets/pages/cycle_analytics.scss index 6753eb08285..2a92673d9fa 100644 --- a/app/assets/stylesheets/pages/cycle_analytics.scss +++ b/app/assets/stylesheets/pages/cycle_analytics.scss @@ -68,7 +68,7 @@ } .stage-name { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } @@ -93,7 +93,7 @@ .header { font-size: 30px; line-height: 38px; - font-weight: normal; + font-weight: $gl-font-weight-normal; margin: 0; } @@ -130,7 +130,7 @@ &.title { line-height: 19px; font-size: 14px; - font-weight: 600; + font-weight: $gl-font-weight-bold; color: $gl-text-color; } @@ -211,7 +211,7 @@ box-shadow: inset 2px 0 0 0 $active-item-blue; .stage-name { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } @@ -404,7 +404,7 @@ color: $gl-link-color; line-height: 1.3; vertical-align: top; - font-weight: normal; + font-weight: $gl-font-weight-normal; } .fa { diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss index 913a1a95dca..8cbf0ec6180 100644 --- a/app/assets/stylesheets/pages/diff.scss +++ b/app/assets/stylesheets/pages/diff.scss @@ -40,7 +40,7 @@ // "Changes suppressed. Click to show." link .show-suppressed-diff { font-size: 110%; - font-weight: bold; + font-weight: $gl-font-weight-bold; } } @@ -104,7 +104,7 @@ a { float: left; width: 35px; - font-weight: normal; + font-weight: $gl-font-weight-normal; &[disabled] { cursor: default; @@ -395,7 +395,7 @@ background-color: transparent; border: 0; color: $gl-link-color; - font-weight: 600; + font-weight: $gl-font-weight-bold; &:hover, &:focus { diff --git a/app/assets/stylesheets/pages/environments.scss b/app/assets/stylesheets/pages/environments.scss index 00ebf4e26ac..a8d2ae0af28 100644 --- a/app/assets/stylesheets/pages/environments.scss +++ b/app/assets/stylesheets/pages/environments.scss @@ -6,7 +6,7 @@ } .environments-folder-name { - font-weight: normal; + font-weight: $gl-font-weight-normal; padding-top: 20px; } @@ -246,13 +246,13 @@ } .text-metric-bold { - font-weight: 600; + font-weight: $gl-font-weight-bold; } .label-axis-text, .text-metric-usage { fill: $black; - font-weight: 500; + font-weight: $gl-font-weight-normal; font-size: 12px; } diff --git a/app/assets/stylesheets/pages/events.scss b/app/assets/stylesheets/pages/events.scss index 4c3fa1fb8d4..1723d716805 100644 --- a/app/assets/stylesheets/pages/events.scss +++ b/app/assets/stylesheets/pages/events.scss @@ -57,7 +57,7 @@ .event-title { @include str-truncated(calc(100% - 174px)); - font-weight: 600; + font-weight: $gl-font-weight-bold; color: $list-text-color; } diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index 49839a9b528..ab5a901da71 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -271,7 +271,7 @@ } .light { - font-weight: normal; + font-weight: $gl-font-weight-normal; } .no-value { @@ -306,7 +306,7 @@ display: block; margin-top: 4px; font-size: 13px; - font-weight: normal; + font-weight: $gl-font-weight-normal; } .hide-expanded { @@ -689,7 +689,7 @@ .issuable-info, .task-status, .issuable-updated-at { - font-weight: normal; + font-weight: $gl-font-weight-normal; color: $gl-text-color-secondary; a { diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss index 8cdb3f34ae5..e2177f96aee 100644 --- a/app/assets/stylesheets/pages/issues.scss +++ b/app/assets/stylesheets/pages/issues.scss @@ -75,7 +75,7 @@ ul.related-merge-requests > li { .merge-requests-title, .related-branches-title { font-size: 16px; - font-weight: 600; + font-weight: $gl-font-weight-bold; } .merge-request-id { @@ -244,7 +244,7 @@ ul.related-merge-requests > li { strong { display: block; - font-weight: 600; + font-weight: $gl-font-weight-bold; } } } diff --git a/app/assets/stylesheets/pages/login.scss b/app/assets/stylesheets/pages/login.scss index 3cbe8dededb..d4dc43035eb 100644 --- a/app/assets/stylesheets/pages/login.scss +++ b/app/assets/stylesheets/pages/login.scss @@ -22,7 +22,7 @@ } h1:first-child { - font-weight: normal; + font-weight: $gl-font-weight-normal; margin-bottom: 0.68em; margin-top: 0; font-size: 34px; @@ -38,7 +38,7 @@ } a { - font-weight: bold; + font-weight: $gl-font-weight-bold; } } @@ -54,7 +54,7 @@ padding: 15px; .login-heading h3 { - font-weight: 300; + font-weight: $gl-font-weight-normal; line-height: 1.5; margin: 0 0 10px; } @@ -186,7 +186,7 @@ } label { - font-weight: normal; + font-weight: $gl-font-weight-normal; } .submit-container { diff --git a/app/assets/stylesheets/pages/members.scss b/app/assets/stylesheets/pages/members.scss index e7c07ef67f0..a385eb359e1 100644 --- a/app/assets/stylesheets/pages/members.scss +++ b/app/assets/stylesheets/pages/members.scss @@ -46,7 +46,7 @@ } strong { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } @@ -221,7 +221,7 @@ } .member { - font-weight: bold; + font-weight: $gl-font-weight-bold; overflow-wrap: break-word; word-break: break-all; } diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index 6bb013cca85..d1678a17aaf 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -197,7 +197,7 @@ @extend .ref-name; color: $gl-text-color; - font-weight: 600; + font-weight: $gl-font-weight-bold; overflow: hidden; word-break: break-all; @@ -228,7 +228,7 @@ .mr-widget-body { h4 { float: left; - font-weight: 600; + font-weight: $gl-font-weight-bold; font-size: 14px; line-height: inherit; margin-top: 0; @@ -239,7 +239,7 @@ } time { - font-weight: normal; + font-weight: $gl-font-weight-normal; } } @@ -249,7 +249,7 @@ } label { - font-weight: normal; + font-weight: $gl-font-weight-normal; } .spacing { @@ -257,12 +257,12 @@ } .bold { - font-weight: 600; + font-weight: $gl-font-weight-bold; color: $gl-gray-light; } .state-label { - font-weight: 600; + font-weight: $gl-font-weight-bold; padding-right: 10px; } @@ -336,7 +336,7 @@ .text { span { - font-weight: 600; + font-weight: $gl-font-weight-bold; } p { @@ -505,7 +505,7 @@ .panel-new-merge-request { .panel-heading { padding: 5px 10px; - font-weight: 600; + font-weight: $gl-font-weight-bold; line-height: 25px; } diff --git a/app/assets/stylesheets/pages/milestone.scss b/app/assets/stylesheets/pages/milestone.scss index 55e0ee1936e..32039936be7 100644 --- a/app/assets/stylesheets/pages/milestone.scss +++ b/app/assets/stylesheets/pages/milestone.scss @@ -7,7 +7,7 @@ padding: 10px 16px; h4 { - font-weight: bold; + font-weight: $gl-font-weight-bold; } .progress { @@ -81,7 +81,7 @@ } .remaining-days strong { - font-weight: normal; + font-weight: $gl-font-weight-normal; } .milestone-stat { diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss index b4468d6d0a2..9558924bbcb 100644 --- a/app/assets/stylesheets/pages/note_form.scss +++ b/app/assets/stylesheets/pages/note_form.scss @@ -188,7 +188,7 @@ .close { color: $white-light; opacity: 0.85; - font-weight: normal; + font-weight: $gl-font-weight-normal; &:hover { opacity: 1; diff --git a/app/assets/stylesheets/pages/pipeline_schedules.scss b/app/assets/stylesheets/pages/pipeline_schedules.scss index dc1654e006e..7e2297c283f 100644 --- a/app/assets/stylesheets/pages/pipeline_schedules.scss +++ b/app/assets/stylesheets/pages/pipeline_schedules.scss @@ -12,7 +12,7 @@ .interval-pattern-form-group { label { margin-right: 10px; - font-weight: normal; + font-weight: $gl-font-weight-normal; &[for='custom'] { margin-right: 0; diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 85d1905ad40..a408bde37d6 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -128,7 +128,7 @@ .branch-commit { .ref-name { - font-weight: bold; + font-weight: $gl-font-weight-bold; max-width: 120px; overflow: hidden; display: inline-block; @@ -272,7 +272,7 @@ .build-name { float: right; - font-weight: 500; + font-weight: $gl-font-weight-normal; } .ci-status-icon-failed svg { @@ -281,7 +281,7 @@ .stage { color: $gl-text-color-secondary; - font-weight: 500; + font-weight: $gl-font-weight-normal; vertical-align: middle; } } @@ -420,7 +420,7 @@ .stage-name { margin: 0 0 15px 10px; - font-weight: bold; + font-weight: $gl-font-weight-bold; width: 176px; white-space: nowrap; overflow: hidden; @@ -580,7 +580,7 @@ vertical-align: bottom; display: inline-block; position: relative; - font-weight: normal; + font-weight: $gl-font-weight-normal; } @mixin mini-pipeline-graph-color($color-light, $color-main, $color-dark) { @@ -724,7 +724,7 @@ button.mini-pipeline-graph-dropdown-toggle { .mini-pipeline-graph-dropdown-item { padding: 3px 7px 4px; clear: both; - font-weight: normal; + font-weight: $gl-font-weight-normal; line-height: 1.428571429; white-space: nowrap; margin: 0 5px; diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss index 14ad06b0ac2..c5d6ff66dd6 100644 --- a/app/assets/stylesheets/pages/profile.scss +++ b/app/assets/stylesheets/pages/profile.scss @@ -83,7 +83,7 @@ &::after { content: "\00B7"; // Middle Dot padding: 0 6px; - font-weight: bold; + font-weight: $gl-font-weight-bold; } &:last-child { @@ -277,7 +277,7 @@ table.u2f-registrations { .oauth-application-show { .scope-name { - font-weight: 600; + font-weight: $gl-font-weight-bold; } .scopes-list { diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index d01326637ea..39c4264e496 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -2,7 +2,7 @@ margin: -16px; .alert-link { - font-weight: normal; + font-weight: $gl-font-weight-normal; } } @@ -114,7 +114,7 @@ margin-top: 10px; margin-bottom: 10px; font-size: 24px; - font-weight: 400; + font-weight: $gl-font-weight-normal; line-height: 1; word-wrap: break-word; @@ -259,7 +259,7 @@ border-width: 1px; border-style: solid; font-size: 13px; - font-weight: 600; + font-weight: $gl-font-weight-bold; line-height: 13px; letter-spacing: .4px; padding: 6px 14px; @@ -309,7 +309,7 @@ } .option-title { - font-weight: normal; + font-weight: $gl-font-weight-normal; display: inline-block; color: $gl-text-color; } @@ -575,7 +575,7 @@ a.deploy-project-label { color: $gl-text-color-tertiary; transform: translateY(-50%); font-size: 12px; - font-weight: bold; + font-weight: $gl-font-weight-bold; line-height: 20px; // Mobile @@ -826,7 +826,7 @@ pre.light-well { .new-protected-tag { label { margin-top: 6px; - font-weight: normal; + font-weight: $gl-font-weight-normal; } } @@ -853,7 +853,7 @@ pre.light-well { } &.is-active { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } @@ -952,7 +952,7 @@ pre.light-well { &::before { font-family: FontAwesome; - font-weight: normal; + font-weight: $gl-font-weight-normal; font-style: normal; } } diff --git a/app/assets/stylesheets/pages/repo.scss b/app/assets/stylesheets/pages/repo.scss index 1f4d4698199..1088eca5322 100644 --- a/app/assets/stylesheets/pages/repo.scss +++ b/app/assets/stylesheets/pages/repo.scss @@ -182,7 +182,6 @@ padding: 5px 10px; position: relative; border-top: 1px solid $white-normal; - margin-top: -5px; } #binary-viewer { @@ -267,7 +266,7 @@ display: inline-block; font-size: 10px; text-transform: uppercase; - font-weight: bold; + font-weight: $gl-font-weight-bold; color: $gray-darkest; white-space: nowrap; overflow: hidden; diff --git a/app/assets/stylesheets/pages/runners.scss b/app/assets/stylesheets/pages/runners.scss index 57c73295d1e..6cac37a4e28 100644 --- a/app/assets/stylesheets/pages/runners.scss +++ b/app/assets/stylesheets/pages/runners.scss @@ -30,7 +30,7 @@ } h4 { - font-weight: normal; + font-weight: $gl-font-weight-normal; } } diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss index b9818ffcf42..8d73246223d 100644 --- a/app/assets/stylesheets/pages/search.scss +++ b/app/assets/stylesheets/pages/search.scss @@ -94,7 +94,7 @@ input[type="checkbox"]:hover { &::before { font-family: FontAwesome; - font-weight: normal; + font-weight: $gl-font-weight-normal; font-style: normal; } } diff --git a/app/assets/stylesheets/pages/sherlock.scss b/app/assets/stylesheets/pages/sherlock.scss index 23a9c2ada80..bfe065dbbaf 100644 --- a/app/assets/stylesheets/pages/sherlock.scss +++ b/app/assets/stylesheets/pages/sherlock.scss @@ -29,5 +29,5 @@ table .sherlock-code { .sherlock-line-samples-table .slow { color: $red-500; - font-weight: bold; + font-weight: $gl-font-weight-bold; } diff --git a/app/assets/stylesheets/pages/todos.scss b/app/assets/stylesheets/pages/todos.scss index d7a9dda3770..5b9fafe31bd 100644 --- a/app/assets/stylesheets/pages/todos.scss +++ b/app/assets/stylesheets/pages/todos.scss @@ -108,14 +108,14 @@ margin: 0; float: none; display: inline-block; - font-weight: normal; + font-weight: $gl-font-weight-normal; padding: 0 5px; line-height: inherit; font-size: 14px; } .action-name { - font-weight: normal; + font-weight: $gl-font-weight-normal; } .todo-body { @@ -262,6 +262,6 @@ } a { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss index 0028e207f3e..224eee90a3f 100644 --- a/app/assets/stylesheets/pages/tree.scss +++ b/app/assets/stylesheets/pages/tree.scss @@ -231,7 +231,7 @@ } .upload-link { - font-weight: normal; + font-weight: $gl-font-weight-normal; color: $md-link-color; } diff --git a/app/assets/stylesheets/pages/ui_dev_kit.scss b/app/assets/stylesheets/pages/ui_dev_kit.scss index 798e060a261..48ac5b21db8 100644 --- a/app/assets/stylesheets/pages/ui_dev_kit.scss +++ b/app/assets/stylesheets/pages/ui_dev_kit.scss @@ -1,7 +1,7 @@ .gitlab-ui-dev-kit { > h2 { margin: 35px 0 20px; - font-weight: bold; + font-weight: $gl-font-weight-bold; } .example { diff --git a/app/assets/stylesheets/pages/wiki.scss b/app/assets/stylesheets/pages/wiki.scss index fa6bdd297eb..b7d4e7bf582 100644 --- a/app/assets/stylesheets/pages/wiki.scss +++ b/app/assets/stylesheets/pages/wiki.scss @@ -37,7 +37,7 @@ } .light { - font-weight: normal; + font-weight: $gl-font-weight-normal; color: $gl-text-color-secondary; } @@ -89,7 +89,7 @@ h3 { font-size: 19px; - font-weight: normal; + font-weight: $gl-font-weight-normal; margin: $gl-padding 0; } } diff --git a/app/assets/stylesheets/pages/xterm.scss b/app/assets/stylesheets/pages/xterm.scss index b085c56390d..c7297a34ad8 100644 --- a/app/assets/stylesheets/pages/xterm.scss +++ b/app/assets/stylesheets/pages/xterm.scss @@ -281,7 +281,7 @@ $xterm-fg-255: #eee; .term-bold { - font-weight: bold; + font-weight: $gl-font-weight-bold; } .term-italic { diff --git a/app/assets/stylesheets/print.scss b/app/assets/stylesheets/print.scss index 113e6e86bb5..b07a5ae22cd 100644 --- a/app/assets/stylesheets/print.scss +++ b/app/assets/stylesheets/print.scss @@ -17,7 +17,7 @@ .wiki h3 { font-size: 18px; - font-weight: bold; + font-weight: 600; } header, diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index 7444826a5d1..9612b8d8514 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -10,6 +10,14 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController end end + if Gitlab::LDAP::Config.enabled? + Gitlab::LDAP::Config.available_servers.each do |server| + define_method server['provider_name'] do + ldap + end + end + end + # Extend the standard message generation to accept our custom exception def failure_message exception = env["omniauth.error"] diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 9e743685d60..be6491d042c 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -5,14 +5,6 @@ class SessionsController < Devise::SessionsController skip_before_action :check_two_factor_requirement, only: [:destroy] - # Explicitly call protect from forgery before anything else. Otherwise the - # CSFR-token might be cleared before authentication is done. This was the case - # when LDAP was enabled and the `OmniauthCallbacksController` is loaded - # - # *Note:* `prepend: true` is the default for rails4, but this will be changed - # to `prepend: false` in rails5. - protect_from_forgery prepend: true, with: :exception - prepend_before_action :check_initial_setup, only: [:new] prepend_before_action :authenticate_with_two_factor, if: :two_factor_enabled?, only: [:create] diff --git a/app/finders/groups_finder.rb b/app/finders/groups_finder.rb index e6fb112e7f2..88d71b0a87b 100644 --- a/app/finders/groups_finder.rb +++ b/app/finders/groups_finder.rb @@ -1,3 +1,19 @@ +# GroupsFinder +# +# Used to filter Groups by a set of params +# +# Arguments: +# current_user - which user is requesting groups +# params: +# owned: boolean +# parent: Group +# all_available: boolean (defaults to true) +# +# Users with full private access can see all groups. The `owned` and `parent` +# params can be used to restrict the groups that are returned. +# +# Anonymous users will never return any `owned` groups. They will return all +# public groups instead, even if `all_available` is set to false. class GroupsFinder < UnionFinder def initialize(current_user = nil, params = {}) @current_user = current_user @@ -16,13 +32,13 @@ class GroupsFinder < UnionFinder attr_reader :current_user, :params def all_groups - groups = [] - - if current_user - groups << Gitlab::GroupHierarchy.new(groups_for_ancestors, groups_for_descendants).all_groups - end - groups << Group.unscoped.public_to_user(current_user) + return [owned_groups] if params[:owned] + return [Group.all] if current_user&.full_private_access? + groups = [] + groups << Gitlab::GroupHierarchy.new(groups_for_ancestors, groups_for_descendants).all_groups if current_user + groups << Group.unscoped.public_to_user(current_user) if include_public_groups? + groups << Group.none if groups.empty? groups end @@ -39,4 +55,12 @@ class GroupsFinder < UnionFinder groups.where(parent: params[:parent]) end + + def owned_groups + current_user&.groups || Group.none + end + + def include_public_groups? + current_user.nil? || params.fetch(:all_available, true) + end end diff --git a/app/helpers/button_helper.rb b/app/helpers/button_helper.rb index bf9ad95b7c2..48cf30a48ab 100644 --- a/app/helpers/button_helper.rb +++ b/app/helpers/button_helper.rb @@ -20,6 +20,9 @@ module ButtonHelper def clipboard_button(data = {}) css_class = data[:class] || 'btn-clipboard btn-transparent' title = data[:title] || 'Copy to clipboard' + button_text = data[:button_text] || '' + hide_tooltip = data[:hide_tooltip] || false + hide_button_icon = data[:hide_button_icon] || false # This supports code in app/assets/javascripts/copy_to_clipboard.js that # works around ClipboardJS limitations to allow the context-specific copy/pasting of plain text or GFM. @@ -35,17 +38,22 @@ module ButtonHelper target = data.delete(:target) data[:clipboard_target] = target if target - data = { toggle: 'tooltip', placement: 'bottom', container: 'body' }.merge(data) + unless hide_tooltip + data = { toggle: 'tooltip', placement: 'bottom', container: 'body' }.merge(data) + end - content_tag :button, - icon('clipboard', 'aria-hidden': 'true'), + button_attributes = { class: "btn #{css_class}", data: data, type: :button, title: title, - aria: { - label: title - } + aria: { label: title } + } + + content_tag :button, button_attributes do + concat(icon('clipboard', 'aria-hidden': 'true')) unless hide_button_icon + concat(button_text) + end end def http_clone_button(project, placement = 'right', append_link: true) diff --git a/app/models/ci/stage.rb b/app/models/ci/stage.rb index 4ee972fa68d..754c37518b3 100644 --- a/app/models/ci/stage.rb +++ b/app/models/ci/stage.rb @@ -17,6 +17,10 @@ module Ci validates :pipeline, presence: true, unless: :importing? validates :name, presence: true, unless: :importing? + after_initialize do |stage| + self.status = DEFAULT_STATUS if self.status.nil? + end + state_machine :status, initial: :created do event :enqueue do transition created: :pending diff --git a/app/models/repository.rb b/app/models/repository.rb index cb2cf658084..9fb2e2aa306 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -1192,7 +1192,7 @@ class Repository end def initialize_raw_repository - Gitlab::Git::Repository.new(project.repository_storage, disk_path + '.git') + Gitlab::Git::Repository.new(project.repository_storage, disk_path + '.git', Gitlab::GlRepository.gl_repository(project, false)) end def circuit_breaker diff --git a/app/services/commits/create_service.rb b/app/services/commits/create_service.rb index c58f04a252b..dbd0b9ef43a 100644 --- a/app/services/commits/create_service.rb +++ b/app/services/commits/create_service.rb @@ -17,7 +17,7 @@ module Commits new_commit = create_commit! success(result: new_commit) - rescue ValidationError, ChangeError, Gitlab::Git::Index::IndexError, Repository::CommitError, GitHooksService::PreReceiveError => ex + rescue ValidationError, ChangeError, Gitlab::Git::Index::IndexError, Repository::CommitError, Gitlab::Git::HooksService::PreReceiveError => ex error(ex.message) end diff --git a/app/services/concerns/users/new_user_notifier.rb b/app/services/concerns/users/new_user_notifier.rb new file mode 100644 index 00000000000..231693ce7a9 --- /dev/null +++ b/app/services/concerns/users/new_user_notifier.rb @@ -0,0 +1,9 @@ +module Users + module NewUserNotifier + def notify_new_user(user, reset_token) + log_info("User \"#{user.name}\" (#{user.email}) was created") + notification_service.new_user(user, reset_token) if reset_token + system_hook_service.execute_hooks_for(user, :create) + end + end +end diff --git a/app/services/create_branch_service.rb b/app/services/create_branch_service.rb index 673ed02f952..0ba6a0ac6b5 100644 --- a/app/services/create_branch_service.rb +++ b/app/services/create_branch_service.rb @@ -14,7 +14,7 @@ class CreateBranchService < BaseService else error('Invalid reference name') end - rescue GitHooksService::PreReceiveError => ex + rescue Gitlab::Git::HooksService::PreReceiveError => ex error(ex.message) end diff --git a/app/services/delete_branch_service.rb b/app/services/delete_branch_service.rb index 64b3c0118fb..1f059c31944 100644 --- a/app/services/delete_branch_service.rb +++ b/app/services/delete_branch_service.rb @@ -16,7 +16,7 @@ class DeleteBranchService < BaseService else error('Failed to remove branch') end - rescue GitHooksService::PreReceiveError => ex + rescue Gitlab::Git::HooksService::PreReceiveError => ex error(ex.message) end diff --git a/app/services/git_hooks_service.rb b/app/services/git_hooks_service.rb deleted file mode 100644 index eab65d09299..00000000000 --- a/app/services/git_hooks_service.rb +++ /dev/null @@ -1,32 +0,0 @@ -class GitHooksService - PreReceiveError = Class.new(StandardError) - - attr_accessor :oldrev, :newrev, :ref - - def execute(user, project, oldrev, newrev, ref) - @project = project - @user = Gitlab::GlId.gl_id(user) - @oldrev = oldrev - @newrev = newrev - @ref = ref - - %w(pre-receive update).each do |hook_name| - status, message = run_hook(hook_name) - - unless status - raise PreReceiveError, message - end - end - - yield(self).tap do - run_hook('post-receive') - end - end - - private - - def run_hook(name) - hook = Gitlab::Git::Hook.new(name, @project) - hook.trigger(@user, oldrev, newrev, ref) - end -end diff --git a/app/services/git_operation_service.rb b/app/services/git_operation_service.rb index 545ca0742e4..6b7a56e6922 100644 --- a/app/services/git_operation_service.rb +++ b/app/services/git_operation_service.rb @@ -1,8 +1,10 @@ class GitOperationService - attr_reader :user, :repository + attr_reader :committer, :repository + + def initialize(committer, new_repository) + committer = Gitlab::Git::Committer.from_user(committer) if committer.is_a?(User) + @committer = committer - def initialize(new_user, new_repository) - @user = new_user @repository = new_repository end @@ -118,9 +120,9 @@ class GitOperationService end def with_hooks(ref, newrev, oldrev) - GitHooksService.new.execute( - user, - repository.project, + Gitlab::Git::HooksService.new.execute( + committer, + repository, oldrev, newrev, ref) do |service| diff --git a/app/services/groups/nested_create_service.rb b/app/services/groups/nested_create_service.rb index 8d793f5c02e..d6f08fc3cce 100644 --- a/app/services/groups/nested_create_service.rb +++ b/app/services/groups/nested_create_service.rb @@ -15,6 +15,10 @@ module Groups return group end + if group_path.include?('/') && !Group.supports_nested_groups? + raise 'Nested groups are not supported on MySQL' + end + create_group_path end diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb index bc846e07f24..5be749cd6a0 100644 --- a/app/services/merge_requests/merge_service.rb +++ b/app/services/merge_requests/merge_service.rb @@ -49,7 +49,7 @@ module MergeRequests raise MergeError, 'Conflicts detected during merge' unless commit_id merge_request.update(merge_commit_sha: commit_id) - rescue GitHooksService::PreReceiveError => e + rescue Gitlab::Git::HooksService::PreReceiveError => e raise MergeError, e.message rescue StandardError => e raise MergeError, "Something went wrong during merge: #{e.message}" diff --git a/app/services/tags/create_service.rb b/app/services/tags/create_service.rb index 674792f6138..b3f4a72d6fe 100644 --- a/app/services/tags/create_service.rb +++ b/app/services/tags/create_service.rb @@ -13,7 +13,7 @@ module Tags new_tag = repository.add_tag(current_user, tag_name, target, message) rescue Rugged::TagError return error("Tag #{tag_name} already exists") - rescue GitHooksService::PreReceiveError => ex + rescue Gitlab::Git::HooksService::PreReceiveError => ex return error(ex.message) end diff --git a/app/services/tags/destroy_service.rb b/app/services/tags/destroy_service.rb index a368f4f5b61..d3d46064729 100644 --- a/app/services/tags/destroy_service.rb +++ b/app/services/tags/destroy_service.rb @@ -21,7 +21,7 @@ module Tags else error('Failed to remove tag') end - rescue GitHooksService::PreReceiveError => ex + rescue Gitlab::Git::HooksService::PreReceiveError => ex error(ex.message) end diff --git a/app/services/users/create_service.rb b/app/services/users/create_service.rb index 74abc017cea..c8a3c461d60 100644 --- a/app/services/users/create_service.rb +++ b/app/services/users/create_service.rb @@ -1,5 +1,7 @@ module Users class CreateService < BaseService + include NewUserNotifier + def initialize(current_user, params = {}) @current_user = current_user @params = params.dup @@ -10,11 +12,7 @@ module Users @reset_token = user.generate_reset_token if user.recently_sent_password_reset? - if user.save - log_info("User \"#{user.name}\" (#{user.email}) was created") - notification_service.new_user(user, @reset_token) if @reset_token - system_hook_service.execute_hooks_for(user, :create) - end + notify_new_user(user, @reset_token) if user.save user end diff --git a/app/services/users/update_service.rb b/app/services/users/update_service.rb index dfbd6016c3f..2f9855273dc 100644 --- a/app/services/users/update_service.rb +++ b/app/services/users/update_service.rb @@ -1,5 +1,7 @@ module Users class UpdateService < BaseService + include NewUserNotifier + def initialize(user, params = {}) @user = user @params = params.dup @@ -10,7 +12,11 @@ module Users assign_attributes(&block) + user_exists = @user.persisted? + if @user.save(validate: validate) + notify_new_user(@user, nil) unless user_exists + success else error(@user.errors.full_messages.uniq.join('. ')) diff --git a/app/services/validate_new_branch_service.rb b/app/services/validate_new_branch_service.rb index d232e85cd33..7d1ed768ee8 100644 --- a/app/services/validate_new_branch_service.rb +++ b/app/services/validate_new_branch_service.rb @@ -13,7 +13,7 @@ class ValidateNewBranchService < BaseService end success - rescue GitHooksService::PreReceiveError => ex + rescue Gitlab::Git::HooksService::PreReceiveError => ex error(ex.message) end end diff --git a/app/views/doorkeeper/authorizations/new.html.haml b/app/views/doorkeeper/authorizations/new.html.haml index 82aa51f9778..8ba88906714 100644 --- a/app/views/doorkeeper/authorizations/new.html.haml +++ b/app/views/doorkeeper/authorizations/new.html.haml @@ -1,39 +1,43 @@ -%h3.page-title Authorization required %main{ :role => "main" } - %p.h4 - Authorize - %strong.text-info= @pre_auth.client.name - to use your account? + .modal-no-backdrop + .modal-content + .modal-header + %h3.page-title + Authorize + = link_to @pre_auth.client.name, @pre_auth.redirect_uri, target: '_blank', rel: 'noopener noreferrer' + to use your account? - - if current_user.admin? - .text-warning.prepend-top-20 - %p - = icon("exclamation-triangle fw") - You are an admin, which means granting access to - %strong= @pre_auth.client.name - will allow them to interact with GitLab as an admin as well. Proceed with caution. - - - if @pre_auth.scopes - #oauth-permissions - %p This application will be able to: - %ul.text-info - - @pre_auth.scopes.each do |scope| - %li= t scope, scope: [:doorkeeper, :scopes] - %hr/ - .actions - = form_tag oauth_authorization_path, method: :post do - = hidden_field_tag :client_id, @pre_auth.client.uid - = hidden_field_tag :redirect_uri, @pre_auth.redirect_uri - = hidden_field_tag :state, @pre_auth.state - = hidden_field_tag :response_type, @pre_auth.response_type - = hidden_field_tag :scope, @pre_auth.scope - = hidden_field_tag :nonce, @pre_auth.nonce - = submit_tag "Authorize", class: "btn btn-success wide pull-left" - = form_tag oauth_authorization_path, method: :delete do - = hidden_field_tag :client_id, @pre_auth.client.uid - = hidden_field_tag :redirect_uri, @pre_auth.redirect_uri - = hidden_field_tag :state, @pre_auth.state - = hidden_field_tag :response_type, @pre_auth.response_type - = hidden_field_tag :scope, @pre_auth.scope - = hidden_field_tag :nonce, @pre_auth.nonce - = submit_tag "Deny", class: "btn btn-danger prepend-left-10" + .modal-body + - if current_user.admin? + .text-warning + %p + = icon("exclamation-triangle fw") + You are an admin, which means granting access to + %strong= @pre_auth.client.name + will allow them to interact with GitLab as an admin as well. Proceed with caution. + %p + You are about to authorize + = link_to @pre_auth.client.name, @pre_auth.redirect_uri, target: '_blank', rel: 'noopener noreferrer' + to use your account. + - if @pre_auth.scopes + This application will be able to: + %ul + - @pre_auth.scopes.each do |scope| + %li= t scope, scope: [:doorkeeper, :scopes] + .form-actions.text-right + = form_tag oauth_authorization_path, method: :delete, class: 'inline' do + = hidden_field_tag :client_id, @pre_auth.client.uid + = hidden_field_tag :redirect_uri, @pre_auth.redirect_uri + = hidden_field_tag :state, @pre_auth.state + = hidden_field_tag :response_type, @pre_auth.response_type + = hidden_field_tag :scope, @pre_auth.scope + = hidden_field_tag :nonce, @pre_auth.nonce + = submit_tag "Deny", class: "btn btn-danger" + = form_tag oauth_authorization_path, method: :post, class: 'inline' do + = hidden_field_tag :client_id, @pre_auth.client.uid + = hidden_field_tag :redirect_uri, @pre_auth.redirect_uri + = hidden_field_tag :state, @pre_auth.state + = hidden_field_tag :response_type, @pre_auth.response_type + = hidden_field_tag :scope, @pre_auth.scope + = hidden_field_tag :nonce, @pre_auth.nonce + = submit_tag "Authorize", class: "btn btn-success prepend-left-10" diff --git a/app/views/layouts/errors.html.haml b/app/views/layouts/errors.html.haml index 6d9ec043590..9382ee8715e 100644 --- a/app/views/layouts/errors.html.haml +++ b/app/views/layouts/errors.html.haml @@ -15,7 +15,7 @@ h1 { font-size: 56px; line-height: 100px; - font-weight: normal; + font-weight: 400; color: #456; } @@ -28,7 +28,7 @@ h3 { color: #456; font-size: 20px; - font-weight: normal; + font-weight: 400; line-height: 28px; } diff --git a/app/views/layouts/nav/_new_admin_sidebar.html.haml b/app/views/layouts/nav/_new_admin_sidebar.html.haml index 3cbcd841aff..1c3fd4a082c 100644 --- a/app/views/layouts/nav/_new_admin_sidebar.html.haml +++ b/app/views/layouts/nav/_new_admin_sidebar.html.haml @@ -4,7 +4,7 @@ = link_to admin_root_path, title: 'Admin Overview' do .avatar-container.s40.settings-avatar = icon('wrench') - .project-title Admin Area + .sidebar-context-title Admin Area %ul.sidebar-top-level-items = nav_link(controller: %w(dashboard admin projects users groups jobs runners cohorts), html_options: {class: 'home'}) do = link_to admin_root_path, title: 'Overview', class: 'shortcuts-tree' do diff --git a/app/views/layouts/nav/_new_group_sidebar.html.haml b/app/views/layouts/nav/_new_group_sidebar.html.haml index ed5793f09fe..d90aea2e361 100644 --- a/app/views/layouts/nav/_new_group_sidebar.html.haml +++ b/app/views/layouts/nav/_new_group_sidebar.html.haml @@ -4,7 +4,7 @@ = link_to group_path(@group), title: @group.name do .avatar-container.s40.group-avatar = image_tag group_icon(@group), class: "avatar s40 avatar-tile" - .group-title + .sidebar-context-title = @group.name %ul.sidebar-top-level-items = nav_link(path: ['groups#show', 'groups#activity', 'groups#subgroups'], html_options: { class: 'home' }) do diff --git a/app/views/layouts/nav/_new_profile_sidebar.html.haml b/app/views/layouts/nav/_new_profile_sidebar.html.haml index 4234df56d1d..85b2c7630c8 100644 --- a/app/views/layouts/nav/_new_profile_sidebar.html.haml +++ b/app/views/layouts/nav/_new_profile_sidebar.html.haml @@ -4,7 +4,7 @@ = link_to profile_path, title: 'Profile Settings' do .avatar-container.s40.settings-avatar = icon('user') - .project-title User Settings + .sidebar-context-title User Settings %ul.sidebar-top-level-items = nav_link(path: 'profiles#show', html_options: {class: 'home'}) do = link_to profile_path, title: 'Profile Settings' do diff --git a/app/views/layouts/nav/_new_project_sidebar.html.haml b/app/views/layouts/nav/_new_project_sidebar.html.haml index 81c84756ff8..341943cf833 100644 --- a/app/views/layouts/nav/_new_project_sidebar.html.haml +++ b/app/views/layouts/nav/_new_project_sidebar.html.haml @@ -5,7 +5,7 @@ = link_to project_path(@project), title: @project.name do .avatar-container.s40.project-avatar = project_icon(@project, alt: @project.name, class: 'avatar s40 avatar-tile') - .project-title + .sidebar-context-title = @project.name %ul.sidebar-top-level-items = nav_link(path: ['projects#show', 'projects#activity', 'cycle_analytics#show'], html_options: { class: 'home' }) do diff --git a/app/views/layouts/oauth_error.html.haml b/app/views/layouts/oauth_error.html.haml index 34bcd2a8b3a..03b387f8181 100644 --- a/app/views/layouts/oauth_error.html.haml +++ b/app/views/layouts/oauth_error.html.haml @@ -19,7 +19,7 @@ h3 { color: #456; font-size: 22px; - font-weight: bold; + font-weight: 600; margin-bottom: 6px; } diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml index ad5befc6ee5..de0f1de057d 100644 --- a/app/views/projects/issues/show.html.haml +++ b/app/views/projects/issues/show.html.haml @@ -32,7 +32,8 @@ %ul - if can_update_issue %li= link_to 'Edit', edit_project_issue_path(@project, @issue) - - unless current_user == @issue.author + / TODO: simplify condition back #36860 + - if @issue.author && current_user != @issue.author %li= link_to 'Report abuse', new_abuse_report_path(user_id: @issue.author.id, ref_url: issue_url(@issue)) - if can_update_issue %li= link_to 'Close issue', issue_path(@issue, issue: { state_event: :close }, format: 'json'), class: "btn-close #{issue_button_visibility(@issue, true)}", title: 'Close issue' diff --git a/app/views/projects/notes/_more_actions_dropdown.html.haml b/app/views/projects/notes/_more_actions_dropdown.html.haml index 5930209a682..7e854186973 100644 --- a/app/views/projects/notes/_more_actions_dropdown.html.haml +++ b/app/views/projects/notes/_more_actions_dropdown.html.haml @@ -6,6 +6,8 @@ %span.icon = custom_icon('ellipsis_v') %ul.dropdown-menu.more-actions-dropdown.dropdown-open-left + %li + = clipboard_button(text: noteable_note_url(note), title: "Copy reference to clipboard", button_text: 'Copy link', hide_tooltip: true, hide_button_icon: true) - unless is_current_user %li = link_to new_abuse_report_path(user_id: note.author.id, ref_url: noteable_note_url(note)) do diff --git a/app/views/projects/pipelines/charts/_pipelines.haml b/app/views/projects/pipelines/charts/_pipelines.haml index 02f1ef4b6da..7a100843f5e 100644 --- a/app/views/projects/pipelines/charts/_pipelines.haml +++ b/app/views/projects/pipelines/charts/_pipelines.haml @@ -14,19 +14,19 @@ .prepend-top-default %p.light - = _("Jobs for last week") + = _("Pipelines for last week") (#{date_from_to(Date.today - 7.days, Date.today)}) %canvas#weekChart{ height: 200 } .prepend-top-default %p.light - = _("Jobs for last month") + = _("Pipelines for last month") (#{date_from_to(Date.today - 30.days, Date.today)}) %canvas#monthChart{ height: 200 } .prepend-top-default %p.light - = _("Jobs for last year") + = _("Pipelines for last year") %canvas#yearChart.padded{ height: 250 } %script#pipelinesChartsData{ type: "application/json" } diff --git a/app/views/search/_form.html.haml b/app/views/search/_form.html.haml index 3139be1cd37..a4a5cec1314 100644 --- a/app/views/search/_form.html.haml +++ b/app/views/search/_form.html.haml @@ -11,5 +11,5 @@ %span.sr-only Clear search - unless params[:snippets].eql? 'true' - = render 'filter' if current_user + = render 'filter' = button_tag "Search", class: "btn btn-success btn-search" diff --git a/app/views/shared/issuable/_close_reopen_button.html.haml b/app/views/shared/issuable/_close_reopen_button.html.haml index 8a1268a1c6d..f22b6c9a6c2 100644 --- a/app/views/shared/issuable/_close_reopen_button.html.haml +++ b/app/views/shared/issuable/_close_reopen_button.html.haml @@ -9,6 +9,7 @@ class: "hidden-xs hidden-sm btn btn-grouped btn-reopen #{issuable_button_visibility(issuable, false)}", title: "Reopen #{display_issuable_type}" - elsif can_update && !is_current_user = render 'shared/issuable/close_reopen_report_toggle', issuable: issuable -- else +- elsif issuable.author + / TODO: change back to else #36860 = link_to 'Report abuse', new_abuse_report_path(user_id: issuable.author.id, ref_url: issuable_url(issuable)), class: 'hidden-xs hidden-sm btn btn-grouped btn-close-color', title: 'Report abuse' diff --git a/app/views/shared/issuable/_close_reopen_report_toggle.html.haml b/app/views/shared/issuable/_close_reopen_report_toggle.html.haml index 6756a7f17fd..daa05990ae9 100644 --- a/app/views/shared/issuable/_close_reopen_report_toggle.html.haml +++ b/app/views/shared/issuable/_close_reopen_report_toggle.html.haml @@ -37,13 +37,15 @@ %li.divider.droplab-item-ignore - %li.report-item{ data: { text: 'Report abuse', url: new_abuse_report_path(user_id: issuable.author.id, ref_url: issuable_url(issuable)), - button_class: "#{button_class} btn-close-color", toggle_class: "#{toggle_class} btn-close-color", method: '' } } - %button.btn.btn-transparent - = icon('check', class: 'icon') - .description - %strong.title Report abuse - %p.text - Report - = display_issuable_type.pluralize - that are abusive, inappropriate or spam. + / TODO: remove condition #36860 + - if issuable.author + %li.report-item{ data: { text: 'Report abuse', url: new_abuse_report_path(user_id: issuable.author.id, ref_url: issuable_url(issuable)), + button_class: "#{button_class} btn-close-color", toggle_class: "#{toggle_class} btn-close-color", method: '' } } + %button.btn.btn-transparent + = icon('check', class: 'icon') + .description + %strong.title Report abuse + %p.text + Report + = display_issuable_type.pluralize + that are abusive, inappropriate or spam. diff --git a/app/workers/concerns/exception_backtrace.rb b/app/workers/concerns/exception_backtrace.rb new file mode 100644 index 00000000000..ea0f1f8d19b --- /dev/null +++ b/app/workers/concerns/exception_backtrace.rb @@ -0,0 +1,8 @@ +# Concern for enabling a few lines of exception backtraces in Sidekiq +module ExceptionBacktrace + extend ActiveSupport::Concern + + included do + sidekiq_options backtrace: 5 + end +end diff --git a/app/workers/group_destroy_worker.rb b/app/workers/group_destroy_worker.rb index 07e82767b06..bd8e212e928 100644 --- a/app/workers/group_destroy_worker.rb +++ b/app/workers/group_destroy_worker.rb @@ -1,6 +1,7 @@ class GroupDestroyWorker include Sidekiq::Worker include DedicatedSidekiqQueue + include ExceptionBacktrace def perform(group_id, user_id) begin diff --git a/app/workers/namespaceless_project_destroy_worker.rb b/app/workers/namespaceless_project_destroy_worker.rb index 1cfb0be759e..f1cd1769421 100644 --- a/app/workers/namespaceless_project_destroy_worker.rb +++ b/app/workers/namespaceless_project_destroy_worker.rb @@ -7,6 +7,7 @@ class NamespacelessProjectDestroyWorker include Sidekiq::Worker include DedicatedSidekiqQueue + include ExceptionBacktrace def self.bulk_perform_async(args_list) Sidekiq::Client.push_bulk('class' => self, 'queue' => sidekiq_options['queue'], 'args' => args_list) diff --git a/app/workers/project_destroy_worker.rb b/app/workers/project_destroy_worker.rb index a9188b78460..3be7e686609 100644 --- a/app/workers/project_destroy_worker.rb +++ b/app/workers/project_destroy_worker.rb @@ -1,6 +1,7 @@ class ProjectDestroyWorker include Sidekiq::Worker include DedicatedSidekiqQueue + include ExceptionBacktrace def perform(project_id, user_id, params) project = Project.find(project_id) diff --git a/app/workers/project_export_worker.rb b/app/workers/project_export_worker.rb index 6009aa1b191..f13ac9e5db2 100644 --- a/app/workers/project_export_worker.rb +++ b/app/workers/project_export_worker.rb @@ -1,6 +1,7 @@ class ProjectExportWorker include Sidekiq::Worker include DedicatedSidekiqQueue + include ExceptionBacktrace sidekiq_options retry: 3 diff --git a/app/workers/repository_import_worker.rb b/app/workers/repository_import_worker.rb index 2c2d1e8b91f..00a021abbdc 100644 --- a/app/workers/repository_import_worker.rb +++ b/app/workers/repository_import_worker.rb @@ -3,6 +3,7 @@ class RepositoryImportWorker include Sidekiq::Worker include DedicatedSidekiqQueue + include ExceptionBacktrace sidekiq_options status_expiration: StuckImportJobsWorker::IMPORT_JOBS_EXPIRATION diff --git a/changelogs/unreleased/31409-fix-group-and-project-search-for-anonymous-users.yml b/changelogs/unreleased/31409-fix-group-and-project-search-for-anonymous-users.yml new file mode 100644 index 00000000000..06e8180db64 --- /dev/null +++ b/changelogs/unreleased/31409-fix-group-and-project-search-for-anonymous-users.yml @@ -0,0 +1,5 @@ +--- +title: Fix group and project search for anonymous users +merge_request: 13745 +author: +type: fixed diff --git a/changelogs/unreleased/35721-auth-style-confirmation.yml b/changelogs/unreleased/35721-auth-style-confirmation.yml new file mode 100644 index 00000000000..9963f76e845 --- /dev/null +++ b/changelogs/unreleased/35721-auth-style-confirmation.yml @@ -0,0 +1,5 @@ +--- +title: restyling of OAuth authorization confirmation +merge_request: +author: Jacopo Beschi @jacopo-beschi +type: changed diff --git a/changelogs/unreleased/35811-copy-link-note.yml b/changelogs/unreleased/35811-copy-link-note.yml new file mode 100644 index 00000000000..9fa74884c8a --- /dev/null +++ b/changelogs/unreleased/35811-copy-link-note.yml @@ -0,0 +1,5 @@ +--- +title: Add support for copying permalink to notes via more actions dropdown +merge_request: 13299 +author: +type: added diff --git a/changelogs/unreleased/36860-deleted-user-fix.yml b/changelogs/unreleased/36860-deleted-user-fix.yml new file mode 100644 index 00000000000..79e75441134 --- /dev/null +++ b/changelogs/unreleased/36860-deleted-user-fix.yml @@ -0,0 +1,5 @@ +--- +title: Fix failure when issue is authored by a deleted user +merge_request: 13807 +author: +type: fixed diff --git a/changelogs/unreleased/36937-fix-invite-by-email-text.yml b/changelogs/unreleased/36937-fix-invite-by-email-text.yml new file mode 100644 index 00000000000..06c6105fab6 --- /dev/null +++ b/changelogs/unreleased/36937-fix-invite-by-email-text.yml @@ -0,0 +1,5 @@ +--- +title: Fix invite by email address duplication +merge_request: +author: +type: fixed diff --git a/changelogs/unreleased/36939-fix-find-blobs-by-path.yml b/changelogs/unreleased/36939-fix-find-blobs-by-path.yml new file mode 100644 index 00000000000..b48b10049ed --- /dev/null +++ b/changelogs/unreleased/36939-fix-find-blobs-by-path.yml @@ -0,0 +1,5 @@ +--- +title: Fix searching for files by path +merge_request: 13798 +author: +type: fixed diff --git a/changelogs/unreleased/docs-document-version-for-group-milestones-api.yml b/changelogs/unreleased/docs-document-version-for-group-milestones-api.yml new file mode 100644 index 00000000000..d75c46313f4 --- /dev/null +++ b/changelogs/unreleased/docs-document-version-for-group-milestones-api.yml @@ -0,0 +1,5 @@ +--- +title: Document version Group Milestones API introduced +merge_request: +author: +type: changed diff --git a/changelogs/unreleased/font-weight-adjusted.yml b/changelogs/unreleased/font-weight-adjusted.yml new file mode 100644 index 00000000000..827f3485099 --- /dev/null +++ b/changelogs/unreleased/font-weight-adjusted.yml @@ -0,0 +1,5 @@ +--- +title: Changed all font-weight values to 400 and 600 and introduced 2 variables to + manage them +merge_request: !12896 +author: diff --git a/changelogs/unreleased/replace_spinach_search_code-feature.yml b/changelogs/unreleased/replace_spinach_search_code-feature.yml new file mode 100644 index 00000000000..28d2108c871 --- /dev/null +++ b/changelogs/unreleased/replace_spinach_search_code-feature.yml @@ -0,0 +1,5 @@ +--- +title: Replace 'source/search_code.feature' spinach test with an rspec analog +merge_request: 13697 +author: blackst0ne +type: other diff --git a/changelogs/unreleased/revert-appearances-description-html-not-null.yml b/changelogs/unreleased/revert-appearances-description-html-not-null.yml new file mode 100644 index 00000000000..4e3c39cb5fd --- /dev/null +++ b/changelogs/unreleased/revert-appearances-description-html-not-null.yml @@ -0,0 +1,5 @@ +--- +title: Re-allow appearances.description_html to be NULL +merge_request: +author: +type: fixed diff --git a/changelogs/unreleased/sh-system-hooks-ldap-users.yml b/changelogs/unreleased/sh-system-hooks-ldap-users.yml new file mode 100644 index 00000000000..87514ec00ea --- /dev/null +++ b/changelogs/unreleased/sh-system-hooks-ldap-users.yml @@ -0,0 +1,5 @@ +--- +title: Fire system hooks when a user is created via LDAP +merge_request: +author: +type: fixed diff --git a/changelogs/unreleased/zj-reword-job-to-pipeline-chart-view.yml b/changelogs/unreleased/zj-reword-job-to-pipeline-chart-view.yml new file mode 100644 index 00000000000..474392a8cdd --- /dev/null +++ b/changelogs/unreleased/zj-reword-job-to-pipeline-chart-view.yml @@ -0,0 +1,5 @@ +--- +title: Reword job to pipeline to reflect what the graphs are really about +merge_request: +author: +type: fixed diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb index 56c279ffcf4..fddb018e948 100644 --- a/config/initializers/omniauth.rb +++ b/config/initializers/omniauth.rb @@ -6,12 +6,6 @@ if Gitlab::LDAP::Config.enabled? const_set(server['provider_class'], Class.new(LDAP)) end end - - OmniauthCallbacksController.class_eval do - Gitlab::LDAP::Config.available_servers.each do |server| - alias_method server['provider_name'], :ldap - end - end end OmniAuth.config.full_host = Settings.gitlab['base_url'] diff --git a/config/webpack.config.js b/config/webpack.config.js index 8aa938d538e..7d63a42d7d8 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -170,7 +170,7 @@ var config = { if (chunk.name) { return chunk.name; } - return chunk.modules.map((m) => { + return chunk.mapModules((m) => { var chunkPath = m.request.split('!').pop(); return path.relative(m.context, chunkPath); }).join('_'); diff --git a/db/fixtures/development/17_cycle_analytics.rb b/db/fixtures/development/17_cycle_analytics.rb index 7c1d758dada..383782112a8 100644 --- a/db/fixtures/development/17_cycle_analytics.rb +++ b/db/fixtures/development/17_cycle_analytics.rb @@ -15,7 +15,7 @@ class Gitlab::Seeder::CycleAnalytics # to disable the `pre_receive` hook in order to remove this # dependency on the GitLab API. def stub_git_pre_receive! - GitHooksService.class_eval do + Gitlab::Git::HooksService.class_eval do def run_hook(name) [true, ''] end diff --git a/db/migrate/20140502125220_migrate_repo_size.rb b/db/migrate/20140502125220_migrate_repo_size.rb index f5d5d834307..ca1b054600c 100644 --- a/db/migrate/20140502125220_migrate_repo_size.rb +++ b/db/migrate/20140502125220_migrate_repo_size.rb @@ -11,7 +11,7 @@ class MigrateRepoSize < ActiveRecord::Migration path = File.join(namespace_path, project['project_path'] + '.git') begin - repo = Gitlab::Git::Repository.new('default', path) + repo = Gitlab::Git::Repository.new('default', path, '') if repo.empty? print '-' else diff --git a/db/migrate/20170809142252_cleanup_appearances_schema.rb b/db/migrate/20170809142252_cleanup_appearances_schema.rb index 90d12925ba2..acf45060114 100644 --- a/db/migrate/20170809142252_cleanup_appearances_schema.rb +++ b/db/migrate/20170809142252_cleanup_appearances_schema.rb @@ -7,7 +7,7 @@ class CleanupAppearancesSchema < ActiveRecord::Migration # Set this constant to true if this migration requires downtime. DOWNTIME = false - NOT_NULL_COLUMNS = %i[title description description_html created_at updated_at] + NOT_NULL_COLUMNS = %i[title description created_at updated_at] TIME_COLUMNS = %i[created_at updated_at] diff --git a/db/migrate/20170824162758_allow_appearances_description_html_null.rb b/db/migrate/20170824162758_allow_appearances_description_html_null.rb new file mode 100644 index 00000000000..d7f481ee894 --- /dev/null +++ b/db/migrate/20170824162758_allow_appearances_description_html_null.rb @@ -0,0 +1,18 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AllowAppearancesDescriptionHtmlNull < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # Set this constant to true if this migration requires downtime. + DOWNTIME = false + + def up + change_column_null :appearances, :description_html, true + end + + def down + # This column should not have a `NOT NULL` class, so we don't want to revert + # back to re-adding it. + end +end diff --git a/db/post_migrate/20170711145558_migrate_stages_statuses.rb b/db/post_migrate/20170711145558_migrate_stages_statuses.rb index 5a24fb1307f..aeb900354db 100644 --- a/db/post_migrate/20170711145558_migrate_stages_statuses.rb +++ b/db/post_migrate/20170711145558_migrate_stages_statuses.rb @@ -6,7 +6,7 @@ class MigrateStagesStatuses < ActiveRecord::Migration disable_ddl_transaction! BATCH_SIZE = 10000 - RANGE_SIZE = 1000 + RANGE_SIZE = 100 MIGRATION = 'MigrateStageStatus'.freeze class Stage < ActiveRecord::Base @@ -17,10 +17,10 @@ class MigrateStagesStatuses < ActiveRecord::Migration def up Stage.where(status: nil).each_batch(of: BATCH_SIZE) do |relation, index| relation.each_batch(of: RANGE_SIZE) do |batch| - range = relation.pluck('MIN(id)', 'MAX(id)').first - schedule = index * 5.minutes + range = batch.pluck('MIN(id)', 'MAX(id)').first + delay = index * 5.minutes - BackgroundMigrationWorker.perform_in(schedule, MIGRATION, range) + BackgroundMigrationWorker.perform_in(delay, MIGRATION, range) end end end diff --git a/db/schema.rb b/db/schema.rb index cd488630237..0f4b0c0c3b3 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170820100558) do +ActiveRecord::Schema.define(version: 20170824162758) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -34,7 +34,7 @@ ActiveRecord::Schema.define(version: 20170820100558) do t.string "logo" t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.text "description_html", null: false + t.text "description_html" t.integer "cached_markdown_version" end diff --git a/doc/administration/auth/authentiq.md b/doc/administration/auth/authentiq.md index 1528f1d2b17..252ff1f4b15 100644 --- a/doc/administration/auth/authentiq.md +++ b/doc/administration/auth/authentiq.md @@ -4,7 +4,7 @@ To enable the Authentiq OmniAuth provider for passwordless authentication you mu Authentiq will generate a Client ID and the accompanying Client Secret for you to use. -1. Get your Client credentials (Client ID and Client Secret) at [Authentiq](https://www.authentiq.com/register). +1. Get your Client credentials (Client ID and Client Secret) at [Authentiq](https://www.authentiq.com/developers). 2. On your GitLab server, open the configuration file: diff --git a/doc/api/group_milestones.md b/doc/api/group_milestones.md index dbfc7529125..a96fb3124fc 100644 --- a/doc/api/group_milestones.md +++ b/doc/api/group_milestones.md @@ -1,5 +1,8 @@ # Group milestones API +> **Notes:** +> [Introduced][ce-12819] in GitLab 9.5. + ## List group milestones Returns a list of group milestones. @@ -118,3 +121,5 @@ Parameters: - `id` (required) - The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user - `milestone_id` (required) - The ID of a group milestone + +[ce-12819]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/12819 diff --git a/doc/api/groups.md b/doc/api/groups.md index 2b3d8e125c8..c2daa8bc029 100644 --- a/doc/api/groups.md +++ b/doc/api/groups.md @@ -2,7 +2,8 @@ ## List groups -Get a list of groups. (As user: my groups or all available, as admin: all groups). +Get a list of visible groups for the authenticated user. When accessed without +authentication, only public groups are returned. Parameters: @@ -43,7 +44,8 @@ You can search for groups by name or path, see below. ## List a group's projects -Get a list of projects in this group. +Get a list of projects in this group. When accessed without authentication, only +public projects are returned. ``` GET /groups/:id/projects @@ -109,7 +111,8 @@ Example response: ## Details of a group -Get all details of a group. +Get all details of a group. This endpoint can be accessed without authentication +if the group is publicly accessible. ``` GET /groups/:id diff --git a/doc/articles/index.md b/doc/articles/index.md index 1aa65504852..4b0c85b9272 100644 --- a/doc/articles/index.md +++ b/doc/articles/index.md @@ -76,7 +76,8 @@ Learn how to deploy a static website with [GitLab Pages](../user/project/pages/i ## Install and maintain GitLab -Install, upgrade, integrate, migrate to GitLab: +[Admin](../README.md#administrator-documentation), [install](../install/README.md), +upgrade, integrate, migrate to GitLab: | Article title | Category | Publishing date | | :------------ | :------: | --------------: | diff --git a/doc/ci/variables/README.md b/doc/ci/variables/README.md index e55a92dbb71..234dc530db0 100644 --- a/doc/ci/variables/README.md +++ b/doc/ci/variables/README.md @@ -86,6 +86,11 @@ To follow conventions of naming across GitLab, and to futher move away from the `build` term and toward `job` CI variables have been renamed for the 9.0 release. +>**Note:** +Starting with GitLab 9.0, we have deprecated the `$CI_BUILD_*` variables. **You are +strongly advised to use the new variables as we will remove the old ones in +future GitLab releases.** + | 8.x name | 9.0+ name | | --------------------- |------------------------ | | `CI_BUILD_ID` | `CI_JOB_ID` | diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index 1869782fe6e..abf4ec7dbf8 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -1065,6 +1065,8 @@ a list of all previous jobs from which the artifacts should be downloaded. You can only define jobs from stages that are executed before the current one. An error will be shown if you define jobs from the current stage or next ones. Defining an empty array will skip downloading any artifacts for that job. +The status of the previous job is not considered when using `dependencies`, so +if it failed or it is a manual job that was not run, no error occurs. --- diff --git a/doc/development/doc_styleguide.md b/doc/development/doc_styleguide.md index 90d1d9657b9..798f40eef3d 100644 --- a/doc/development/doc_styleguide.md +++ b/doc/development/doc_styleguide.md @@ -113,13 +113,12 @@ merge request. ## Links -- If a link makes the paragraph to span across multiple lines, do not use - the regular Markdown approach: `[Text](https://example.com)`. Instead use - `[Text][identifier]` and at the very bottom of the document add: - `[identifier]: https://example.com`. This is another way to create Markdown - links which keeps the document clear and concise. Bonus points if you also - add an alternative text: `[identifier]: https://example.com "Alternative text"` - that appears when hovering your mouse on a link +- Use the regular inline link markdown markup `[Text](https://example.com)`. + It's easier to read, review, and maintain. +- If there's a link that repeats several times through the same document, + you can use `[Text][identifier]` and at the bottom of the section or the + document add: `[identifier]: https://example.com`, in which case, we do + encourage you to also add an alternative text: `[identifier]: https://example.com "Alternative text"` that appears when hovering your mouse on a link. ### Linking to inline docs diff --git a/doc/install/README.md b/doc/install/README.md index bc831a37735..656f8720361 100644 --- a/doc/install/README.md +++ b/doc/install/README.md @@ -17,10 +17,18 @@ the hardware requirements. - [Installation from source](installation.md) - Install GitLab from source. Useful for unsupported systems like *BSD. For an overview of the directory structure, read the [structure documentation](structure.md). -- [Docker](https://docs.gitlab.com/omnibus/docker/) - Install GitLab using Docker. +- [Docker](docker.md) - Install GitLab using Docker. + +## Install GitLab on cloud providers + - [Installing in Kubernetes](kubernetes/index.md) - Install GitLab into a Kubernetes Cluster using our official Helm Chart Repository. -- Testing only! [DigitalOcean and Docker Machine](digitaloceandocker.md) - +- [Install GitLab on OpenShift](../articles/openshift_and_gitlab/index.md) +- [Install GitLab on DC/OS](https://mesosphere.com/blog/gitlab-dcos/) via [GitLab-Mesosphere integration](https://about.gitlab.com/2016/09/16/announcing-gitlab-and-mesosphere/) +- [Install GitLab on Azure](azure/index.md) +- [Install GitLab on Google Cloud Platform](google_cloud_platform/index.md) +- [Install on AWS](https://about.gitlab.com/aws/) +- _Testing only!_ [DigitalOcean and Docker Machine](digitaloceandocker.md) - Quickly test any version of GitLab on DigitalOcean using Docker Machine. ## Database diff --git a/doc/install/azure/img/azure-add-inbound-sec-rule-http.png b/doc/install/azure/img/azure-add-inbound-sec-rule-http.png Binary files differnew file mode 100644 index 00000000000..abf500cb63a --- /dev/null +++ b/doc/install/azure/img/azure-add-inbound-sec-rule-http.png diff --git a/doc/install/azure/img/azure-add-inbound-sec-rule-ssh.png b/doc/install/azure/img/azure-add-inbound-sec-rule-ssh.png Binary files differnew file mode 100644 index 00000000000..f7a8a04dfa7 --- /dev/null +++ b/doc/install/azure/img/azure-add-inbound-sec-rule-ssh.png diff --git a/doc/install/azure/img/azure-create-virtual-machine-basics-password.png b/doc/install/azure/img/azure-create-virtual-machine-basics-password.png Binary files differnew file mode 100644 index 00000000000..80bf39ecb48 --- /dev/null +++ b/doc/install/azure/img/azure-create-virtual-machine-basics-password.png diff --git a/doc/install/azure/img/azure-create-virtual-machine-basics.png b/doc/install/azure/img/azure-create-virtual-machine-basics.png Binary files differnew file mode 100644 index 00000000000..229c073fe17 --- /dev/null +++ b/doc/install/azure/img/azure-create-virtual-machine-basics.png diff --git a/doc/install/azure/img/azure-create-virtual-machine-deployment.png b/doc/install/azure/img/azure-create-virtual-machine-deployment.png Binary files differnew file mode 100644 index 00000000000..5cfdd973a58 --- /dev/null +++ b/doc/install/azure/img/azure-create-virtual-machine-deployment.png diff --git a/doc/install/azure/img/azure-create-virtual-machine-purchase.png b/doc/install/azure/img/azure-create-virtual-machine-purchase.png Binary files differnew file mode 100644 index 00000000000..f4de62299f1 --- /dev/null +++ b/doc/install/azure/img/azure-create-virtual-machine-purchase.png diff --git a/doc/install/azure/img/azure-create-virtual-machine-settings.png b/doc/install/azure/img/azure-create-virtual-machine-settings.png Binary files differnew file mode 100644 index 00000000000..20097921660 --- /dev/null +++ b/doc/install/azure/img/azure-create-virtual-machine-settings.png diff --git a/doc/install/azure/img/azure-create-virtual-machine-size.png b/doc/install/azure/img/azure-create-virtual-machine-size.png Binary files differnew file mode 100644 index 00000000000..a408394151f --- /dev/null +++ b/doc/install/azure/img/azure-create-virtual-machine-size.png diff --git a/doc/install/azure/img/azure-dashboard-highlight-nsg.png b/doc/install/azure/img/azure-dashboard-highlight-nsg.png Binary files differnew file mode 100644 index 00000000000..025efd33977 --- /dev/null +++ b/doc/install/azure/img/azure-dashboard-highlight-nsg.png diff --git a/doc/install/azure/img/azure-dashboard-running-resources.png b/doc/install/azure/img/azure-dashboard-running-resources.png Binary files differnew file mode 100644 index 00000000000..7e661a6aa65 --- /dev/null +++ b/doc/install/azure/img/azure-dashboard-running-resources.png diff --git a/doc/install/azure/img/azure-dashboard.png b/doc/install/azure/img/azure-dashboard.png Binary files differnew file mode 100644 index 00000000000..375ec8622b8 --- /dev/null +++ b/doc/install/azure/img/azure-dashboard.png diff --git a/doc/install/azure/img/azure-inbound-sec-rules-list.png b/doc/install/azure/img/azure-inbound-sec-rules-list.png Binary files differnew file mode 100644 index 00000000000..1667671b21d --- /dev/null +++ b/doc/install/azure/img/azure-inbound-sec-rules-list.png diff --git a/doc/install/azure/img/azure-new-gitlab-ce.png b/doc/install/azure/img/azure-new-gitlab-ce.png Binary files differnew file mode 100644 index 00000000000..88949f69a94 --- /dev/null +++ b/doc/install/azure/img/azure-new-gitlab-ce.png diff --git a/doc/install/azure/img/azure-new-search-gitlab.png b/doc/install/azure/img/azure-new-search-gitlab.png Binary files differnew file mode 100644 index 00000000000..f96ed577d62 --- /dev/null +++ b/doc/install/azure/img/azure-new-search-gitlab.png diff --git a/doc/install/azure/img/azure-nsg-inbound-sec-rules-add-highlight.png b/doc/install/azure/img/azure-nsg-inbound-sec-rules-add-highlight.png Binary files differnew file mode 100644 index 00000000000..c9a08b87ce6 --- /dev/null +++ b/doc/install/azure/img/azure-nsg-inbound-sec-rules-add-highlight.png diff --git a/doc/install/azure/img/azure-nsg-inbound-sec-rules-highlight.png b/doc/install/azure/img/azure-nsg-inbound-sec-rules-highlight.png Binary files differnew file mode 100644 index 00000000000..6423625ca8b --- /dev/null +++ b/doc/install/azure/img/azure-nsg-inbound-sec-rules-highlight.png diff --git a/doc/install/azure/img/azure-vm-domain-name.png b/doc/install/azure/img/azure-vm-domain-name.png Binary files differnew file mode 100644 index 00000000000..01c03004b24 --- /dev/null +++ b/doc/install/azure/img/azure-vm-domain-name.png diff --git a/doc/install/azure/img/azure-vm-management-public-ip.png b/doc/install/azure/img/azure-vm-management-public-ip.png Binary files differnew file mode 100644 index 00000000000..ef313641db8 --- /dev/null +++ b/doc/install/azure/img/azure-vm-management-public-ip.png diff --git a/doc/install/azure/img/azure-vm-management-settings-network-interfaces.png b/doc/install/azure/img/azure-vm-management-settings-network-interfaces.png Binary files differnew file mode 100644 index 00000000000..4ff10718059 --- /dev/null +++ b/doc/install/azure/img/azure-vm-management-settings-network-interfaces.png diff --git a/doc/install/azure/img/azure-vm-management.png b/doc/install/azure/img/azure-vm-management.png Binary files differnew file mode 100644 index 00000000000..a0e0067258c --- /dev/null +++ b/doc/install/azure/img/azure-vm-management.png diff --git a/doc/install/azure/img/gitlab-admin-area-9.4.0.png b/doc/install/azure/img/gitlab-admin-area-9.4.0.png Binary files differnew file mode 100644 index 00000000000..b7ee4598731 --- /dev/null +++ b/doc/install/azure/img/gitlab-admin-area-9.4.0.png diff --git a/doc/install/azure/img/gitlab-admin-area.png b/doc/install/azure/img/gitlab-admin-area.png Binary files differnew file mode 100644 index 00000000000..028f0b0a0eb --- /dev/null +++ b/doc/install/azure/img/gitlab-admin-area.png diff --git a/doc/install/azure/img/gitlab-change-password.png b/doc/install/azure/img/gitlab-change-password.png Binary files differnew file mode 100644 index 00000000000..7350d604d56 --- /dev/null +++ b/doc/install/azure/img/gitlab-change-password.png diff --git a/doc/install/azure/img/gitlab-home.png b/doc/install/azure/img/gitlab-home.png Binary files differnew file mode 100644 index 00000000000..7c935805ea2 --- /dev/null +++ b/doc/install/azure/img/gitlab-home.png diff --git a/doc/install/azure/img/gitlab-login.png b/doc/install/azure/img/gitlab-login.png Binary files differnew file mode 100644 index 00000000000..95fe5aec1e0 --- /dev/null +++ b/doc/install/azure/img/gitlab-login.png diff --git a/doc/install/azure/img/gitlab-new-project.png b/doc/install/azure/img/gitlab-new-project.png Binary files differnew file mode 100644 index 00000000000..3b6b9a81682 --- /dev/null +++ b/doc/install/azure/img/gitlab-new-project.png diff --git a/doc/install/azure/img/gitlab-project-home-empty.png b/doc/install/azure/img/gitlab-project-home-empty.png Binary files differnew file mode 100644 index 00000000000..54d0b36a251 --- /dev/null +++ b/doc/install/azure/img/gitlab-project-home-empty.png diff --git a/doc/install/azure/img/gitlab-project-home-instructions.png b/doc/install/azure/img/gitlab-project-home-instructions.png Binary files differnew file mode 100644 index 00000000000..fd040d33e95 --- /dev/null +++ b/doc/install/azure/img/gitlab-project-home-instructions.png diff --git a/doc/install/azure/img/gitlab-ssh-update-in-progress.png b/doc/install/azure/img/gitlab-ssh-update-in-progress.png Binary files differnew file mode 100644 index 00000000000..8a686ebde26 --- /dev/null +++ b/doc/install/azure/img/gitlab-ssh-update-in-progress.png diff --git a/doc/install/azure/index.md b/doc/install/azure/index.md new file mode 100644 index 00000000000..9cc4b56c932 --- /dev/null +++ b/doc/install/azure/index.md @@ -0,0 +1,439 @@ +# Install GitLab on Microsoft Azure + +> _This article was originally written by Dave Wentzel and [published on the GitLab Blog][Original-Blog-Post]._ +> +> _Ported to the GitLab documentation and updated on 2017-08-24 by [Ian Scorer](https://gitlab.com/iscorer)._ + +Azure is Microsoft's business cloud and GitLab is a pre-configured offering on the Azure Marketplace. +Hopefully, you aren't surprised to hear that Microsoft and Azure have embraced open source software +like Ubuntu, Red Hat Enterprise Linux, and of course - GitLab! This means that you can spin up a +pre-configured GitLab VM and have your very own private GitLab up and running in around 30 minutes. +Let's get started. + +## Getting started + +First, you'll need an account on Azure. There are three ways to do this: + +- If your company (or you) already has an account, then you are ready to go! +- You can also open your own Azure account for free. _At time of writing_, you get $200 +of credit to spend on Azure services for 30 days. You can use this credit to try out paid Azure +services, exploring Microsoft's cloud for free. Even after the first 30 days, you never have to pay +anything unless you decide to transition to paid services with a Pay-As-You-Go Azure subscription. +This is a great way to try out Azure and cloud computing, and you can +[read more in their comprehensive FAQ][Azure-Free-Account-FAQ]. +- If you have an MSDN subscription, you can activate your Azure subscriber benefits. Your MSDN +subscription gives you recurring Azure credits every month, so why not put those credits to use and +try out GitLab right now? + +## Working with Azure + +Once you have an Azure account, you can get started. Login to Azure using +[portal.azure.com](https://portal.azure.com) and the first thing you will see is the Dashboard: + +![Azure Dashboard](img/azure-dashboard.png) + +The Dashboard gives you a quick overview of Azure resources, and from here you you can build VMs, +create SQL Databases, author websites, and perform lots of other cloud tasks. + +## Create New VM + +The [Azure Marketplace][Azure-Marketplace] is an online store for pre-configured applications and +services which have been optimized for the cloud by software vendors like GitLab, and both +the [Community Edition ("CE")][CE] and the [Enterprise Edition ("EE")][EE] versions of GitLab are +available on the Azure Marketplace as pre-configured solutions. + +To begin creating a new GitLab VM, click on the **+ New** icon, type "GitLab" into the search +box, and then click the **"GitLab Community Edition"** search result: + +![Azure - New - Search for 'GitLab'](img/azure-new-search-gitlab.png) + +A new "blade" window will pop-out, where you can read more about the **"GitLab Community Edition"** +offering which is freely available under the MIT Expat License: + +![Azure - New - Select 'GitLab Community Edition'](img/azure-new-gitlab-ce.png) + +Click **"Create"** and you will be presented with the "Create virtual machine" blade: + +![Azure - Create Virtual Machine - Basics](img/azure-create-virtual-machine-basics.png) + +## Basics + +The first items we need to configure are the basic settings of the underlying virtual machine: + +1. Enter a `Name` for the VM - e.g. **"GitLab-CE"** +1. Select a `VM disk type` - either **HDD** _(slower, lower cost)_ or **SSD** _(faster, higher cost)_ +1. Enter a `User name` - e.g. **"gitlab-admin"** +1. Select an `Authentication type`, either **SSH public key** or **Password**: + + >**Note:** if you're unsure which authentication type to use, select **Password** + + 1. If you chose **SSH public key** - enter your `SSH public key` into the field provided + _(read the [SSH documentation][GitLab-Docs-SSH] to learn more about how to setup SSH + public keys)_ + 1. If you chose **Password** - enter the password you wish to use _(this is the password that you + will use later in this tutorial to [SSH] into the VM, so make sure it's a strong password/passphrase)_ +1. Choose the appropriate `Subscription` tier for your Azure account +1. Choose an existing `Resource Group` or create a new one - e.g. **"GitLab-CE-Azure"** +>**Note:** a "Resource group" is a way to group related resources together for easier administration. +We chose "GitLab-CE-Azure", but your resource group can have the same name as your VM. +1. Choose a `Location` - if you're unsure, select the default location + +Here are the settings we've used: + +![Azure - Create Virtual Machine - Basics Completed](img/azure-create-virtual-machine-basics-password.png) + +Check the settings you have entered, and then click **"OK"** when you're ready to proceed. + +## Size + +Next, you need to choose the size of your VM - selecting features such as the number of CPU cores, +the amount of RAM, the size of storage (and its speed), etc. + +>**Note:** in common with other cloud vendors, Azure operates a resource/usage pricing model, i.e. +the more resources your VM consumes the more it will cost you to run, so make your selection +carefully. You'll see that Azure provides an _estimated_ monthly cost beneath each VM Size to help +guide your selection. + +The default size - the lowest cost **"DS1_V2 Standard"** VM - meets the minimum system requirements +to run a small GitLab environment for testing and evaluation purposes, and so we're going to go +ahead and select this one, but please choose the size which best meets your own requirements: + +![Azure - Create Virtual Machine - Size](img/azure-create-virtual-machine-size.png) + +>**Note:** be aware that whilst your VM is active (known as "allocated"), it will incur +"compute charges" which, ultimately, you will be billed for. So, even if you're using the +free trial credits, you'll likely want to learn +[how to properly shutdown an Azure VM to save money][Azure-Properly-Shutdown-VM]. + +Go ahead and click your chosen size, then click **"Select"** when you're ready to proceed to the +next step. + +## Settings + +On the next blade, you're asked to configure the Storage, Network and Extension settings. +We've gone with the default settings as they're sufficient for test-driving GitLab, but please +choose the settings which best meet your own requirements: + +![Azure - Create Virtual Machine - Settings](img/azure-create-virtual-machine-settings.png) + +Review the settings and then click **"OK"** when you're ready to proceed to the last step. + +## Purchase + +The Purchase page is the last step and here you will be presented with the price per hour for your +new VM. You'll be billed only for the VM itself (e.g. "Standard DS1 v2") because the +**"GitLab Community Edition"** marketplace solution is free to use at 0 USD/hr: + +![Azure - Create Virtual Machine - Purchase](img/azure-create-virtual-machine-purchase.png) + +>**Note:** at this stage, you can review and modify the any of the settings you have made during all +previous steps, just click on any of the four steps to re-open them. + +When you have read and agreed to the terms of use and are ready to proceed, click **"Purchase"**. + +## Deployment + +At this point, Azure will begin deploying your new VM. The deployment process will take a few +minutes to complete, with progress displayed on the **"Deployment"** blade: + +![Azure - Create Virtual Machine - Deployment](img/azure-create-virtual-machine-deployment.png) + +Once the deployment process is complete, the new VM and its associated resources will be displayed +on the Azure Dashboard (you may need to refresh the page): + +![Azure - Dashboard - All resources](img/azure-dashboard-running-resources.png) + +The new VM can also be accessed by clicking the `All resources` or `Virtual machines` icons in the +Azure Portal sidebar navigation menu. + +## Setup a domain name + +The VM will have a public IP address (static by default), but Azure allows us to assign a friendly +DNS name to the VM, so let's go ahead and do that. + +From the Dashboard, click on the **"GitLab-CE"** tile to open the management blade for the new VM. +The public IP address that the VM uses is shown in the 'Essentials' section: + +![Azure - VM - Management - Public IP Address](img/azure-vm-management-public-ip.png) + +Click on the public IP address - which should open the **"Public IP address - Configuration"** blade, +then click on **"Configuration"** (under "Settings"). Now enter a friendly DNS name for your instance +in the `DNS name label` field: + +![Azure - VM - Domain Name](img/azure-vm-domain-name.png) + +In the screenshot above, you'll see that we've set the `DNS name label` to **"gitlab-ce-test"**. +This will make our VM accessible at `gitlab-ce-test.centralus.cloudapp.azure.com` +_(the full domain name of your own VM will be different, of course)_. + +Click **"Save"** for the changes to take effect. + +>**Note:** if you want to use your own domain name, you will need to add a DNS `A` record at your +domain registrar which points to the public IP address of your Azure VM. If you do this, you'll need +to make sure your VM is configured to use a _static_ public IP address (i.e. not a _dynamic_ one) +or you will have to reconfigure the DNS `A` record each time Azure reassigns your VM a new public IP +address. Read [IP address types and allocation methods in Azure][Azure-IP-Address-Types] to learn more. + +## Let's open some ports! + +At this stage you should have a running and fully operational VM. However, none of the services on +your VM (e.g. GitLab) will be publicly accessible via the internet until you have opened up the +neccessary ports to enable access to those services. + +Ports are opened by adding _security rules_ to the **"Network security group"** (NSG) which our VM +has been assigned to. If you followed the process above, then Azure will have automatically created +an NSG named `GitLab-CE-nsg` and assigned the `GitLab-CE` VM to it. + +>**Note:** if you gave your VM a different name then the NSG automatically created by Azure will +also have a different name - the name you have your VM, with `-nsg` appended to it. + +You can navigate to the NSG settings via many different routes in the Azure Portal, but one of the +simplest ways is to go to the Azure Dashboard, and then click on the Network Security Group listed +in the **"All resources"** tile: + +![Azure - Dashboard - All resources - Network security group](img/azure-dashboard-highlight-nsg.png) + +With the **"Network security group"** blade open, click on **"Inbound security rules"** under +**"Settings"**: + +![Azure - Network security group - Inbound security rules](img/azure-nsg-inbound-sec-rules-highlight.png) + +Next, click **"Add"**: + +![Azure - Network security group - Inbound security rules - Add](img/azure-nsg-inbound-sec-rules-add-highlight.png) + +### Which ports to open? + +Like all servers, our VM will be running many services. However, we want to open up the correct +ports to enable public internet access to two services in particular: + +1. **HTTP** (port 80) - opening port 80 will enable our VM to respond to HTTP requests, allowing +public access to the instance of GitLab running on our VM. +1. **SSH** (port 22) - opening port 22 will enable our VM to respond to SSH connection requests, +allowing public access (with authentication) to remote terminal sessions +_(you'll see why we need [SSH] access to our VM [later on in this tutorial](#maintaining-your-gitlab-instance))_ + +### Open HTTP on Port 80 + +In the **"Add inbound security rule"** blade, let's open port 80 so that our VM will accept HTTP +connections: + +![Azure - Add inbound security rules - HTTP](img/azure-add-inbound-sec-rule-http.png) + +1. Enter **"HTTP"** in the `Name` field +1. Select **HTTP** from the options in the `Service` drop-down +1. Make sure the `Action` is set to **Allow** +1. Click **"OK"** + +### Open SSH on Port 22 + +Repeat the above process, adding a second Inbound security rule to open port 22, enabling our VM to +accept [SSH] connections: + +![Azure - Add inbound security rules - SSH](img/azure-add-inbound-sec-rule-ssh.png) + +1. Enter **"SSH"** in the `Name` field +1. Select **SSH** from the options in the `Service` drop-down +1. Make sure the `Action` is set to **Allow** +1. Click **"OK"** + + +It will take a moment for Azure to add each new Inbound Security Rule (and you may need to click on +**"Inbound security rules"** to refresh the list), but once completed, you should see the two new +rules in the list: + +![Azure - Inbound security rules - List](img/azure-inbound-sec-rules-list.png) + +## Connecting to GitLab +Use the domain name you set up earlier (or the public IP address) to visit your new GitLab instance +in your browser. If everything has gone according to plan you should be presented with the +following page, asking you to set a _new_ password for the administrator account automatically +created by GitLab: + +![GitLab - Change Password](img/gitlab-change-password.png) + +Enter your _new_ password into both form fields, and then click **"Change your password"**. + +Once you have changed the password you will be redirected to the GitLab login page. Use `root` as +the username, enter the new password you set in the previous step, and then click **"Sign in"**: + +![GitLab - Login](img/gitlab-login.png) + +### Success? + +After signing in successfully, you should see the GitLab Projects page displaying a +**"Welcome to GitLab!"** message: + +![GitLab - Projects Page](img/gitlab-home.png) + +If so, you now have a working GitLab instance on your own private Azure VM. **Congratulations!** + +## Creating your first GitLab project + +You can skip this section if you are familiar with Git and GitLab. Otherwise, let's create our first +project. From the Welcome page, click **"New Project"**. + +Let's give our project a name and a description, and then accept the default values for everything +else: + +1. Enter **"demo"** into the `Project path` project name field +1. Enter a `description`, e.g. **"My awesome demo project!"** +1. Click **"Create project"** + +![GitLab - New Project](img/gitlab-new-project.png) + +Once the new project has been created (which should only take a moment), you'll be redirected to +homepage for the project: + +![GitLab - Empty Project](img/gitlab-project-home-empty.png) + +If you scroll further down the project's home page, you'll see some basic instructions on how to +setup a local clone of your new repository and push and pull from it: + +![GitLab - Empty Project - Basic Instructions](img/gitlab-project-home-instructions.png) + +**That's it! You now have your own private GitLab environment installed and running in the cloud!** + +## Maintaining your GitLab instance + +It's important to keep your GitLab environment up-to-date. The GitLab team is constantly making +enhancements and occasionally you may need to update for security reasons. So let's review how to +update GitLab. + +### Checking our current version + +To check which version of GitLab we're currently running, click on the "Admin Area" link - it's the +the wrench icon displayed in the top-right, next to the search box. + +In the following screenshot you can see an **"update asap"** notification message in the top-right. +This particular message indicates that there is a newer version of GitLab available which contains +one or more security fixes: + +![GitLab - update asap](img/gitlab-admin-area.png) + +Under the **"Components"** section, we can see that our VM is currently running version `8.6.5` of +GitLab. This is the version of GitLab which was contained in the Azure Marketplace +**"GitLab Community Edition"** offering we used to build the VM when we wrote this tutorial. + +>**Note:** The version of GitLab in your own VM instance may well be different, but the update +process will still be the same. + +### Connect via SSH + +To perform an update, we need to connect directly to our Azure VM instance and run some commands +from the terminal. Our Azure VM is actually a server running Linux (Ubuntu), so we'll need to +connect to it using SSH ([Secure Shell][SSH]). + +If you're running Windows, you'll need to connect using [PuTTY] or an equivalent Windows SSH client. +If you're running Linux or macOS, then you already have an SSH client installed. + +>**Note:** +- Remember that you will need to login with the username and password you specified +[when you created](#basics) your Azure VM +- If you need to reset your VM password, read +[how to reset SSH credentials for a user on an Azure VM][Azure-Troubleshoot-SSH-Connection]. + +#### SSH from the command-line + +If you're running [SSH] from the command-line (terminal), then type in the following command to +connect to your VM, substituting `username` and `your-azure-domain-name.com` for the correct values. + +Again, remember that your Azure VM domain name will be the one you +[setup previously in the tutorial](#set-up-a-domain-name). If you didn't setup a domain name for +your VM, you can use the IP address in its place in the following command: + +```bash +ssh username@your-azure-domain-name.com +``` +Provide your password at the prompt to authenticate. + +#### SSH from Windows (PuTTY) + +If you're using [PuTTY] in Windows as your [SSH] client, then you might want to take a quick +read on [using PuTTY in Windows][Using-SSH-In-Putty]. + +### Updating GitLab + +Once you've logged in via SSH, enter the following command to update GitLab to the latest +version: + +```bash +sudo apt-get update && sudo apt-get install gitlab-ce +``` + +This command will update GitLab and its associated components to the latest versions, so it will +take a little time to complete. You'll see various update tasks being completed in your SSH +terminal window: + +![GitLab updating](img/gitlab-ssh-update-in-progress.png) + +Once the update process has completed, you'll see a message like this: + +``` +Upgrade complete! If your GitLab server is misbehaving try running + + sudo gitlab-ctl restart + +before anything else. +``` + +#### Check out your updated GitLab + +Refresh your GitLab instance in the browser and navigate to the Admin Area. You should now have an +up-to-date GitLab instance. + +When we wrote this tutorial our Azure VM GitLab instance was updated to the latest version at time +of writing (`9.4.0`). You can see that the message which was previously displaying **"update asap"** +is now showing **"up-to-date"**: + +![GitLab up to date](img/gitlab-admin-area-9.4.0.png) + +## Conclusion + +Naturally, we believe that GitLab is a great git repository tool. However, GitLab is a whole lot +more than that too. GitLab unifies issues, code review, CI and CD into a single UI, helping you to +move faster from idea to production, and in this tutorial we showed you how quick and easy it is to +setup and run your own instance of GitLab on Azure, Microsoft's cloud service. + +Azure is a great way to experiment with GitLab, and if you decide (as we hope) that GitLab is for +you, you can continue to use Azure as your secure, scalable cloud provider or of course run GitLab +on any cloud service you choose. + +## Where to next? + +Check out our other [Technical Articles][GitLab-Technical-Articles] or browse the [GitLab Documentation][GitLab-Docs] to learn more about GitLab. + +### Useful links + +- [GitLab Community Edition][CE] +- [GitLab Enterprise Edition][EE] +- [Microsoft Azure][Azure] + - [Azure - Free Account FAQ][Azure-Free-Account-FAQ] + - [Azure - Marketplace][Azure-Marketplace] + - [Azure Portal][Azure-Portal] + - [Azure - Pricing Calculator][Azure-Pricing-Calculator] + - [Azure - Troubleshoot SSH Connections to an Azure Linux VM][Azure-Troubleshoot-SSH-Connection] + - [Azure - Properly Shutdown an Azure VM][Azure-Properly-Shutdown-VM] +- [SSH], [PuTTY] and [Using SSH in PuTTY][Using-SSH-In-Putty] + +[Original-Blog-Post]: https://about.gitlab.com/2016/07/13/how-to-setup-a-gitlab-instance-on-microsoft-azure/ "How to Setup a GitLab Instance on Microsoft Azure" +[GitLab-Docs]: https://docs.gitlab.com/ce/README.html "GitLab Documentation" +[GitLab-Technical-Articles]: https://docs.gitlab.com/ce/articles/index.html "GitLab Technical Articles" +[GitLab-Docs-SSH]: https://docs.gitlab.com/ce/ssh/README.html "GitLab Documentation: SSH" +[CE]: https://about.gitlab.com/features/ +[EE]: https://about.gitlab.com/features/#ee-starter + +[Azure-Troubleshoot-Linux-VM]: https://docs.microsoft.com/en-us/azure/virtual-machines/linux/troubleshoot-app-connection "Troubleshoot application connectivity issues on a Linux virtual machine in Azure" +[Azure-IP-Address-Types]: https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-ip-addresses-overview-arm "IP address types and allocation methods in Azure" +[Azure-How-To-Open-Ports]: https://docs.microsoft.com/en-us/azure/virtual-machines/windows/nsg-quickstart-portal "How to open ports to a virtual machine with the Azure portal" +[Azure-Troubleshoot-SSH-Connection]: https://docs.microsoft.com/en-us/azure/virtual-machines/linux/troubleshoot-ssh-connection "Troubleshoot SSH connections to an Azure Linux VM" +[Azure]: https://azure.microsoft.com/en-us/ +[Azure-Free-Account-FAQ]: https://azure.microsoft.com/en-us/free/free-account-faq/ +[Azure-Marketplace]: https://azure.microsoft.com/en-us/marketplace/ +[Azure-Portal]: https://portal.azure.com +[Azure-Pricing-Calculator]: https://azure.microsoft.com/en-us/pricing/calculator/ +[Azure-Properly-Shutdown-VM]: https://buildazure.com/2017/03/16/properly-shutdown-azure-vm-to-save-money/ "Properly Shutdown an Azure VM to Save Money" + +[SSH]: https://en.wikipedia.org/wiki/Secure_Shell +[PuTTY]: http://www.putty.org/ +[Using-SSH-In-Putty]: https://mediatemple.net/community/products/dv/204404604/using-ssh-in-putty-
\ No newline at end of file diff --git a/doc/install/docker.md b/doc/install/docker.md new file mode 100644 index 00000000000..933756072ff --- /dev/null +++ b/doc/install/docker.md @@ -0,0 +1,18 @@ +# GitLab Docker images + +[Docker](https://www.docker.com) and container technology have been revolutionizing the software world for the past few years. They combine the performance and efficiency of native execution with the abstraction, security, and immutability of virtualization. + +GitLab provides official Docker images to allowing you to easily take advantage of the benefits of containerization while operating your GitLab instance. + +## Omnibus GitLab based images + +GitLab maintains a set of [official Docker images](https://hub.docker.com/r/gitlab) based on our [Omnibus GitLab package](https://docs.gitlab.com/omnibus/README.html). These images include: +* [GitLab Community Edition](https://hub.docker.com/r/gitlab/gitlab-ce/) +* [GitLab Enterprise Edition](https://hub.docker.com/r/gitlab/gitlab-ee/) +* [GitLab Runner](https://hub.docker.com/r/gitlab/gitlab-runner/) + +A [complete usage guide](https://docs.gitlab.com/omnibus/docker/) to these images is available, as well as the [Dockerfile used for building the images](https://gitlab.com/gitlab-org/omnibus-gitlab/tree/master/docker). + +## Cloud native images + +GitLab is also working towards a [cloud native set of containers](https://gitlab.com/charts/helm.gitlab.io#docker-container-images), with a single image for each component service. We intend for these images to eventually replace the [Omnibus GitLab based images](#omnibus-gitlab-based-images). diff --git a/doc/user/index.md b/doc/user/index.md index e9ec603f2f1..f239a15d441 100644 --- a/doc/user/index.md +++ b/doc/user/index.md @@ -119,6 +119,13 @@ When performing inline reviews to implementations to your codebase through merge requests you can gather feedback through [resolvable discussions](discussions/index.md#resolvable-discussions). +### GitLab Flavored Markdown (GFM) + +Read through the [GFM documentation](markdown.md) to learn how to apply +the best of GitLab Flavored Markdown in your discussions, comments, +issues and merge requests descriptions, and everywhere else GMF is +supported. + ## Todos Never forget to reply to your collaborators. [GitLab Todos](../workflow/todos.md) diff --git a/docker/README.md b/docker/README.md index f9e12c5733b..61b41d2f109 100644 --- a/docker/README.md +++ b/docker/README.md @@ -1,7 +1,3 @@ # GitLab Docker images -* The official GitLab Community Edition Docker image is [available on Docker Hub](https://hub.docker.com/r/gitlab/gitlab-ce/). -* The official GitLab Enterprise Edition Docker image is [available on Docker Hub](https://hub.docker.com/r/gitlab/gitlab-ee/). -* The complete usage guide can be found in [Using GitLab Docker images](https://docs.gitlab.com/omnibus/docker/) -* The Dockerfile used for building public images is in [Omnibus Repository](https://gitlab.com/gitlab-org/omnibus-gitlab/tree/master/docker) -* Check the guide for [creating Omnibus-based Docker Image](https://docs.gitlab.com/omnibus/build/README.html#build-docker-image) +This content has been moved to [our documentation site](https://docs.gitlab.com/ce/install/docker.html). diff --git a/features/project/source/search_code.feature b/features/project/source/search_code.feature deleted file mode 100644 index 4f9dcea249f..00000000000 --- a/features/project/source/search_code.feature +++ /dev/null @@ -1,15 +0,0 @@ -Feature: Project Source Search Code - Background: - Given I sign in as a user - - Scenario: Search for term "coffee" - Given I own project "Shop" - And I visit project source page - When I search for term "coffee" - Then I should see files from repository containing "coffee" - - Scenario: Search on empty project - Given I own an empty project - And I visit my project's home page - When I search for term "coffee" - Then I should see empty result diff --git a/features/steps/project/graph.rb b/features/steps/project/graph.rb index e78e25318a6..b9cddf4041d 100644 --- a/features/steps/project/graph.rb +++ b/features/steps/project/graph.rb @@ -38,9 +38,9 @@ class Spinach::Features::ProjectGraph < Spinach::FeatureSteps step 'page should have CI graphs' do expect(page).to have_content 'Overall' - expect(page).to have_content 'Jobs for last week' - expect(page).to have_content 'Jobs for last month' - expect(page).to have_content 'Jobs for last year' + expect(page).to have_content 'Pipelines for last week' + expect(page).to have_content 'Pipelines for last month' + expect(page).to have_content 'Pipelines for last year' expect(page).to have_content 'Commit duration in minutes for last 30 commits' end diff --git a/features/steps/project/source/search_code.rb b/features/steps/project/source/search_code.rb deleted file mode 100644 index feee756d7ec..00000000000 --- a/features/steps/project/source/search_code.rb +++ /dev/null @@ -1,19 +0,0 @@ -class Spinach::Features::ProjectSourceSearchCode < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - step 'I search for term "coffee"' do - fill_in "search", with: "coffee" - click_button "Go" - end - - step 'I should see files from repository containing "coffee"' do - expect(page).to have_content 'coffee' - expect(page).to have_content 'CONTRIBUTING.md' - end - - step 'I should see empty result' do - expect(page).to have_content "We couldn't find any" - end -end diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index 830263fd038..be69a96c3ee 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -304,10 +304,6 @@ module SharedPaths visit project_commits_path(@project, 'stable', { limit: 5 }) end - step 'I visit project source page' do - visit project_tree_path(@project, root_ref) - end - step 'I visit blob file from repo' do visit project_blob_path(@project, File.join(sample_commit.id, sample_blob.path)) end diff --git a/lib/api/groups.rb b/lib/api/groups.rb index 49c3b2278c7..e56427304a6 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -2,7 +2,7 @@ module API class Groups < Grape::API include PaginationParams - before { authenticate! } + before { authenticate_non_get! } helpers do params :optional_params_ce do @@ -47,16 +47,8 @@ module API use :pagination end get do - groups = if params[:owned] - current_user.owned_groups - elsif current_user.admin - Group.all - elsif params[:all_available] - GroupsFinder.new(current_user).execute - else - current_user.groups - end - + find_params = { all_available: params[:all_available], owned: params[:owned] } + groups = GroupsFinder.new(current_user, find_params).execute groups = groups.search(params[:search]) if params[:search].present? groups = groups.where.not(id: params[:skip_groups]) if params[:skip_groups].present? groups = groups.reorder(params[:order_by] => params[:sort]) diff --git a/lib/gitlab/file_finder.rb b/lib/gitlab/file_finder.rb index 093d9ed8092..10ffc345bd5 100644 --- a/lib/gitlab/file_finder.rb +++ b/lib/gitlab/file_finder.rb @@ -6,27 +6,48 @@ module Gitlab attr_reader :project, :ref + delegate :repository, to: :project + def initialize(project, ref) @project = project @ref = ref end def find(query) - blobs = project.repository.search_files_by_content(query, ref).first(BATCH_SIZE) - found_file_names = Set.new + by_content = find_by_content(query) - results = blobs.map do |blob| - blob = Gitlab::ProjectSearchResults.parse_search_result(blob) - found_file_names << blob.filename + already_found = Set.new(by_content.map(&:filename)) + by_filename = find_by_filename(query, except: already_found) - [blob.filename, blob] - end + (by_content + by_filename) + .sort_by(&:filename) + .map { |blob| [blob.filename, blob] } + end - project.repository.search_files_by_name(query, ref).first(BATCH_SIZE).each do |filename| - results << [filename, OpenStruct.new(ref: ref)] unless found_file_names.include?(filename) - end + private - results.sort_by(&:first) + def find_by_content(query) + results = repository.search_files_by_content(query, ref).first(BATCH_SIZE) + results.map { |result| Gitlab::ProjectSearchResults.parse_search_result(result) } + end + + def find_by_filename(query, except: []) + filenames = repository.search_files_by_name(query, ref).first(BATCH_SIZE) + filenames.delete_if { |filename| except.include?(filename) } unless except.empty? + + blob_refs = filenames.map { |filename| [ref, filename] } + blobs = Gitlab::Git::Blob.batch(repository, blob_refs, blob_size_limit: 1024) + + blobs.map do |blob| + Gitlab::SearchResults::FoundBlob.new( + id: blob.id, + filename: blob.path, + basename: File.basename(blob.path), + ref: ref, + startline: 1, + data: blob.data + ) + end end end end diff --git a/lib/gitlab/git/committer.rb b/lib/gitlab/git/committer.rb new file mode 100644 index 00000000000..1f4bcf7a3a0 --- /dev/null +++ b/lib/gitlab/git/committer.rb @@ -0,0 +1,21 @@ +module Gitlab + module Git + class Committer + attr_reader :name, :email, :gl_id + + def self.from_user(user) + new(user.name, user.email, Gitlab::GlId.gl_id(user)) + end + + def initialize(name, email, gl_id) + @name = name + @email = email + @gl_id = gl_id + end + + def ==(other) + [name, email, gl_id] == [other.name, other.email, other.gl_id] + end + end + end +end diff --git a/lib/gitlab/git/hook.rb b/lib/gitlab/git/hook.rb index 8f0c377ef4f..cc35d77c6e4 100644 --- a/lib/gitlab/git/hook.rb +++ b/lib/gitlab/git/hook.rb @@ -1,20 +1,23 @@ -# Gitaly note: JV: looks like this is only used by GitHooksService in +# Gitaly note: JV: looks like this is only used by Gitlab::Git::HooksService in # app/services. We shouldn't bother migrating this until we know how -# GitHooksService will be migrated. +# Gitlab::Git::HooksService will be migrated. module Gitlab module Git class Hook GL_PROTOCOL = 'web'.freeze - attr_reader :name, :repo_path, :path + attr_reader :name, :path, :repository - def initialize(name, project) + def initialize(name, repository) @name = name - @project = project - @repo_path = project.repository.path + @repository = repository @path = File.join(repo_path.strip, 'hooks', name) end + def repo_path + repository.path + end + def exists? File.exist?(path) end @@ -44,7 +47,7 @@ module Gitlab 'GL_ID' => gl_id, 'PWD' => repo_path, 'GL_PROTOCOL' => GL_PROTOCOL, - 'GL_REPOSITORY' => Gitlab::GlRepository.gl_repository(@project, false) + 'GL_REPOSITORY' => repository.gl_repository } options = { diff --git a/lib/gitlab/git/hooks_service.rb b/lib/gitlab/git/hooks_service.rb new file mode 100644 index 00000000000..ea8a87a1290 --- /dev/null +++ b/lib/gitlab/git/hooks_service.rb @@ -0,0 +1,36 @@ +module Gitlab + module Git + class HooksService + PreReceiveError = Class.new(StandardError) + + attr_accessor :oldrev, :newrev, :ref + + def execute(committer, repository, oldrev, newrev, ref) + @repository = repository + @gl_id = committer.gl_id + @oldrev = oldrev + @newrev = newrev + @ref = ref + + %w(pre-receive update).each do |hook_name| + status, message = run_hook(hook_name) + + unless status + raise PreReceiveError, message + end + end + + yield(self).tap do + run_hook('post-receive') + end + end + + private + + def run_hook(name) + hook = Gitlab::Git::Hook.new(name, @repository) + hook.trigger(@gl_id, oldrev, newrev, ref) + end + end + end +end diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index 860ed01c05d..b835dec24eb 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -49,13 +49,14 @@ module Gitlab # Rugged repo object attr_reader :rugged - attr_reader :storage + attr_reader :storage, :gl_repository, :relative_path # 'path' must be the path to a _bare_ git repository, e.g. # /path/to/my-repo.git - def initialize(storage, relative_path) + def initialize(storage, relative_path, gl_repository) @storage = storage @relative_path = relative_path + @gl_repository = gl_repository storage_path = Gitlab.config.repositories.storages[@storage]['path'] @path = File.join(storage_path, @relative_path) diff --git a/locale/gitlab.pot b/locale/gitlab.pot index a4a3ef6c42c..5a1db208d5a 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: gitlab 1.0.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-08-18 14:15+0530\n" -"PO-Revision-Date: 2017-08-18 14:15+0530\n" +"POT-Creation-Date: 2017-08-24 09:29+0200\n" +"PO-Revision-Date: 2017-08-24 09:29+0200\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" "Language: \n" @@ -517,15 +517,6 @@ msgstr "" msgid "Issue events" msgstr "" -msgid "Jobs for last month" -msgstr "" - -msgid "Jobs for last week" -msgstr "" - -msgid "Jobs for last year" -msgstr "" - msgid "LFSStatus|Disabled" msgstr "" @@ -766,6 +757,15 @@ msgstr "" msgid "Pipelines charts" msgstr "" +msgid "Pipelines for last month" +msgstr "" + +msgid "Pipelines for last week" +msgstr "" + +msgid "Pipelines for last year" +msgstr "" + msgid "Pipeline|all" msgstr "" diff --git a/public/404.html b/public/404.html index 03e98e81862..4db72be6f8c 100644 --- a/public/404.html +++ b/public/404.html @@ -15,7 +15,7 @@ h1 { font-size: 56px; line-height: 100px; - font-weight: normal; + font-weight: 400; color: #456; } @@ -28,7 +28,7 @@ h3 { color: #456; font-size: 20px; - font-weight: normal; + font-weight: 400; line-height: 28px; } @@ -48,7 +48,7 @@ a { line-height: 100px; - font-weight: normal; + font-weight: 400; color: #4A8BEE; font-size: 18px; text-decoration: none; diff --git a/public/422.html b/public/422.html index 49ebbe40f39..a67dcd02200 100644 --- a/public/422.html +++ b/public/422.html @@ -15,7 +15,7 @@ h1 { font-size: 56px; line-height: 100px; - font-weight: normal; + font-weight: 400; color: #456; } @@ -28,7 +28,7 @@ h3 { color: #456; font-size: 20px; - font-weight: normal; + font-weight: 400; line-height: 28px; } @@ -48,7 +48,7 @@ a { line-height: 100px; - font-weight: normal; + font-weight: 400; color: #4A8BEE; font-size: 18px; text-decoration: none; diff --git a/public/500.html b/public/500.html index 516920f7471..7091d14dfc4 100644 --- a/public/500.html +++ b/public/500.html @@ -15,7 +15,7 @@ h1 { font-size: 56px; line-height: 100px; - font-weight: normal; + font-weight: 400; color: #456; } @@ -28,7 +28,7 @@ h3 { color: #456; font-size: 20px; - font-weight: normal; + font-weight: 400; line-height: 28px; } @@ -48,7 +48,7 @@ a { line-height: 100px; - font-weight: normal; + font-weight: 400; color: #4A8BEE; font-size: 18px; text-decoration: none; diff --git a/public/502.html b/public/502.html index 189458c9816..82afd273248 100644 --- a/public/502.html +++ b/public/502.html @@ -15,7 +15,7 @@ h1 { font-size: 56px; line-height: 100px; - font-weight: normal; + font-weight: 400; color: #456; } @@ -28,7 +28,7 @@ h3 { color: #456; font-size: 20px; - font-weight: normal; + font-weight: 400; line-height: 28px; } @@ -48,7 +48,7 @@ a { line-height: 100px; - font-weight: normal; + font-weight: 400; color: #4A8BEE; font-size: 18px; text-decoration: none; diff --git a/public/503.html b/public/503.html index b09b0e2a67e..f1486bc3e84 100644 --- a/public/503.html +++ b/public/503.html @@ -15,7 +15,7 @@ h1 { font-size: 56px; line-height: 100px; - font-weight: normal; + font-weight: 400; color: #456; } @@ -28,7 +28,7 @@ h3 { color: #456; font-size: 20px; - font-weight: normal; + font-weight: 400; line-height: 28px; } @@ -48,7 +48,7 @@ a { line-height: 100px; - font-weight: normal; + font-weight: 400; color: #4A8BEE; font-size: 18px; text-decoration: none; diff --git a/public/deploy.html b/public/deploy.html index 49ec4ac5ce1..e463b62520c 100644 --- a/public/deploy.html +++ b/public/deploy.html @@ -20,7 +20,7 @@ h1 { font-size: 56px; line-height: 100px; - font-weight: normal; + font-weight: 400; color: #456; } @@ -33,7 +33,7 @@ h3 { color: #456; font-size: 20px; - font-weight: normal; + font-weight: 400; line-height: 28px; } @@ -66,4 +66,4 @@ <p>Please contact your GitLab administrator if this problem persists.</p> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/spec/features/issues/issue_detail_spec.rb b/spec/features/issues/issue_detail_spec.rb index 28b636f9359..c470cb7c716 100644 --- a/spec/features/issues/issue_detail_spec.rb +++ b/spec/features/issues/issue_detail_spec.rb @@ -40,4 +40,18 @@ feature 'Issue Detail', :js do end end end + + context 'when authored by a user who is later deleted' do + before do + issue.update_attribute(:author_id, nil) + sign_in(user) + visit project_issue_path(project, issue) + end + + it 'shows the issue' do + page.within('.issuable-details') do + expect(find('h2')).to have_content(issue.title) + end + end + end end diff --git a/spec/features/projects/files/find_files_spec.rb b/spec/features/projects/files/find_files_spec.rb deleted file mode 100644 index 57d67b28920..00000000000 --- a/spec/features/projects/files/find_files_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -require 'spec_helper' - -feature 'Find files button in the tree header' do - given(:user) { create(:user) } - given(:project) { create(:project, :repository) } - - background do - sign_in(user) - project.team << [user, :developer] - end - - scenario 'project main screen' do - visit project_path(project) - - expect(page).to have_selector('.tree-controls .shortcuts-find-file') - end - - scenario 'project tree screen' do - visit project_tree_path(project, project.default_branch) - - expect(page).to have_selector('.tree-controls .shortcuts-find-file') - end -end diff --git a/spec/features/projects/files/user_searches_for_files_spec.rb b/spec/features/projects/files/user_searches_for_files_spec.rb new file mode 100644 index 00000000000..a105685bca7 --- /dev/null +++ b/spec/features/projects/files/user_searches_for_files_spec.rb @@ -0,0 +1,58 @@ +require 'spec_helper' + +describe 'User searches for files' do + let(:user) { create(:user) } + let(:project) { create(:project, :repository) } + + before do + sign_in(user) + end + + describe 'project main screen' do + context 'when project is empty' do + let(:empty_project) { create(:project) } + + before do + empty_project.add_developer(user) + visit project_path(empty_project) + end + + it 'does not show any result' do + fill_in('search', with: 'coffee') + click_button('Go') + + expect(page).to have_content("We couldn't find any") + end + end + + context 'when project is not empty' do + before do + project.add_developer(user) + visit project_path(project) + end + + it 'shows "Find file" button' do + expect(page).to have_selector('.tree-controls .shortcuts-find-file') + end + end + end + + describe 'project tree screen' do + before do + project.add_developer(user) + visit project_tree_path(project, project.default_branch) + end + + it 'shows "Find file" button' do + expect(page).to have_selector('.tree-controls .shortcuts-find-file') + end + + it 'shows found files' do + fill_in('search', with: 'coffee') + click_button('Go') + + expect(page).to have_content('coffee') + expect(page).to have_content('CONTRIBUTING.md') + end + end +end diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb index 9f2c86923b7..2eb6fab129d 100644 --- a/spec/features/projects/import_export/import_file_spec.rb +++ b/spec/features/projects/import_export/import_file_spec.rb @@ -99,6 +99,6 @@ feature 'Import/Export - project import integration test', js: true do end def project_hook_exists?(project) - Gitlab::Git::Hook.new('post-receive', project).exists? + Gitlab::Git::Hook.new('post-receive', project.repository.raw_repository).exists? end end diff --git a/spec/features/search_spec.rb b/spec/features/search_spec.rb index 6742d77937f..31d509455ba 100644 --- a/spec/features/search_spec.rb +++ b/spec/features/search_spec.rb @@ -281,4 +281,30 @@ describe "Search" do expect(page).to have_selector('.commit-row-description', count: 9) end end + + context 'anonymous user' do + let(:project) { create(:project, :public) } + + before do + sign_out(user) + end + + it 'preserves the group being searched in' do + visit search_path(group_id: project.namespace.id) + + fill_in 'search', with: 'foo' + click_button 'Search' + + expect(find('#group_id').value).to eq(project.namespace.id.to_s) + end + + it 'preserves the project being searched in' do + visit search_path(project_id: project.id) + + fill_in 'search', with: 'foo' + click_button 'Search' + + expect(find('#project_id').value).to eq(project.id.to_s) + end + end end diff --git a/spec/features/tags/master_deletes_tag_spec.rb b/spec/features/tags/master_deletes_tag_spec.rb index 4d6fc13557f..d6a6b8fc7d5 100644 --- a/spec/features/tags/master_deletes_tag_spec.rb +++ b/spec/features/tags/master_deletes_tag_spec.rb @@ -36,8 +36,8 @@ feature 'Master deletes tag' do context 'when pre-receive hook fails', js: true do before do - allow_any_instance_of(GitHooksService).to receive(:execute) - .and_raise(GitHooksService::PreReceiveError, 'Do not delete tags') + allow_any_instance_of(Gitlab::Git::HooksService).to receive(:execute) + .and_raise(Gitlab::Git::HooksService::PreReceiveError, 'Do not delete tags') end scenario 'shows the error message' do diff --git a/spec/fixtures/emails/ios_default.eml b/spec/fixtures/emails/ios_default.eml index 8d4d58feb16..fa19475104a 100644 --- a/spec/fixtures/emails/ios_default.eml +++ b/spec/fixtures/emails/ios_default.eml @@ -76,7 +76,7 @@ Content-Transfer-Encoding: 7bit <img src="https://meta-discourse.global.ssl.fastly.net/user_avatar/meta.discourse.org/techapj/45/3281.png" title="techAPJ" style="max-width:100%;" width="45" height="45"> </td> <td> - <a href="https://meta.discourse.org/users/techapj" target="_blank" style="text-decoration: none; font-weight: bold; color: #006699;; font-size:13px;font-family:'lucida grande',tahoma,verdana,arial,sans-serif;color:#3b5998;text-decoration:none;font-weight:bold">techAPJ</a><br> + <a href="https://meta.discourse.org/users/techapj" target="_blank" style="text-decoration: none; font-weight: 600; color: #006699;; font-size:13px;font-family:'lucida grande',tahoma,verdana,arial,sans-serif;color:#3b5998;text-decoration:none;font-weight:bold">techAPJ</a><br> <span style="text-align:right;color:#999999;padding-right:5px;font-family:'lucida grande',tahoma,verdana,arial,sans-serif;font-size:11px">November 28</span> </td> </tr> @@ -94,7 +94,7 @@ Content-Transfer-Encoding: 7bit <div style="color:#666;"> - <p>To respond, reply to this email or visit <a href="https://meta.discourse.org/t/testing-default-email-replies/22638/3" style="text-decoration: none; font-weight: bold; color: #006699;; color:#666;">https://meta.discourse.org/t/testing-default-email-replies/22638/3</a> in your browser.</p> + <p>To respond, reply to this email or visit <a href="https://meta.discourse.org/t/testing-default-email-replies/22638/3" style="text-decoration: none; font-weight: 600; color: #006699;; color:#666;">https://meta.discourse.org/t/testing-default-email-replies/22638/3</a> in your browser.</p> </div> <hr style="background-color: #ddd; height: 1px; border: 1px;; background-color: #ddd; height: 1px; border: 1px;"> <h4>Previous Replies</h4> @@ -106,7 +106,7 @@ Content-Transfer-Encoding: 7bit <img src="https://meta-discourse.global.ssl.fastly.net/user_avatar/meta.discourse.org/codinghorror/45/5297.png" title="codinghorror" style="max-width:100%;" width="45" height="45"> </td> <td> - <a href="https://meta.discourse.org/users/codinghorror" target="_blank" style="text-decoration: none; font-weight: bold; color: #006699;; font-size:13px;font-family:'lucida grande',tahoma,verdana,arial,sans-serif;color:#3b5998;text-decoration:none;font-weight:bold">codinghorror</a><br> + <a href="https://meta.discourse.org/users/codinghorror" target="_blank" style="text-decoration: none; font-weight: 600; color: #006699;; font-size:13px;font-family:'lucida grande',tahoma,verdana,arial,sans-serif;color:#3b5998;text-decoration:none;font-weight:bold">codinghorror</a><br> <span style="text-align:right;color:#999999;padding-right:5px;font-family:'lucida grande',tahoma,verdana,arial,sans-serif;font-size:11px">November 28</span> </td> </tr> @@ -114,7 +114,7 @@ Content-Transfer-Encoding: 7bit <td style="padding-top:5px;" colspan="2"> <p style="margin-top:0; border: 0;">We're testing the latest GitHub email processing library which we are integrating now.</p> -<p style="margin-top:0; border: 0;"><a href="https://github.com/github/email_reply_parser" target="_blank" style="text-decoration: none; font-weight: bold; color: #006699;">https://github.com/github/email_reply_parser</a></p> +<p style="margin-top:0; border: 0;"><a href="https://github.com/github/email_reply_parser" target="_blank" style="text-decoration: none; font-weight: 600; color: #006699;">https://github.com/github/email_reply_parser</a></p> <p style="margin-top:0; border: 0;">Go ahead and reply to this topic and I'll reply from various email clients for testing.</p> </td> @@ -126,10 +126,10 @@ Content-Transfer-Encoding: 7bit <hr style="background-color: #ddd; height: 1px; border: 1px;; background-color: #ddd; height: 1px; border: 1px;"> <div style="color:#666;"> -<p>To respond, reply to this email or visit <a href="https://meta.discourse.org/t/testing-default-email-replies/22638/3" style="text-decoration: none; font-weight: bold; color: #006699;; color:#666;">https://meta.discourse.org/t/testing-default-email-replies/22638/3</a> in your browser.</p> +<p>To respond, reply to this email or visit <a href="https://meta.discourse.org/t/testing-default-email-replies/22638/3" style="text-decoration: none; font-weight: 600; color: #006699;; color:#666;">https://meta.discourse.org/t/testing-default-email-replies/22638/3</a> in your browser.</p> </div> <div style="color:#666;"> -<p>To unsubscribe from these emails, visit your <a href="https://meta.discourse.org/my/preferences" style="text-decoration: none; font-weight: bold; color: #006699;; color:#666;">user preferences</a>.</p> +<p>To unsubscribe from these emails, visit your <a href="https://meta.discourse.org/my/preferences" style="text-decoration: none; font-weight: 600; color: #006699;; color:#666;">user preferences</a>.</p> </div> </div> </div></blockquote></body></html> diff --git a/spec/fixtures/emails/on_wrote.eml b/spec/fixtures/emails/on_wrote.eml index feb59bd27bb..af6a4e50a49 100644 --- a/spec/fixtures/emails/on_wrote.eml +++ b/spec/fixtures/emails/on_wrote.eml @@ -53,7 +53,7 @@ y > display: inline-block; > font-family: FontAwesome; > font-style: normal; -> font-weight: normal; +> font-weight: 400; > line-height: 1; > -webkit-font-smoothing: antialiased; > -moz-osx-font-smoothing: grayscale; @@ -227,7 +227,7 @@ ding:5px">.fa { display: inline-block; font-family: FontAwesome; font-style: normal; - font-weight: normal; + font-weight: 400; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; @@ -274,4 +274,4 @@ ight:bold;color:#006699" target=3D"_blank">user preferences</a>.</p> </div> </blockquote></div><br></div></div> ---001a11c34c389e728f0502aa26a0--
\ No newline at end of file +--001a11c34c389e728f0502aa26a0-- diff --git a/spec/helpers/button_helper_spec.rb b/spec/helpers/button_helper_spec.rb index 250ba239033..4423560ecaa 100644 --- a/spec/helpers/button_helper_spec.rb +++ b/spec/helpers/button_helper_spec.rb @@ -62,4 +62,67 @@ describe ButtonHelper do end end end + + describe 'clipboard_button' do + let(:user) { create(:user) } + let(:project) { build_stubbed(:project) } + + def element(data = {}) + element = helper.clipboard_button(data) + Nokogiri::HTML::DocumentFragment.parse(element).first_element_child + end + + before do + allow(helper).to receive(:current_user).and_return(user) + end + + context 'with default options' do + context 'when no `text` attribute is not provided' do + it 'shows copy to clipboard button with default configuration and no text set to copy' do + expect(element.attr('class')).to eq('btn btn-clipboard btn-transparent') + expect(element.attr('type')).to eq('button') + expect(element.attr('aria-label')).to eq('Copy to clipboard') + expect(element.attr('data-toggle')).to eq('tooltip') + expect(element.attr('data-placement')).to eq('bottom') + expect(element.attr('data-container')).to eq('body') + expect(element.attr('data-clipboard-text')).to eq(nil) + expect(element.inner_text).to eq("") + + expect(element).to have_selector('.fa.fa-clipboard') + end + end + + context 'when `text` attribute is provided' do + it 'shows copy to clipboard button with provided `text` to copy' do + expect(element(text: 'Hello World!').attr('data-clipboard-text')).to eq('Hello World!') + end + end + + context 'when `title` attribute is provided' do + it 'shows copy to clipboard button with provided `title` as tooltip' do + expect(element(title: 'Copy to my clipboard!').attr('aria-label')).to eq('Copy to my clipboard!') + end + end + end + + context 'with `button_text` attribute provided' do + it 'shows copy to clipboard button with provided `button_text` as button label' do + expect(element(button_text: 'Copy text').inner_text).to eq('Copy text') + end + end + + context 'with `hide_tooltip` attribute provided' do + it 'shows copy to clipboard button without tooltip support' do + expect(element(hide_tooltip: true).attr('data-placement')).to eq(nil) + expect(element(hide_tooltip: true).attr('data-toggle')).to eq(nil) + expect(element(hide_tooltip: true).attr('data-container')).to eq(nil) + end + end + + context 'with `hide_button_icon` attribute provided' do + it 'shows copy to clipboard button without tooltip support' do + expect(element(hide_button_icon: true)).not_to have_selector('.fa.fa-clipboard') + end + end + end end diff --git a/spec/javascripts/api_spec.js b/spec/javascripts/api_spec.js index 867322ce8ae..8c68ceff914 100644 --- a/spec/javascripts/api_spec.js +++ b/spec/javascripts/api_spec.js @@ -17,7 +17,7 @@ describe('Api', () => { beforeEach(() => { originalGon = window.gon; - window.gon = dummyGon; + window.gon = Object.assign({}, dummyGon); }); afterEach(() => { @@ -98,10 +98,11 @@ describe('Api', () => { }); describe('projects', () => { - it('fetches projects', (done) => { + it('fetches projects with membership when logged in', (done) => { const query = 'dummy query'; const options = { unused: 'option' }; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects.json?simple=true`; + window.gon.current_user_id = 1; const expectedData = Object.assign({ search: query, per_page: 20, @@ -119,6 +120,27 @@ describe('Api', () => { done(); }); }); + + it('fetches projects without membership when not logged in', (done) => { + const query = 'dummy query'; + const options = { unused: 'option' }; + const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects.json?simple=true`; + const expectedData = Object.assign({ + search: query, + per_page: 20, + }, options); + spyOn(jQuery, 'ajax').and.callFake((request) => { + expect(request.url).toEqual(expectedUrl); + expect(request.dataType).toEqual('json'); + expect(request.data).toEqual(expectedData); + return sendDummyResponse(); + }); + + Api.projects(query, options, (response) => { + expect(response).toBe(dummyResponse); + done(); + }); + }); }); describe('newLabel', () => { diff --git a/spec/javascripts/project_title_spec.js b/spec/javascripts/project_title_spec.js index cc336180ff7..3d36bb3e4d4 100644 --- a/spec/javascripts/project_title_spec.js +++ b/spec/javascripts/project_title_spec.js @@ -7,6 +7,7 @@ import '~/project_select'; import '~/project'; describe('Project Title', () => { + const dummyApiVersion = 'v3000'; preloadFixtures('issues/open-issue.html.raw'); loadJSONFixtures('projects.json'); @@ -14,7 +15,7 @@ describe('Project Title', () => { loadFixtures('issues/open-issue.html.raw'); window.gon = {}; - window.gon.api_version = 'v3'; + window.gon.api_version = dummyApiVersion; // eslint-disable-next-line no-new new Project(); @@ -37,9 +38,10 @@ describe('Project Title', () => { it('toggles dropdown', () => { const $menu = $('.js-dropdown-menu-projects'); + window.gon.current_user_id = 1; $('.js-projects-dropdown-toggle').click(); expect($menu).toHaveClass('open'); - expect(reqUrl).toBe('/api/v3/projects.json?simple=true'); + expect(reqUrl).toBe(`/api/${dummyApiVersion}/projects.json?simple=true`); expect(reqData).toEqual({ search: '', order_by: 'last_activity_at', diff --git a/spec/lib/gitlab/bare_repository_importer_spec.rb b/spec/lib/gitlab/bare_repository_importer_spec.rb index 892f2dafc96..36d1844b5b1 100644 --- a/spec/lib/gitlab/bare_repository_importer_spec.rb +++ b/spec/lib/gitlab/bare_repository_importer_spec.rb @@ -2,67 +2,99 @@ require 'spec_helper' describe Gitlab::BareRepositoryImporter, repository: true do subject(:importer) { described_class.new('default', project_path) } - let(:project_path) { 'a-group/a-sub-group/a-project' } + let!(:admin) { create(:admin) } before do allow(described_class).to receive(:log) end - describe '.execute' do - it 'creates a project for a repository in storage' do - FileUtils.mkdir_p(File.join(TestEnv.repos_path, "#{project_path}.git")) - fake_importer = double + shared_examples 'importing a repository' do + describe '.execute' do + it 'creates a project for a repository in storage' do + FileUtils.mkdir_p(File.join(TestEnv.repos_path, "#{project_path}.git")) + fake_importer = double - expect(described_class).to receive(:new).with('default', project_path) - .and_return(fake_importer) - expect(fake_importer).to receive(:create_project_if_needed) + expect(described_class).to receive(:new).with('default', project_path) + .and_return(fake_importer) + expect(fake_importer).to receive(:create_project_if_needed) - described_class.execute - end + described_class.execute + end - it 'skips wiki repos' do - FileUtils.mkdir_p(File.join(TestEnv.repos_path, 'the-group', 'the-project.wiki.git')) + it 'skips wiki repos' do + FileUtils.mkdir_p(File.join(TestEnv.repos_path, 'the-group', 'the-project.wiki.git')) - expect(described_class).to receive(:log).with(' * Skipping wiki repo') - expect(described_class).not_to receive(:new) + expect(described_class).to receive(:log).with(' * Skipping wiki repo') + expect(described_class).not_to receive(:new) - described_class.execute + described_class.execute + end end - end - describe '#initialize' do - context 'without admin users' do - let(:admin) { nil } + describe '#initialize' do + context 'without admin users' do + let(:admin) { nil } - it 'raises an error' do - expect { importer }.to raise_error(Gitlab::BareRepositoryImporter::NoAdminError) + it 'raises an error' do + expect { importer }.to raise_error(Gitlab::BareRepositoryImporter::NoAdminError) + end end end - end - describe '#create_project_if_needed' do - it 'starts an import for a project that did not exist' do - expect(importer).to receive(:create_project) + describe '#create_project_if_needed' do + it 'starts an import for a project that did not exist' do + expect(importer).to receive(:create_project) + + importer.create_project_if_needed + end + + it 'skips importing when the project already exists' do + project = create(:project, path: 'a-project', namespace: existing_group) + + expect(importer).not_to receive(:create_project) + expect(importer).to receive(:log).with(" * #{project.name} (#{project_path}) exists") + + importer.create_project_if_needed + end + + it 'creates a project with the correct path in the database' do + importer.create_project_if_needed - importer.create_project_if_needed + expect(Project.find_by_full_path(project_path)).not_to be_nil + end end + end + + context 'with subgroups', :nested_groups do + let(:project_path) { 'a-group/a-sub-group/a-project' } - it 'skips importing when the project already exists' do + let(:existing_group) do group = create(:group, path: 'a-group') - subgroup = create(:group, path: 'a-sub-group', parent: group) - project = create(:project, path: 'a-project', namespace: subgroup) + create(:group, path: 'a-sub-group', parent: group) + end - expect(importer).not_to receive(:create_project) - expect(importer).to receive(:log).with(" * #{project.name} (a-group/a-sub-group/a-project) exists") + it_behaves_like 'importing a repository' + end - importer.create_project_if_needed - end + context 'without subgroups' do + let(:project_path) { 'a-group/a-project' } + let(:existing_group) { create(:group, path: 'a-group') } - it 'creates a project with the correct path in the database' do - importer.create_project_if_needed + it_behaves_like 'importing a repository' + end + + context 'when subgroups are not available' do + let(:project_path) { 'a-group/a-sub-group/a-project' } + + before do + expect(Group).to receive(:supports_nested_groups?) { false } + end - expect(Project.find_by_full_path(project_path)).not_to be_nil + describe '#create_project_if_needed' do + it 'raises an error' do + expect { importer.create_project_if_needed }.to raise_error('Nested groups are not supported on MySQL') + end end end end diff --git a/spec/lib/gitlab/file_finder_spec.rb b/spec/lib/gitlab/file_finder_spec.rb index 3fb6315a39a..07cb10e563e 100644 --- a/spec/lib/gitlab/file_finder_spec.rb +++ b/spec/lib/gitlab/file_finder_spec.rb @@ -7,15 +7,23 @@ describe Gitlab::FileFinder do it 'finds by name' do results = finder.find('files') - expect(results.map(&:first)).to include('files/images/wm.svg') + + filename, blob = results.find { |_, blob| blob.filename == 'files/images/wm.svg' } + expect(filename).to eq('files/images/wm.svg') + expect(blob).to be_a(Gitlab::SearchResults::FoundBlob) + expect(blob.ref).to eq(finder.ref) + expect(blob.data).not_to be_empty end it 'finds by content' do results = finder.find('files') - blob = results.select { |result| result.first == "CHANGELOG" }.flatten.last + filename, blob = results.find { |_, blob| blob.filename == 'CHANGELOG' } - expect(blob.filename).to eq("CHANGELOG") + expect(filename).to eq('CHANGELOG') + expect(blob).to be_a(Gitlab::SearchResults::FoundBlob) + expect(blob.ref).to eq(finder.ref) + expect(blob.data).not_to be_empty end end end diff --git a/spec/lib/gitlab/git/blame_spec.rb b/spec/lib/gitlab/git/blame_spec.rb index 800c245b130..465c2012b05 100644 --- a/spec/lib/gitlab/git/blame_spec.rb +++ b/spec/lib/gitlab/git/blame_spec.rb @@ -2,7 +2,7 @@ require "spec_helper" describe Gitlab::Git::Blame, seed_helper: true do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } let(:blame) do Gitlab::Git::Blame.new(repository, SeedRepo::Commit::ID, "CONTRIBUTING.md") end diff --git a/spec/lib/gitlab/git/blob_spec.rb b/spec/lib/gitlab/git/blob_spec.rb index dfab0c2fe85..66ba00acb7d 100644 --- a/spec/lib/gitlab/git/blob_spec.rb +++ b/spec/lib/gitlab/git/blob_spec.rb @@ -3,7 +3,7 @@ require "spec_helper" describe Gitlab::Git::Blob, seed_helper: true do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } describe 'initialize' do let(:blob) { Gitlab::Git::Blob.new(name: 'test') } diff --git a/spec/lib/gitlab/git/branch_spec.rb b/spec/lib/gitlab/git/branch_spec.rb index cdf1b8beee3..318a7b7a332 100644 --- a/spec/lib/gitlab/git/branch_spec.rb +++ b/spec/lib/gitlab/git/branch_spec.rb @@ -1,7 +1,7 @@ require "spec_helper" describe Gitlab::Git::Branch, seed_helper: true do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } subject { repository.branches } diff --git a/spec/lib/gitlab/git/commit_spec.rb b/spec/lib/gitlab/git/commit_spec.rb index ac33cd8a2c9..14d64d8c4da 100644 --- a/spec/lib/gitlab/git/commit_spec.rb +++ b/spec/lib/gitlab/git/commit_spec.rb @@ -1,7 +1,7 @@ require "spec_helper" describe Gitlab::Git::Commit, seed_helper: true do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } let(:commit) { described_class.find(repository, SeedRepo::Commit::ID) } let(:rugged_commit) do repository.rugged.lookup(SeedRepo::Commit::ID) @@ -9,7 +9,7 @@ describe Gitlab::Git::Commit, seed_helper: true do describe "Commit info" do before do - repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH).rugged + repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '').rugged @committer = { email: 'mike@smith.com', @@ -59,7 +59,7 @@ describe Gitlab::Git::Commit, seed_helper: true do after do # Erase the new commit so other tests get the original repo - repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH).rugged + repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '').rugged repo.references.update("refs/heads/master", SeedRepo::LastCommit::ID) end end @@ -144,7 +144,7 @@ describe Gitlab::Git::Commit, seed_helper: true do end context 'with broken repo' do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_BROKEN_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_BROKEN_REPO_PATH, '') } it 'returns nil' do expect(described_class.find(repository, SeedRepo::Commit::ID)).to be_nil diff --git a/spec/lib/gitlab/git/committer_spec.rb b/spec/lib/gitlab/git/committer_spec.rb new file mode 100644 index 00000000000..b0ddbb51449 --- /dev/null +++ b/spec/lib/gitlab/git/committer_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +describe Gitlab::Git::Committer do + let(:name) { 'Jane Doe' } + let(:email) { 'janedoe@example.com' } + let(:gl_id) { 'user-123' } + + subject { described_class.new(name, email, gl_id) } + + describe '#==' do + def eq_other(name, email, gl_id) + eq(described_class.new(name, email, gl_id)) + end + + it { expect(subject).to eq_other(name, email, gl_id) } + + it { expect(subject).not_to eq_other(nil, nil, nil) } + it { expect(subject).not_to eq_other(name + 'x', email, gl_id) } + it { expect(subject).not_to eq_other(name, email + 'x', gl_id) } + it { expect(subject).not_to eq_other(name, email, gl_id + 'x') } + end +end diff --git a/spec/lib/gitlab/git/compare_spec.rb b/spec/lib/gitlab/git/compare_spec.rb index 4c9f4a28f32..b6a42e422b5 100644 --- a/spec/lib/gitlab/git/compare_spec.rb +++ b/spec/lib/gitlab/git/compare_spec.rb @@ -1,7 +1,7 @@ require "spec_helper" describe Gitlab::Git::Compare, seed_helper: true do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } let(:compare) { Gitlab::Git::Compare.new(repository, SeedRepo::BigCommit::ID, SeedRepo::Commit::ID, straight: false) } let(:compare_straight) { Gitlab::Git::Compare.new(repository, SeedRepo::BigCommit::ID, SeedRepo::Commit::ID, straight: true) } diff --git a/spec/lib/gitlab/git/diff_spec.rb b/spec/lib/gitlab/git/diff_spec.rb index 7ea3386ac2a..dfbdbee48f7 100644 --- a/spec/lib/gitlab/git/diff_spec.rb +++ b/spec/lib/gitlab/git/diff_spec.rb @@ -1,7 +1,7 @@ require "spec_helper" describe Gitlab::Git::Diff, seed_helper: true do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } before do @raw_diff_hash = { diff --git a/spec/lib/gitlab/git/hook_spec.rb b/spec/lib/gitlab/git/hook_spec.rb index 19391a70cf6..ea3e4680b1d 100644 --- a/spec/lib/gitlab/git/hook_spec.rb +++ b/spec/lib/gitlab/git/hook_spec.rb @@ -10,7 +10,8 @@ describe Gitlab::Git::Hook do describe "#trigger" do let(:project) { create(:project, :repository) } - let(:repo_path) { project.repository.path } + let(:repository) { project.repository.raw_repository } + let(:repo_path) { repository.path } let(:user) { create(:user) } let(:gl_id) { Gitlab::GlId.gl_id(user) } @@ -48,7 +49,7 @@ describe Gitlab::Git::Hook do it "returns success with no errors" do create_hook(hook_name) - hook = described_class.new(hook_name, project) + hook = described_class.new(hook_name, repository) blank = Gitlab::Git::BLANK_SHA ref = Gitlab::Git::BRANCH_REF_PREFIX + 'new_branch' @@ -66,7 +67,7 @@ describe Gitlab::Git::Hook do context "when the hook is unsuccessful" do it "returns failure with errors" do create_failing_hook(hook_name) - hook = described_class.new(hook_name, project) + hook = described_class.new(hook_name, repository) blank = Gitlab::Git::BLANK_SHA ref = Gitlab::Git::BRANCH_REF_PREFIX + 'new_branch' @@ -80,7 +81,7 @@ describe Gitlab::Git::Hook do context "when the hook doesn't exist" do it "returns success with no errors" do - hook = described_class.new('unknown_hook', project) + hook = described_class.new('unknown_hook', repository) blank = Gitlab::Git::BLANK_SHA ref = Gitlab::Git::BRANCH_REF_PREFIX + 'new_branch' diff --git a/spec/services/git_hooks_service_spec.rb b/spec/lib/gitlab/git/hooks_service_spec.rb index 3ce01a995b4..e9c0209fe3b 100644 --- a/spec/services/git_hooks_service_spec.rb +++ b/spec/lib/gitlab/git/hooks_service_spec.rb @@ -1,16 +1,14 @@ require 'spec_helper' -describe GitHooksService do - include RepoHelpers - - let(:user) { create(:user) } - let(:project) { create(:project, :repository) } +describe Gitlab::Git::HooksService, seed_helper: true do + let(:committer) { Gitlab::Git::Committer.new('Jane Doe', 'janedoe@example.com', 'user-456') } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, 'project-123') } let(:service) { described_class.new } before do @blankrev = Gitlab::Git::BLANK_SHA - @oldrev = sample_commit.parent_id - @newrev = sample_commit.id + @oldrev = SeedRepo::Commit::PARENT_ID + @newrev = SeedRepo::Commit::ID @ref = 'refs/heads/feature' end @@ -20,7 +18,7 @@ describe GitHooksService do hook = double(trigger: [true, nil]) expect(Gitlab::Git::Hook).to receive(:new).exactly(3).times.and_return(hook) - service.execute(user, project, @blankrev, @newrev, @ref) { } + service.execute(committer, repository, @blankrev, @newrev, @ref) { } end end @@ -30,8 +28,8 @@ describe GitHooksService do expect(service).not_to receive(:run_hook).with('post-receive') expect do - service.execute(user, project, @blankrev, @newrev, @ref) - end.to raise_error(GitHooksService::PreReceiveError) + service.execute(committer, repository, @blankrev, @newrev, @ref) + end.to raise_error(Gitlab::Git::HooksService::PreReceiveError) end end @@ -42,8 +40,8 @@ describe GitHooksService do expect(service).not_to receive(:run_hook).with('post-receive') expect do - service.execute(user, project, @blankrev, @newrev, @ref) - end.to raise_error(GitHooksService::PreReceiveError) + service.execute(committer, repository, @blankrev, @newrev, @ref) + end.to raise_error(Gitlab::Git::HooksService::PreReceiveError) end end end diff --git a/spec/lib/gitlab/git/index_spec.rb b/spec/lib/gitlab/git/index_spec.rb index 21b71654251..73fbc6a6afa 100644 --- a/spec/lib/gitlab/git/index_spec.rb +++ b/spec/lib/gitlab/git/index_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe Gitlab::Git::Index, seed_helper: true do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } let(:index) { described_class.new(repository) } before do diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb index 62da733170c..6b9773c9b63 100644 --- a/spec/lib/gitlab/git/repository_spec.rb +++ b/spec/lib/gitlab/git/repository_spec.rb @@ -17,7 +17,7 @@ describe Gitlab::Git::Repository, seed_helper: true do end end - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } describe "Respond to" do subject { repository } @@ -56,14 +56,14 @@ describe Gitlab::Git::Repository, seed_helper: true do describe "#rugged" do describe 'when storage is broken', broken_storage: true do it 'raises a storage exception when storage is not available' do - broken_repo = described_class.new('broken', 'a/path.git') + broken_repo = described_class.new('broken', 'a/path.git', '') expect { broken_repo.rugged }.to raise_error(Gitlab::Git::Storage::Inaccessible) end end it 'raises a no repository exception when there is no repo' do - broken_repo = described_class.new('default', 'a/path.git') + broken_repo = described_class.new('default', 'a/path.git', '') expect { broken_repo.rugged }.to raise_error(Gitlab::Git::Repository::NoRepository) end @@ -257,7 +257,7 @@ describe Gitlab::Git::Repository, seed_helper: true do end describe '#submodule_url_for' do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } let(:ref) { 'master' } def submodule_url(path) @@ -295,7 +295,7 @@ describe Gitlab::Git::Repository, seed_helper: true do end context '#submodules' do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } context 'where repo has submodules' do let(:submodules) { repository.send(:submodules, 'master') } @@ -391,7 +391,7 @@ describe Gitlab::Git::Repository, seed_helper: true do describe "#delete_branch" do before(:all) do - @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH) + @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') @repo.delete_branch("feature") end @@ -407,7 +407,7 @@ describe Gitlab::Git::Repository, seed_helper: true do describe "#create_branch" do before(:all) do - @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH) + @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') end it "should create a new branch" do @@ -445,7 +445,7 @@ describe Gitlab::Git::Repository, seed_helper: true do describe "#remote_delete" do before(:all) do - @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH) + @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') @repo.remote_delete("expendable") end @@ -461,7 +461,7 @@ describe Gitlab::Git::Repository, seed_helper: true do describe "#remote_add" do before(:all) do - @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH) + @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') @repo.remote_add("new_remote", SeedHelper::GITLAB_GIT_TEST_REPO_URL) end @@ -477,7 +477,7 @@ describe Gitlab::Git::Repository, seed_helper: true do describe "#remote_update" do before(:all) do - @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH) + @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') @repo.remote_update("expendable", url: TEST_NORMAL_REPO_PATH) end @@ -506,7 +506,7 @@ describe Gitlab::Git::Repository, seed_helper: true do before(:context) do # Add new commits so that there's a renamed file in the commit history - repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH).rugged + repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '').rugged @commit_with_old_name_id = new_commit_edit_old_file(repo) @rename_commit_id = new_commit_move_file(repo) @commit_with_new_name_id = new_commit_edit_new_file(repo) @@ -514,7 +514,7 @@ describe Gitlab::Git::Repository, seed_helper: true do after(:context) do # Erase our commits so other tests get the original repo - repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH).rugged + repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '').rugged repo.references.update("refs/heads/master", SeedRepo::LastCommit::ID) end @@ -849,7 +849,7 @@ describe Gitlab::Git::Repository, seed_helper: true do describe '#autocrlf' do before(:all) do - @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH) + @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') @repo.rugged.config['core.autocrlf'] = true end @@ -864,7 +864,7 @@ describe Gitlab::Git::Repository, seed_helper: true do describe '#autocrlf=' do before(:all) do - @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH) + @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') @repo.rugged.config['core.autocrlf'] = false end @@ -933,7 +933,7 @@ describe Gitlab::Git::Repository, seed_helper: true do context 'with local and remote branches' do let(:repository) do - Gitlab::Git::Repository.new('default', File.join(TEST_MUTABLE_REPO_PATH, '.git')) + Gitlab::Git::Repository.new('default', File.join(TEST_MUTABLE_REPO_PATH, '.git'), '') end before do @@ -980,7 +980,7 @@ describe Gitlab::Git::Repository, seed_helper: true do context 'with local and remote branches' do let(:repository) do - Gitlab::Git::Repository.new('default', File.join(TEST_MUTABLE_REPO_PATH, '.git')) + Gitlab::Git::Repository.new('default', File.join(TEST_MUTABLE_REPO_PATH, '.git'), '') end before do @@ -1186,7 +1186,7 @@ describe Gitlab::Git::Repository, seed_helper: true do describe '#local_branches' do before(:all) do - @repo = Gitlab::Git::Repository.new('default', File.join(TEST_MUTABLE_REPO_PATH, '.git')) + @repo = Gitlab::Git::Repository.new('default', File.join(TEST_MUTABLE_REPO_PATH, '.git'), '') end after(:all) do diff --git a/spec/lib/gitlab/git/tag_spec.rb b/spec/lib/gitlab/git/tag_spec.rb index 78d1e120013..cc10679ef1e 100644 --- a/spec/lib/gitlab/git/tag_spec.rb +++ b/spec/lib/gitlab/git/tag_spec.rb @@ -1,7 +1,7 @@ require "spec_helper" describe Gitlab::Git::Tag, seed_helper: true do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } shared_examples 'Gitlab::Git::Repository#tags' do describe 'first tag' do diff --git a/spec/lib/gitlab/git/tree_spec.rb b/spec/lib/gitlab/git/tree_spec.rb index 98ddd3c3664..c07a2d91768 100644 --- a/spec/lib/gitlab/git/tree_spec.rb +++ b/spec/lib/gitlab/git/tree_spec.rb @@ -1,7 +1,7 @@ require "spec_helper" describe Gitlab::Git::Tree, seed_helper: true do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } context :repo do let(:tree) { Gitlab::Git::Tree.where(repository, SeedRepo::Commit::ID) } diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb index 80dc49e99cb..295a979da76 100644 --- a/spec/lib/gitlab/git_access_spec.rb +++ b/spec/lib/gitlab/git_access_spec.rb @@ -384,7 +384,7 @@ describe Gitlab::GitAccess do def stub_git_hooks # Running the `pre-receive` hook is expensive, and not necessary for this test. - allow_any_instance_of(GitHooksService).to receive(:execute) do |service, &block| + allow_any_instance_of(Gitlab::Git::HooksService).to receive(:execute) do |service, &block| block.call(service) end end diff --git a/spec/lib/gitlab/import_export/repo_restorer_spec.rb b/spec/lib/gitlab/import_export/repo_restorer_spec.rb index 2786bc92fe5..c49af602a01 100644 --- a/spec/lib/gitlab/import_export/repo_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/repo_restorer_spec.rb @@ -34,7 +34,7 @@ describe Gitlab::ImportExport::RepoRestorer do it 'has the webhooks' do restorer.restore - expect(Gitlab::Git::Hook.new('post-receive', project)).to exist + expect(Gitlab::Git::Hook.new('post-receive', project.repository.raw_repository)).to exist end end end diff --git a/spec/migrations/migrate_stages_statuses_spec.rb b/spec/migrations/migrate_stages_statuses_spec.rb index 4102d57e368..094c9bc604e 100644 --- a/spec/migrations/migrate_stages_statuses_spec.rb +++ b/spec/migrations/migrate_stages_statuses_spec.rb @@ -12,7 +12,7 @@ describe MigrateStagesStatuses, :migration do before do stub_const("#{described_class.name}::BATCH_SIZE", 2) - stub_const("#{described_class.name}::RANGE_SIZE", 2) + stub_const("#{described_class.name}::RANGE_SIZE", 1) projects.create!(id: 1, name: 'gitlab1', path: 'gitlab1') projects.create!(id: 2, name: 'gitlab2', path: 'gitlab2') @@ -50,9 +50,10 @@ describe MigrateStagesStatuses, :migration do Timecop.freeze do migrate! - expect(described_class::MIGRATION).to be_scheduled_migration(5.minutes, 1, 2) + expect(described_class::MIGRATION).to be_scheduled_migration(5.minutes, 1, 1) + expect(described_class::MIGRATION).to be_scheduled_migration(5.minutes, 2, 2) expect(described_class::MIGRATION).to be_scheduled_migration(10.minutes, 3, 3) - expect(BackgroundMigrationWorker.jobs.size).to eq 2 + expect(BackgroundMigrationWorker.jobs.size).to eq 3 end end end diff --git a/spec/models/ci/stage_spec.rb b/spec/models/ci/stage_spec.rb index 74c9d6145e2..586d073eb5e 100644 --- a/spec/models/ci/stage_spec.rb +++ b/spec/models/ci/stage_spec.rb @@ -38,6 +38,17 @@ describe Ci::Stage, :models do expect(stage.status).to eq 'success' end end + + context 'when stage status is not defined' do + before do + stage.update_column(:status, nil) + end + + it 'sets the default value' do + expect(described_class.find(stage.id).status) + .to eq 'created' + end + end end describe 'update_status' do diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index 4926d5d6c49..462e92b8b62 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -8,6 +8,7 @@ describe Repository, models: true do let(:repository) { project.repository } let(:broken_repository) { create(:project, :broken_storage).repository } let(:user) { create(:user) } + let(:committer) { Gitlab::Git::Committer.from_user(user) } let(:commit_options) do author = repository.user_to_committer(user) @@ -846,7 +847,7 @@ describe Repository, models: true do expect do repository.add_branch(user, 'new_feature', 'master') - end.to raise_error(GitHooksService::PreReceiveError) + end.to raise_error(Gitlab::Git::HooksService::PreReceiveError) end it 'does not create the branch' do @@ -854,7 +855,7 @@ describe Repository, models: true do expect do repository.add_branch(user, 'new_feature', 'master') - end.to raise_error(GitHooksService::PreReceiveError) + end.to raise_error(Gitlab::Git::HooksService::PreReceiveError) expect(repository.find_branch('new_feature')).to be_nil end end @@ -884,8 +885,8 @@ describe Repository, models: true do context 'when pre hooks were successful' do it 'runs without errors' do - expect_any_instance_of(GitHooksService).to receive(:execute) - .with(user, project, old_rev, blank_sha, 'refs/heads/feature') + expect_any_instance_of(Gitlab::Git::HooksService).to receive(:execute) + .with(committer, repository, old_rev, blank_sha, 'refs/heads/feature') expect { repository.rm_branch(user, 'feature') }.not_to raise_error end @@ -905,7 +906,7 @@ describe Repository, models: true do expect do repository.rm_branch(user, 'feature') - end.to raise_error(GitHooksService::PreReceiveError) + end.to raise_error(Gitlab::Git::HooksService::PreReceiveError) end it 'does not delete the branch' do @@ -913,7 +914,7 @@ describe Repository, models: true do expect do repository.rm_branch(user, 'feature') - end.to raise_error(GitHooksService::PreReceiveError) + end.to raise_error(Gitlab::Git::HooksService::PreReceiveError) expect(repository.find_branch('feature')).not_to be_nil end end @@ -925,23 +926,23 @@ describe Repository, models: true do context 'when pre hooks were successful' do before do - service = GitHooksService.new - expect(GitHooksService).to receive(:new).and_return(service) + service = Gitlab::Git::HooksService.new + expect(Gitlab::Git::HooksService).to receive(:new).and_return(service) expect(service).to receive(:execute) - .with(user, project, old_rev, new_rev, 'refs/heads/feature') + .with(committer, repository, old_rev, new_rev, 'refs/heads/feature') .and_yield(service).and_return(true) end it 'runs without errors' do expect do - GitOperationService.new(user, repository).with_branch('feature') do + GitOperationService.new(committer, repository).with_branch('feature') do new_rev end end.not_to raise_error end it 'ensures the autocrlf Git option is set to :input' do - service = GitOperationService.new(user, repository) + service = GitOperationService.new(committer, repository) expect(service).to receive(:update_autocrlf_option) @@ -952,7 +953,7 @@ describe Repository, models: true do it 'updates the head' do expect(repository.find_branch('feature').dereferenced_target.id).to eq(old_rev) - GitOperationService.new(user, repository).with_branch('feature') do + GitOperationService.new(committer, repository).with_branch('feature') do new_rev end @@ -974,7 +975,7 @@ describe Repository, models: true do end expect do - GitOperationService.new(user, target_project.repository) + GitOperationService.new(committer, target_project.repository) .with_branch('feature', start_project: project, &:itself) @@ -996,7 +997,7 @@ describe Repository, models: true do repository.add_branch(user, branch, old_rev) expect do - GitOperationService.new(user, repository).with_branch(branch) do + GitOperationService.new(committer, repository).with_branch(branch) do new_rev end end.not_to raise_error @@ -1014,7 +1015,7 @@ describe Repository, models: true do # Updating 'master' to new_rev would lose the commits on 'master' that # are not contained in new_rev. This should not be allowed. expect do - GitOperationService.new(user, repository).with_branch(branch) do + GitOperationService.new(committer, repository).with_branch(branch) do new_rev end end.to raise_error(Repository::CommitError) @@ -1026,10 +1027,10 @@ describe Repository, models: true do allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return([false, '']) expect do - GitOperationService.new(user, repository).with_branch('feature') do + GitOperationService.new(committer, repository).with_branch('feature') do new_rev end - end.to raise_error(GitHooksService::PreReceiveError) + end.to raise_error(Gitlab::Git::HooksService::PreReceiveError) end end @@ -1044,7 +1045,7 @@ describe Repository, models: true do expect(repository).not_to receive(:expire_emptiness_caches) expect(repository).to receive(:expire_branches_cache) - GitOperationService.new(user, repository) + GitOperationService.new(committer, repository) .with_branch('new-feature') do new_rev end diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb index 313c38cd29c..a7557c7fb22 100644 --- a/spec/requests/api/groups_spec.rb +++ b/spec/requests/api/groups_spec.rb @@ -20,10 +20,15 @@ describe API::Groups do describe "GET /groups" do context "when unauthenticated" do - it "returns authentication error" do + it "returns public groups" do get api("/groups") - expect(response).to have_http_status(401) + expect(response).to have_http_status(200) + expect(response).to include_pagination_headers + expect(json_response).to be_an Array + expect(json_response.length).to eq(1) + expect(json_response) + .to satisfy_one { |group| group['name'] == group1.name } end end @@ -165,6 +170,18 @@ describe API::Groups do end describe "GET /groups/:id" do + context 'when unauthenticated' do + it 'returns 404 for a private group' do + get api("/groups/#{group2.id}") + expect(response).to have_http_status(404) + end + + it 'returns 200 for a public group' do + get api("/groups/#{group1.id}") + expect(response).to have_http_status(200) + end + end + context "when authenticated as user" do it "returns one of user1's groups" do project = create(:project, namespace: group2, path: 'Foo') diff --git a/spec/services/files/update_service_spec.rb b/spec/services/files/update_service_spec.rb index cc950ae6bb3..2b4f8cd42ee 100644 --- a/spec/services/files/update_service_spec.rb +++ b/spec/services/files/update_service_spec.rb @@ -76,7 +76,7 @@ describe Files::UpdateService do let(:branch_name) { "#{project.default_branch}-new" } it 'fires hooks only once' do - expect(GitHooksService).to receive(:new).once.and_call_original + expect(Gitlab::Git::HooksService).to receive(:new).once.and_call_original subject.execute end diff --git a/spec/services/groups/nested_create_service_spec.rb b/spec/services/groups/nested_create_service_spec.rb index c1526456bac..6491fb34777 100644 --- a/spec/services/groups/nested_create_service_spec.rb +++ b/spec/services/groups/nested_create_service_spec.rb @@ -2,52 +2,87 @@ require 'spec_helper' describe Groups::NestedCreateService do let(:user) { create(:user) } - let(:params) { { group_path: 'a-group/a-sub-group' } } subject(:service) { described_class.new(user, params) } - describe "#execute" do - it 'returns the group if it already existed' do - parent = create(:group, path: 'a-group', owner: user) - child = create(:group, path: 'a-sub-group', parent: parent, owner: user) + shared_examples 'with a visibility level' do + it 'creates the group with correct visibility level' do + allow(Gitlab::CurrentSettings.current_application_settings) + .to receive(:default_group_visibility) { Gitlab::VisibilityLevel::INTERNAL } + + group = service.execute - expect(service.execute).to eq(child) + expect(group.visibility_level).to eq(Gitlab::VisibilityLevel::INTERNAL) end - it 'reuses a parent if it already existed' do - parent = create(:group, path: 'a-group') - parent.add_owner(user) + context 'adding a visibility level ' do + it 'overwrites the visibility level' do + service = described_class.new(user, params.merge(visibility_level: Gitlab::VisibilityLevel::PRIVATE)) + + group = service.execute - expect(service.execute.parent).to eq(parent) + expect(group.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) + end end + end + + describe 'without subgroups' do + let(:params) { { group_path: 'a-group' } } - it 'creates group and subgroup in the database' do - service.execute + before do + allow(Group).to receive(:supports_nested_groups?) { false } + end - parent = Group.find_by_full_path('a-group') - child = parent.children.find_by(path: 'a-sub-group') + it 'creates the group' do + group = service.execute - expect(parent).not_to be_nil - expect(child).not_to be_nil + expect(group).to be_persisted end - it 'creates the group with correct visibility level' do - allow(Gitlab::CurrentSettings.current_application_settings) - .to receive(:default_group_visibility) { Gitlab::VisibilityLevel::INTERNAL } + it 'returns the group if it already existed' do + existing_group = create(:group, path: 'a-group') - group = service.execute + expect(service.execute).to eq(existing_group) + end - expect(group.visibility_level).to eq(Gitlab::VisibilityLevel::INTERNAL) + it 'raises an error when tring to create a subgroup' do + service = described_class.new(user, group_path: 'a-group/a-sub-group') + + expect { service.execute }.to raise_error('Nested groups are not supported on MySQL') end - context 'adding a visibility level ' do - let(:params) { { group_path: 'a-group/a-sub-group', visibility_level: Gitlab::VisibilityLevel::PRIVATE } } + it_behaves_like 'with a visibility level' + end - it 'overwrites the visibility level' do - group = service.execute + describe 'with subgroups', :nested_groups do + let(:params) { { group_path: 'a-group/a-sub-group' } } - expect(group.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) + describe "#execute" do + it 'returns the group if it already existed' do + parent = create(:group, path: 'a-group', owner: user) + child = create(:group, path: 'a-sub-group', parent: parent, owner: user) + + expect(service.execute).to eq(child) end + + it 'reuses a parent if it already existed' do + parent = create(:group, path: 'a-group') + parent.add_owner(user) + + expect(service.execute.parent).to eq(parent) + end + + it 'creates group and subgroup in the database' do + service.execute + + parent = Group.find_by_full_path('a-group') + child = parent.children.find_by(path: 'a-sub-group') + + expect(parent).not_to be_nil + expect(child).not_to be_nil + end + + it_behaves_like 'with a visibility level' end end end diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb index e593bfeeaf7..5cfdb5372f3 100644 --- a/spec/services/merge_requests/merge_service_spec.rb +++ b/spec/services/merge_requests/merge_service_spec.rb @@ -217,7 +217,7 @@ describe MergeRequests::MergeService do it 'logs and saves error if there is an PreReceiveError exception' do error_message = 'error message' - allow(service).to receive(:repository).and_raise(GitHooksService::PreReceiveError, error_message) + allow(service).to receive(:repository).and_raise(Gitlab::Git::HooksService::PreReceiveError, error_message) allow(service).to receive(:execute_hooks) service.execute(merge_request) diff --git a/spec/services/tags/create_service_spec.rb b/spec/services/tags/create_service_spec.rb index 1b31ce29f7a..57013b54560 100644 --- a/spec/services/tags/create_service_spec.rb +++ b/spec/services/tags/create_service_spec.rb @@ -41,7 +41,7 @@ describe Tags::CreateService do it 'returns an error' do expect(repository).to receive(:add_tag) .with(user, 'v1.1.0', 'master', 'Foo') - .and_raise(GitHooksService::PreReceiveError, 'something went wrong') + .and_raise(Gitlab::Git::HooksService::PreReceiveError, 'something went wrong') response = service.execute('v1.1.0', 'master', 'Foo') diff --git a/spec/services/users/update_service_spec.rb b/spec/services/users/update_service_spec.rb index 985f6d94876..6ee35a33b2d 100644 --- a/spec/services/users/update_service_spec.rb +++ b/spec/services/users/update_service_spec.rb @@ -37,7 +37,10 @@ describe Users::UpdateService do describe '#execute!' do it 'updates the name' do - result = update_user(user, name: 'New Name') + service = described_class.new(user, name: 'New Name') + expect(service).not_to receive(:notify_new_user) + + result = service.execute! expect(result).to be true expect(user.name).to eq('New Name') @@ -49,6 +52,18 @@ describe Users::UpdateService do end.to raise_error(ActiveRecord::RecordInvalid) end + it 'fires system hooks when a new user is saved' do + system_hook_service = spy(:system_hook_service) + user = build(:user) + service = described_class.new(user, name: 'John Doe') + expect(service).to receive(:notify_new_user).and_call_original + expect(service).to receive(:system_hook_service).and_return(system_hook_service) + + service.execute + + expect(system_hook_service).to have_received(:execute_hooks_for).with(user, :create) + end + def update_user(user, opts) described_class.new(user, opts).execute! end diff --git a/spec/support/api_helpers.rb b/spec/support/api_helpers.rb index ac0aaa524b7..01aca74274c 100644 --- a/spec/support/api_helpers.rb +++ b/spec/support/api_helpers.rb @@ -45,18 +45,4 @@ module ApiHelpers oauth_access_token: oauth_access_token ) end - - def ci_api(path, user = nil) - "/ci/api/v1/#{path}" + - - # Normalize query string - (path.index('?') ? '' : '?') + - - # Append private_token if given a User object - if user.respond_to?(:private_token) - "&private_token=#{user.private_token}" - else - '' - end - end end diff --git a/vendor/assets/stylesheets/katex.scss b/vendor/assets/stylesheets/katex.scss index 9dd8a30bf51..b45836716f2 100644 --- a/vendor/assets/stylesheets/katex.scss +++ b/vendor/assets/stylesheets/katex.scss @@ -45,112 +45,112 @@ SOFTWARE. font-family: 'KaTeX_AMS'; src: url(font-path('KaTeX_AMS-Regular.eot')); src: url(font-path('KaTeX_AMS-Regular.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_AMS-Regular.woff2')) format('woff2'), url(font-path('KaTeX_AMS-Regular.woff')) format('woff'), url(font-path('KaTeX_AMS-Regular.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: normal; } @font-face { font-family: 'KaTeX_Caligraphic'; src: url(font-path('KaTeX_Caligraphic-Bold.eot')); src: url(font-path('KaTeX_Caligraphic-Bold.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Caligraphic-Bold.woff2')) format('woff2'), url(font-path('KaTeX_Caligraphic-Bold.woff')) format('woff'), url(font-path('KaTeX_Caligraphic-Bold.ttf')) format('truetype'); - font-weight: bold; + font-weight: 600; font-style: normal; } @font-face { font-family: 'KaTeX_Caligraphic'; src: url(font-path('KaTeX_Caligraphic-Regular.eot')); src: url(font-path('KaTeX_Caligraphic-Regular.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Caligraphic-Regular.woff2')) format('woff2'), url(font-path('KaTeX_Caligraphic-Regular.woff')) format('woff'), url(font-path('KaTeX_Caligraphic-Regular.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: normal; } @font-face { font-family: 'KaTeX_Fraktur'; src: url(font-path('KaTeX_Fraktur-Bold.eot')); src: url(font-path('KaTeX_Fraktur-Bold.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Fraktur-Bold.woff2')) format('woff2'), url(font-path('KaTeX_Fraktur-Bold.woff')) format('woff'), url(font-path('KaTeX_Fraktur-Bold.ttf')) format('truetype'); - font-weight: bold; + font-weight: 600; font-style: normal; } @font-face { font-family: 'KaTeX_Fraktur'; src: url(font-path('KaTeX_Fraktur-Regular.eot')); src: url(font-path('KaTeX_Fraktur-Regular.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Fraktur-Regular.woff2')) format('woff2'), url(font-path('KaTeX_Fraktur-Regular.woff')) format('woff'), url(font-path('KaTeX_Fraktur-Regular.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: normal; } @font-face { font-family: 'KaTeX_Main'; src: url(font-path('KaTeX_Main-Bold.eot')); src: url(font-path('KaTeX_Main-Bold.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Main-Bold.woff2')) format('woff2'), url(font-path('KaTeX_Main-Bold.woff')) format('woff'), url(font-path('KaTeX_Main-Bold.ttf')) format('truetype'); - font-weight: bold; + font-weight: 600; font-style: normal; } @font-face { font-family: 'KaTeX_Main'; src: url(font-path('KaTeX_Main-Italic.eot')); src: url(font-path('KaTeX_Main-Italic.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Main-Italic.woff2')) format('woff2'), url(font-path('KaTeX_Main-Italic.woff')) format('woff'), url(font-path('KaTeX_Main-Italic.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: italic; } @font-face { font-family: 'KaTeX_Main'; src: url(font-path('KaTeX_Main-Regular.eot')); src: url(font-path('KaTeX_Main-Regular.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Main-Regular.woff2')) format('woff2'), url(font-path('KaTeX_Main-Regular.woff')) format('woff'), url(font-path('KaTeX_Main-Regular.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: normal; } @font-face { font-family: 'KaTeX_Math'; src: url(font-path('KaTeX_Math-Italic.eot')); src: url(font-path('KaTeX_Math-Italic.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Math-Italic.woff2')) format('woff2'), url(font-path('KaTeX_Math-Italic.woff')) format('woff'), url(font-path('KaTeX_Math-Italic.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: italic; } @font-face { font-family: 'KaTeX_SansSerif'; src: url(font-path('KaTeX_SansSerif-Regular.eot')); src: url(font-path('KaTeX_SansSerif-Regular.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_SansSerif-Regular.woff2')) format('woff2'), url(font-path('KaTeX_SansSerif-Regular.woff')) format('woff'), url(font-path('KaTeX_SansSerif-Regular.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: normal; } @font-face { font-family: 'KaTeX_Script'; src: url(font-path('KaTeX_Script-Regular.eot')); src: url(font-path('KaTeX_Script-Regular.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Script-Regular.woff2')) format('woff2'), url(font-path('KaTeX_Script-Regular.woff')) format('woff'), url(font-path('KaTeX_Script-Regular.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: normal; } @font-face { font-family: 'KaTeX_Size1'; src: url(font-path('KaTeX_Size1-Regular.eot')); src: url(font-path('KaTeX_Size1-Regular.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Size1-Regular.woff2')) format('woff2'), url(font-path('KaTeX_Size1-Regular.woff')) format('woff'), url(font-path('KaTeX_Size1-Regular.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: normal; } @font-face { font-family: 'KaTeX_Size2'; src: url(font-path('KaTeX_Size2-Regular.eot')); src: url(font-path('KaTeX_Size2-Regular.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Size2-Regular.woff2')) format('woff2'), url(font-path('KaTeX_Size2-Regular.woff')) format('woff'), url(font-path('KaTeX_Size2-Regular.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: normal; } @font-face { font-family: 'KaTeX_Size3'; src: url(font-path('KaTeX_Size3-Regular.eot')); src: url(font-path('KaTeX_Size3-Regular.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Size3-Regular.woff2')) format('woff2'), url(font-path('KaTeX_Size3-Regular.woff')) format('woff'), url(font-path('KaTeX_Size3-Regular.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: normal; } @font-face { font-family: 'KaTeX_Size4'; src: url(font-path('KaTeX_Size4-Regular.eot')); src: url(font-path('KaTeX_Size4-Regular.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Size4-Regular.woff2')) format('woff2'), url(font-path('KaTeX_Size4-Regular.woff')) format('woff'), url(font-path('KaTeX_Size4-Regular.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: normal; } @font-face { font-family: 'KaTeX_Typewriter'; src: url(font-path('KaTeX_Typewriter-Regular.eot')); src: url(font-path('KaTeX_Typewriter-Regular.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Typewriter-Regular.woff2')) format('woff2'), url(font-path('KaTeX_Typewriter-Regular.woff')) format('woff'), url(font-path('KaTeX_Typewriter-Regular.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: normal; } .katex-display { @@ -192,7 +192,7 @@ SOFTWARE. } .katex .mathbf { font-family: KaTeX_Main; - font-weight: bold; + font-weight: 600; } .katex .amsrm { font-family: KaTeX_AMS; diff --git a/vendor/assets/stylesheets/xterm/xterm.css b/vendor/assets/stylesheets/xterm/xterm.css index b30d7b493f1..fabc51b0e3d 100644 --- a/vendor/assets/stylesheets/xterm/xterm.css +++ b/vendor/assets/stylesheets/xterm/xterm.css @@ -142,7 +142,7 @@ * Determine default colors for xterm.js */ .terminal .xterm-bold { - font-weight: bold; + font-weight: 600; } .terminal .xterm-underline { |