diff options
author | Achilleas Pipinellis <axilleas@axilleas.me> | 2016-01-12 12:11:25 +0100 |
---|---|---|
committer | Achilleas Pipinellis <axilleas@axilleas.me> | 2016-01-12 12:11:25 +0100 |
commit | e8cf990d87168484a386b18d9c14835039faa8cc (patch) | |
tree | e6c0acad843a7c6d631aa2cc4b9652e46e66fe14 | |
parent | acc86ac8575a12a2f7524c944db7cdb57c4f9f45 (diff) | |
parent | 587f850170a38e2642c0de76fb69efdeae930d66 (diff) | |
download | gitlab-ce-e8cf990d87168484a386b18d9c14835039faa8cc.tar.gz |
Merge branch 'master' into docs_refactor
91 files changed, 470 insertions, 278 deletions
diff --git a/CHANGELOG b/CHANGELOG index 04bcbf9dad2..175399fe1fa 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,7 +1,13 @@ Please view this file on the master branch, on stable branches it's out of date. v 8.4.0 (unreleased) + - Autocomplete data is now always loaded, instead of when focusing a comment text area (Yorick Peterse) + - Improved performance of finding issues for an entire group (Yorick Peterse) + - Added custom application performance measuring system powered by InfluxDB (Yorick Peterse) + - Bump fog to 1.36.0 (Stan Hu) + - Add housekeeping function to project settings page - The default GitLab logo now acts as a loading indicator + - Fix caching issue where build status was not updating in project dashboard (Stan Hu) - Accept 2xx status codes for successful Web hook triggers (Stan Hu) - Fix missing date of month in network graph when commits span a month (Stan Hu) - Expire view caches when application settings change (e.g. Gravatar disabled) (Stan Hu) @@ -24,6 +30,9 @@ v 8.4.0 (unreleased) - Show 'All' tab by default in the builds page - Add Open Graph and Twitter Card data to all pages - Fix API project lookups when querying with a namespace with dots (Stan Hu) + - Enable forcing Two-Factor authentication sitewide, with optional grace period + - Import GitHub Pull Requests into GitLab + - Change single user API endpoint to return more detailed data (Michael Potthoff) - Update version check images to use SVG - Validate README format before displaying - Enable Microsoft Azure OAuth2 support (Janis Meybohm) @@ -31,20 +40,23 @@ v 8.4.0 (unreleased) - Add file finder feature in tree view (Kyungchul Shin) - Ajax filter by message for commits page - API: Add support for deleting a tag via the API (Robert Schilling) + - Allow subsequent validations in CI Linter -v 8.3.3 (unreleased) +v 8.3.3 - Preserve CE behavior with JIRA integration by only calling API if URL is set + - Fix duplicated branch creation/deletion events when using Web UI (Stan Hu) + - Add configurable LDAP server query timeout - Get "Merge when build succeeds" to work when commits were pushed to MR target branch while builds were running - Suppress e-mails on failed builds if allow_failure is set (Stan Hu) - Fix project transfer e-mail sending incorrect paths in e-mail notification (Stan Hu) + - Better support for referencing and closing issues in Asana service (Mike Wyatt) - Enable "Add key" button when user fills in a proper key (Stan Hu) - Fix error in processing reply-by-email messages (Jason Lee) - Fix Error 500 when visiting build page of project with nil runners_token (Stan Hu) + - Use WOFF versions of SourceSansPro fonts + - Fix regression when builds were not generated for tags created through web/api interface v 8.3.2 - - Change single user API endpoint to return more detailed data (Michael Potthoff) - -v 8.3.2 (unreleased) - Disable --follow in `git log` to avoid loading duplicate commit data in infinite scroll (Stan Hu) - Add support for Google reCAPTCHA in user registration @@ -53,8 +65,6 @@ v 8.3.1 - Fix Error 500 when doing a search in dashboard before visiting any project (Stan Hu) - Fix LDAP identity and user retrieval when special characters are used - Move Sidekiq-cron configuration to gitlab.yml - - Enable forcing Two-Factor authentication sitewide, with optional grace period - - Import GitHub Pull Requests into GitLab v 8.3.0 - Bump rack-attack to 4.3.1 for security fix (Stan Hu) diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION index d48d3702aed..a04abec9149 100644 --- a/GITLAB_SHELL_VERSION +++ b/GITLAB_SHELL_VERSION @@ -1 +1 @@ -2.6.9 +2.6.10 diff --git a/GITLAB_WORKHORSE_VERSION b/GITLAB_WORKHORSE_VERSION index 4b9fcbec101..be14282b7ff 100644 --- a/GITLAB_WORKHORSE_VERSION +++ b/GITLAB_WORKHORSE_VERSION @@ -1 +1 @@ -0.5.1 +0.5.3 @@ -22,6 +22,7 @@ gem 'devise', '~> 3.5.3' gem 'devise-async', '~> 0.9.0' gem 'doorkeeper', '~> 2.2.0' gem 'omniauth', '~> 1.2.2' +gem 'omniauth-azure-oauth2', '~> 0.0.6' gem 'omniauth-bitbucket', '~> 0.0.2' gem 'omniauth-cas3', '~> 1.1.2' gem 'omniauth-facebook', '~> 3.0.0' @@ -32,8 +33,7 @@ gem 'omniauth-kerberos', '~> 0.3.0', group: :kerberos gem 'omniauth-saml', '~> 1.4.0' gem 'omniauth-shibboleth', '~> 1.2.0' gem 'omniauth-twitter', '~> 1.2.0' -gem 'omniauth_crowd' -gem 'omniauth-azure-oauth2' +gem 'omniauth_crowd', '~> 2.2.0' gem 'rack-oauth2', '~> 1.2.1' # reCAPTCHA protection @@ -80,7 +80,7 @@ gem "carrierwave", '~> 0.9.0' gem 'dropzonejs-rails', '~> 0.7.1' # for aws storage -gem "fog", "~> 1.25.0" +gem "fog", "~> 1.36.0" gem "unf", '~> 0.1.4' # Authorization diff --git a/Gemfile.lock b/Gemfile.lock index 96bf2bd1a2e..f1bba7f437e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -219,21 +219,45 @@ GEM flowdock (0.7.1) httparty (~> 0.7) multi_json - fog (1.25.0) + fog (1.36.0) + fog-aliyun (>= 0.1.0) + fog-atmos + fog-aws (>= 0.6.0) fog-brightbox (~> 0.4) - fog-core (~> 1.25) + fog-core (~> 1.32) + fog-dynect (~> 0.0.2) + fog-ecloud (~> 0.1) + fog-google (<= 0.1.0) fog-json + fog-local + fog-powerdns (>= 0.1.1) fog-profitbricks fog-radosgw (>= 0.0.2) + fog-riakcs fog-sakuracloud (>= 0.0.4) + fog-serverlove fog-softlayer + fog-storm_on_demand fog-terremark fog-vmfusion fog-voxel + fog-xenserver fog-xml (~> 0.1.1) ipaddress (~> 0.5) nokogiri (~> 1.5, >= 1.5.11) - opennebula + fog-aliyun (0.1.0) + fog-core (~> 1.27) + fog-json (~> 1.0) + ipaddress (~> 0.8) + xml-simple (~> 1.1) + fog-atmos (0.1.0) + fog-core + fog-xml + fog-aws (0.8.1) + fog-core (~> 1.27) + fog-json (~> 1.0) + fog-xml (~> 0.1) + ipaddress (~> 0.8) fog-brightbox (0.10.1) fog-core (~> 1.22) fog-json @@ -242,21 +266,48 @@ GEM builder excon (~> 0.45) formatador (~> 0.2) + fog-dynect (0.0.2) + fog-core + fog-json + fog-xml + fog-ecloud (0.3.0) + fog-core + fog-xml + fog-google (0.1.0) + fog-core + fog-json + fog-xml fog-json (1.0.2) fog-core (~> 1.0) multi_json (~> 1.10) + fog-local (0.2.1) + fog-core (~> 1.27) + fog-powerdns (0.1.1) + fog-core (~> 1.27) + fog-json (~> 1.0) + fog-xml (~> 0.1) fog-profitbricks (0.0.5) fog-core fog-xml nokogiri - fog-radosgw (0.0.4) + fog-radosgw (0.0.5) fog-core (>= 1.21.0) fog-json fog-xml (>= 0.0.1) - fog-sakuracloud (1.5.0) + fog-riakcs (0.1.0) + fog-core + fog-json + fog-xml + fog-sakuracloud (1.7.5) + fog-core + fog-json + fog-serverlove (0.1.2) + fog-core + fog-json + fog-softlayer (1.0.3) fog-core fog-json - fog-softlayer (1.0.2) + fog-storm_on_demand (0.1.1) fog-core fog-json fog-terremark (0.1.0) @@ -268,6 +319,9 @@ GEM fog-voxel (0.1.0) fog-core fog-xml + fog-xenserver (0.2.2) + fog-core + fog-xml fog-xml (0.1.2) fog-core nokogiri (~> 1.5, >= 1.5.11) @@ -377,7 +431,7 @@ GEM influxdb (0.2.3) cause json - ipaddress (0.8.0) + ipaddress (0.8.2) jquery-atwho-rails (1.3.2) jquery-rails (4.0.5) rails-dom-testing (~> 1.0) @@ -492,10 +546,6 @@ GEM activesupport nokogiri (>= 1.4.4) omniauth (~> 1.0) - opennebula (4.14.2) - json - nokogiri - rbvmomi org-ruby (0.9.12) rubypants (~> 0.2) orm_adapter (0.5.0) @@ -571,10 +621,6 @@ GEM ffi (>= 0.5.0) rblineprof (0.3.6) debugger-ruby_core_source (~> 1.3) - rbvmomi (1.8.2) - builder - nokogiri (>= 1.4.1) - trollop rdoc (3.12.2) json (~> 1.4) recaptcha (1.0.2) @@ -773,7 +819,6 @@ GEM multi_json (~> 1.7) twitter-stream (~> 0.1) tins (1.6.0) - trollop (2.1.2) turbolinks (2.5.3) coffee-rails twitter-stream (0.1.16) @@ -822,6 +867,7 @@ GEM builder expression_parser rinku + xml-simple (1.1.5) xpath (2.0.0) nokogiri (~> 1.3) @@ -877,7 +923,7 @@ DEPENDENCIES ffaker (~> 2.0.0) flay flog - fog (~> 1.25.0) + fog (~> 1.36.0) font-awesome-rails (~> 4.2) foreman fuubar (~> 2.0.0) @@ -919,7 +965,7 @@ DEPENDENCIES oauth2 (~> 1.0.0) octokit (~> 3.7.0) omniauth (~> 1.2.2) - omniauth-azure-oauth2 + omniauth-azure-oauth2 (~> 0.0.6) omniauth-bitbucket (~> 0.0.2) omniauth-cas3 (~> 1.1.2) omniauth-facebook (~> 3.0.0) @@ -930,7 +976,7 @@ DEPENDENCIES omniauth-saml (~> 1.4.0) omniauth-shibboleth (~> 1.2.0) omniauth-twitter (~> 1.2.0) - omniauth_crowd + omniauth_crowd (~> 2.2.0) org-ruby (~> 0.9.12) paranoia (~> 2.0) pg (~> 0.18.2) diff --git a/app/assets/fonts/OFL.txt b/app/assets/fonts/OFL.txt index a9b845ed1d4..df187637e18 100755 --- a/app/assets/fonts/OFL.txt +++ b/app/assets/fonts/OFL.txt @@ -1,7 +1,8 @@ -Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. +Copyright 2010, 2012, 2014 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -http://scripts.sil.org/OFL + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL ----------------------------------------------------------- diff --git a/app/assets/fonts/SourceSansPro-Black.ttf b/app/assets/fonts/SourceSansPro-Black.ttf Binary files differdeleted file mode 100644 index 9c9b5cb7f03..00000000000 --- a/app/assets/fonts/SourceSansPro-Black.ttf +++ /dev/null diff --git a/app/assets/fonts/SourceSansPro-Black.ttf.woff b/app/assets/fonts/SourceSansPro-Black.ttf.woff Binary files differnew file mode 100755 index 00000000000..b7e86200927 --- /dev/null +++ b/app/assets/fonts/SourceSansPro-Black.ttf.woff diff --git a/app/assets/fonts/SourceSansPro-BlackIt.ttf b/app/assets/fonts/SourceSansPro-BlackIt.ttf Binary files differdeleted file mode 100644 index 294ce5abe8f..00000000000 --- a/app/assets/fonts/SourceSansPro-BlackIt.ttf +++ /dev/null diff --git a/app/assets/fonts/SourceSansPro-BlackIt.ttf.woff b/app/assets/fonts/SourceSansPro-BlackIt.ttf.woff Binary files differnew file mode 100755 index 00000000000..c3314b1ef06 --- /dev/null +++ b/app/assets/fonts/SourceSansPro-BlackIt.ttf.woff diff --git a/app/assets/fonts/SourceSansPro-BlackItalic.ttf b/app/assets/fonts/SourceSansPro-BlackItalic.ttf Binary files differdeleted file mode 100755 index c719243c0d6..00000000000 --- a/app/assets/fonts/SourceSansPro-BlackItalic.ttf +++ /dev/null diff --git a/app/assets/fonts/SourceSansPro-Bold.ttf b/app/assets/fonts/SourceSansPro-Bold.ttf Binary files differdeleted file mode 100644 index 5d65c93242f..00000000000 --- a/app/assets/fonts/SourceSansPro-Bold.ttf +++ /dev/null diff --git a/app/assets/fonts/SourceSansPro-Bold.ttf.woff b/app/assets/fonts/SourceSansPro-Bold.ttf.woff Binary files differnew file mode 100755 index 00000000000..d1d40f840f8 --- /dev/null +++ b/app/assets/fonts/SourceSansPro-Bold.ttf.woff diff --git a/app/assets/fonts/SourceSansPro-BoldIt.ttf b/app/assets/fonts/SourceSansPro-BoldIt.ttf Binary files differdeleted file mode 100644 index 3decd130070..00000000000 --- a/app/assets/fonts/SourceSansPro-BoldIt.ttf +++ /dev/null diff --git a/app/assets/fonts/SourceSansPro-BoldIt.ttf.woff b/app/assets/fonts/SourceSansPro-BoldIt.ttf.woff Binary files differnew file mode 100755 index 00000000000..ef6ff514d3a --- /dev/null +++ b/app/assets/fonts/SourceSansPro-BoldIt.ttf.woff diff --git a/app/assets/fonts/SourceSansPro-BoldItalic.ttf b/app/assets/fonts/SourceSansPro-BoldItalic.ttf Binary files differdeleted file mode 100755 index d20dd0c5eca..00000000000 --- a/app/assets/fonts/SourceSansPro-BoldItalic.ttf +++ /dev/null diff --git a/app/assets/fonts/SourceSansPro-ExtraLight.ttf b/app/assets/fonts/SourceSansPro-ExtraLight.ttf Binary files differdeleted file mode 100644 index 253eafa3783..00000000000 --- a/app/assets/fonts/SourceSansPro-ExtraLight.ttf +++ /dev/null diff --git a/app/assets/fonts/SourceSansPro-ExtraLight.ttf.woff b/app/assets/fonts/SourceSansPro-ExtraLight.ttf.woff Binary files differnew file mode 100755 index 00000000000..1e6c94d9eb3 --- /dev/null +++ b/app/assets/fonts/SourceSansPro-ExtraLight.ttf.woff diff --git a/app/assets/fonts/SourceSansPro-ExtraLightIt.ttf b/app/assets/fonts/SourceSansPro-ExtraLightIt.ttf Binary files differdeleted file mode 100644 index 00d7e9a7aa8..00000000000 --- a/app/assets/fonts/SourceSansPro-ExtraLightIt.ttf +++ /dev/null diff --git a/app/assets/fonts/SourceSansPro-ExtraLightIt.ttf.woff b/app/assets/fonts/SourceSansPro-ExtraLightIt.ttf.woff Binary files differnew file mode 100755 index 00000000000..7a408b1ec73 --- /dev/null +++ b/app/assets/fonts/SourceSansPro-ExtraLightIt.ttf.woff diff --git a/app/assets/fonts/SourceSansPro-ExtraLightItalic.ttf b/app/assets/fonts/SourceSansPro-ExtraLightItalic.ttf Binary files differdeleted file mode 100755 index 2c34f3b8dc4..00000000000 --- a/app/assets/fonts/SourceSansPro-ExtraLightItalic.ttf +++ /dev/null diff --git a/app/assets/fonts/SourceSansPro-It.ttf b/app/assets/fonts/SourceSansPro-It.ttf Binary files differdeleted file mode 100644 index f7af5377595..00000000000 --- a/app/assets/fonts/SourceSansPro-It.ttf +++ /dev/null diff --git a/app/assets/fonts/SourceSansPro-It.ttf.woff b/app/assets/fonts/SourceSansPro-It.ttf.woff Binary files differnew file mode 100755 index 00000000000..4d54bc95718 --- /dev/null +++ b/app/assets/fonts/SourceSansPro-It.ttf.woff diff --git a/app/assets/fonts/SourceSansPro-Italic.ttf b/app/assets/fonts/SourceSansPro-Italic.ttf Binary files differdeleted file mode 100755 index e5a1a86e631..00000000000 --- a/app/assets/fonts/SourceSansPro-Italic.ttf +++ /dev/null diff --git a/app/assets/fonts/SourceSansPro-Light.ttf b/app/assets/fonts/SourceSansPro-Light.ttf Binary files differdeleted file mode 100644 index 83a0a336661..00000000000 --- a/app/assets/fonts/SourceSansPro-Light.ttf +++ /dev/null diff --git a/app/assets/fonts/SourceSansPro-Light.ttf.woff b/app/assets/fonts/SourceSansPro-Light.ttf.woff Binary files differnew file mode 100755 index 00000000000..1706d57d3c5 --- /dev/null +++ b/app/assets/fonts/SourceSansPro-Light.ttf.woff diff --git a/app/assets/fonts/SourceSansPro-LightIt.ttf b/app/assets/fonts/SourceSansPro-LightIt.ttf Binary files differdeleted file mode 100644 index f18827985ef..00000000000 --- a/app/assets/fonts/SourceSansPro-LightIt.ttf +++ /dev/null diff --git a/app/assets/fonts/SourceSansPro-LightIt.ttf.woff b/app/assets/fonts/SourceSansPro-LightIt.ttf.woff Binary files differnew file mode 100755 index 00000000000..87378d6c609 --- /dev/null +++ b/app/assets/fonts/SourceSansPro-LightIt.ttf.woff diff --git a/app/assets/fonts/SourceSansPro-LightItalic.ttf b/app/assets/fonts/SourceSansPro-LightItalic.ttf Binary files differdeleted file mode 100755 index 88a6778d24f..00000000000 --- a/app/assets/fonts/SourceSansPro-LightItalic.ttf +++ /dev/null diff --git a/app/assets/fonts/SourceSansPro-Regular.ttf b/app/assets/fonts/SourceSansPro-Regular.ttf Binary files differdeleted file mode 100644 index 44486cdc670..00000000000 --- a/app/assets/fonts/SourceSansPro-Regular.ttf +++ /dev/null diff --git a/app/assets/fonts/SourceSansPro-Regular.ttf.woff b/app/assets/fonts/SourceSansPro-Regular.ttf.woff Binary files differnew file mode 100755 index 00000000000..460ab12a638 --- /dev/null +++ b/app/assets/fonts/SourceSansPro-Regular.ttf.woff diff --git a/app/assets/fonts/SourceSansPro-Semibold.ttf b/app/assets/fonts/SourceSansPro-Semibold.ttf Binary files differdeleted file mode 100644 index 86b00c067e0..00000000000 --- a/app/assets/fonts/SourceSansPro-Semibold.ttf +++ /dev/null diff --git a/app/assets/fonts/SourceSansPro-Semibold.ttf.woff b/app/assets/fonts/SourceSansPro-Semibold.ttf.woff Binary files differnew file mode 100755 index 00000000000..43379631b2d --- /dev/null +++ b/app/assets/fonts/SourceSansPro-Semibold.ttf.woff diff --git a/app/assets/fonts/SourceSansPro-SemiboldIt.ttf b/app/assets/fonts/SourceSansPro-SemiboldIt.ttf Binary files differdeleted file mode 100644 index 13d66a1fc45..00000000000 --- a/app/assets/fonts/SourceSansPro-SemiboldIt.ttf +++ /dev/null diff --git a/app/assets/fonts/SourceSansPro-SemiboldIt.ttf.woff b/app/assets/fonts/SourceSansPro-SemiboldIt.ttf.woff Binary files differnew file mode 100755 index 00000000000..232c2048ae7 --- /dev/null +++ b/app/assets/fonts/SourceSansPro-SemiboldIt.ttf.woff diff --git a/app/assets/fonts/SourceSansPro-SemiboldItalic.ttf b/app/assets/fonts/SourceSansPro-SemiboldItalic.ttf Binary files differdeleted file mode 100755 index 2c5ad3008c3..00000000000 --- a/app/assets/fonts/SourceSansPro-SemiboldItalic.ttf +++ /dev/null diff --git a/app/assets/javascripts/gfm_auto_complete.js.coffee b/app/assets/javascripts/gfm_auto_complete.js.coffee index 7967892f856..4718bcf7a1e 100644 --- a/app/assets/javascripts/gfm_auto_complete.js.coffee +++ b/app/assets/javascripts/gfm_auto_complete.js.coffee @@ -34,7 +34,7 @@ GitLab.GfmAutoComplete = searchKey: 'search' callbacks: beforeSave: (members) -> - $.map members, (m) -> + $.map members, (m) -> title = m.name title += " (#{m.count})" if m.count @@ -50,7 +50,7 @@ GitLab.GfmAutoComplete = insertTpl: '${atwho-at}${id}' callbacks: beforeSave: (issues) -> - $.map issues, (i) -> + $.map issues, (i) -> id: i.iid title: sanitize(i.title) search: "#{i.iid} #{i.title}" @@ -63,12 +63,12 @@ GitLab.GfmAutoComplete = insertTpl: '${atwho-at}${id}' callbacks: beforeSave: (merges) -> - $.map merges, (m) -> + $.map merges, (m) -> id: m.iid title: sanitize(m.title) search: "#{m.iid} #{m.title}" - input.one 'focus', => + if @dataSource $.getJSON(@dataSource).done (data) -> # load members input.atwho 'load', '@', data.members diff --git a/app/assets/javascripts/logo.js.coffee b/app/assets/javascripts/logo.js.coffee index e864a674cdd..a5879c8b793 100644 --- a/app/assets/javascripts/logo.js.coffee +++ b/app/assets/javascripts/logo.js.coffee @@ -21,6 +21,7 @@ start = -> clearHighlights() pieceIndex = 0 pieces.reverse() unless pieces[0] == firstPiece + clearInterval(currentTimer) if currentTimer currentTimer = setInterval(work, delay) stop = -> diff --git a/app/assets/javascripts/zen_mode.js.coffee b/app/assets/javascripts/zen_mode.js.coffee index a1462cf3cae..e1c5446eaac 100644 --- a/app/assets/javascripts/zen_mode.js.coffee +++ b/app/assets/javascripts/zen_mode.js.coffee @@ -1,56 +1,80 @@ +# Zen Mode (full screen) textarea +# +#= provides zen_mode:enter +#= provides zen_mode:leave +# +#= require jquery.scrollTo #= require dropzone #= require mousetrap #= require mousetrap/pause - +# +# ### Events +# +# `zen_mode:enter` +# +# Fired when the "Edit in fullscreen" link is clicked. +# +# **Synchronicity** Sync +# **Bubbles** Yes +# **Cancelable** No +# **Target** a.js-zen-enter +# +# `zen_mode:leave` +# +# Fired when the "Leave Fullscreen" link is clicked. +# +# **Synchronicity** Sync +# **Bubbles** Yes +# **Cancelable** No +# **Target** a.js-zen-leave +# class @ZenMode constructor: -> - @active_zen_area = null - @active_checkbox = null - @scroll_position = 0 - - $(window).scroll => - if not @active_checkbox - @scroll_position = window.pageYOffset + @active_backdrop = null + @active_textarea = null - $('body').on 'click', '.zen-enter-link', (e) => + $(document).on 'click', '.js-zen-enter', (e) -> e.preventDefault() - $(e.currentTarget).closest('.zennable').find('.zen-toggle-comment').prop('checked', true).change() + $(e.currentTarget).trigger('zen_mode:enter') - $('body').on 'click', '.zen-leave-link', (e) => + $(document).on 'click', '.js-zen-leave', (e) -> e.preventDefault() - $(e.currentTarget).closest('.zennable').find('.zen-toggle-comment').prop('checked', false).change() - - $('body').on 'change', '.zen-toggle-comment', (e) => - checkbox = e.currentTarget - if checkbox.checked - # Disable other keyboard shortcuts in ZEN mode - Mousetrap.pause() - @updateActiveZenArea(checkbox) - else - @exitZenMode() - - $(document).on 'keydown', (e) => - if e.keyCode is 27 # Esc - @exitZenMode() + $(e.currentTarget).trigger('zen_mode:leave') + + $(document).on 'zen_mode:enter', (e) => + @enter(e.target.parentNode) + $(document).on 'zen_mode:leave', (e) => + @exit() + + $(document).on 'keydown', (e) -> + if e.keyCode == 27 # Esc e.preventDefault() + $(document).trigger('zen_mode:leave') + + enter: (backdrop) -> + Mousetrap.pause() + + @active_backdrop = $(backdrop) + @active_backdrop.addClass('fullscreen') + + @active_textarea = @active_backdrop.find('textarea') - updateActiveZenArea: (checkbox) => - @active_checkbox = $(checkbox) - @active_checkbox.prop('checked', true) - @active_zen_area = @active_checkbox.parent().find('textarea') # Prevent a user-resized textarea from persisting to fullscreen - @active_zen_area.removeAttr('style') - @active_zen_area.focus() + @active_textarea.removeAttr('style') + @active_textarea.focus() - exitZenMode: => - if @active_zen_area isnt null + exit: -> + if @active_textarea Mousetrap.unpause() - @active_checkbox.prop('checked', false) - @active_zen_area = null - @active_checkbox = null - @restoreScroll(@scroll_position) - # Enable dropzone when leaving ZEN mode + + @active_textarea.closest('.zen-backdrop').removeClass('fullscreen') + + @scrollTo(@active_textarea) + + @active_textarea = null + @active_backdrop = null + Dropzone.forElement('.div-dropzone').enable() - restoreScroll: (y) -> - window.scrollTo(window.pageXOffset, y) + scrollTo: (zen_area) -> + $.scrollTo(zen_area, 0, offset: -150) diff --git a/app/assets/stylesheets/framework/fonts.scss b/app/assets/stylesheets/framework/fonts.scss index e214567eca1..20988f7b430 100644 --- a/app/assets/stylesheets/framework/fonts.scss +++ b/app/assets/stylesheets/framework/fonts.scss @@ -3,23 +3,23 @@ font-family: 'Source Sans Pro'; font-style: normal; font-weight: 300; - src: local('Source Sans Pro Light'), local('SourceSansPro-Light'), font-url('SourceSansPro-Light.ttf'); + src: local('Source Sans Pro Light'), local('SourceSansPro-Light'), font-url('SourceSansPro-Light.ttf.woff'); } @font-face { font-family: 'Source Sans Pro'; font-style: normal; font-weight: 400; - src: local('Source Sans Pro'), local('SourceSansPro-Regular'), font-url('SourceSansPro-Regular.ttf'); + src: local('Source Sans Pro'), local('SourceSansPro-Regular'), font-url('SourceSansPro-Regular.ttf.woff'); } @font-face { font-family: 'Source Sans Pro'; font-style: normal; font-weight: 600; - src: local('Source Sans Pro Semibold'), local('SourceSansPro-Semibold'), font-url('SourceSansPro-Semibold.ttf'); + src: local('Source Sans Pro Semibold'), local('SourceSansPro-Semibold'), font-url('SourceSansPro-Semibold.ttf.woff'); } @font-face { font-family: 'Source Sans Pro'; font-style: normal; font-weight: 700; - src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), font-url('SourceSansPro-Bold.ttf'); + src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), font-url('SourceSansPro-Bold.ttf.woff'); } diff --git a/app/assets/stylesheets/framework/zen.scss b/app/assets/stylesheets/framework/zen.scss index 32e2c020e06..002bd7e8ca5 100644 --- a/app/assets/stylesheets/framework/zen.scss +++ b/app/assets/stylesheets/framework/zen.scss @@ -1,9 +1,5 @@ .zennable { - .zen-toggle-comment { - display: none; - } - - .zen-enter-link { + a.js-zen-enter { color: $gl-gray; position: absolute; top: 0px; @@ -11,7 +7,7 @@ line-height: 40px; } - .zen-leave-link { + a.js-zen-leave { display: none; color: $gl-text-color; position: absolute; @@ -25,62 +21,41 @@ } } - // Hide the Enter link when we're in Zen mode - input:checked ~ .zen-backdrop .zen-enter-link { - display: none; - } - - // Show the Leave link when we're in Zen mode - input:checked ~ .zen-backdrop .zen-leave-link { - display: block; - position: absolute; - top: 0; - } - - input:checked ~ .zen-backdrop { - background-color: white; - position: fixed; - top: 0; - bottom: 0; - left: 0; - right: 0; - z-index: 1031; - - textarea { - border: none; - box-shadow: none; - border-radius: 0; - color: #000; - font-size: 20px; - line-height: 26px; - padding: 30px; - display: block; - outline: none; - resize: none; - height: 100vh; - max-width: 900px; - margin: 0 auto; + .zen-backdrop { + &.fullscreen { + background-color: white; + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + z-index: 1031; + + textarea { + border: none; + box-shadow: none; + border-radius: 0; + color: #000; + font-size: 20px; + line-height: 26px; + padding: 30px; + display: block; + outline: none; + resize: none; + height: 100vh; + max-width: 900px; + margin: 0 auto; + } + + a.js-zen-enter { + display: none; + } + + a.js-zen-leave { + display: block; + position: absolute; + top: 0; + } } } - - // Make the color of the placeholder text in the Zenned-out textarea darker, - // so it becomes visible - - input:checked ~ .zen-backdrop textarea::-webkit-input-placeholder { - color: #A8A8A8; - } - - input:checked ~ .zen-backdrop textarea:-moz-placeholder { - color: #A8A8A8; - opacity: 1; - } - - input:checked ~ .zen-backdrop textarea::-moz-placeholder { - color: #A8A8A8; - opacity: 1; - } - - input:checked ~ .zen-backdrop textarea:-ms-input-placeholder { - color: #A8A8A8; - } } diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index 0133a0d6822..f24b71963a8 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -295,10 +295,9 @@ border: 1px solid #c6cacf !important; background-color: #e4e7ed !important; - text-transform: uppercase; + text-transform: none; color: #313236 !important; - font-size: 13px; - font-weight: 600; + font-size: 15px; } .dropdown-menu { @@ -411,11 +410,15 @@ ul.nav.nav-projects-tabs { } } +.last-push-widget { + margin-top: -1px; +} + .top-area { border-bottom: 1px solid #EEE; margin: 0 -16px; padding: 0 $gl-padding; - height: 57px; + height: 42px; ul.left-top-menu { display: inline-block; @@ -522,6 +525,7 @@ pre.light-well { .projects-search-form { margin: -$gl-padding; padding: $gl-padding; + padding-bottom: 0; margin-bottom: 0px; input { diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index d9a37a4d45f..81cb1367e2c 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -286,7 +286,7 @@ class ApplicationController < ActionController::Base end def set_filters_params - params[:sort] ||= 'created_desc' + params[:sort] ||= 'id_desc' params[:scope] = 'all' if params[:scope].blank? params[:state] = 'opened' if params[:state].blank? diff --git a/app/controllers/ci/lints_controller.rb b/app/controllers/ci/lints_controller.rb index e782a51e7eb..a7af3cb8345 100644 --- a/app/controllers/ci/lints_controller.rb +++ b/app/controllers/ci/lints_controller.rb @@ -6,11 +6,13 @@ module Ci end def create - if params[:content].blank? + @content = params[:content] + + if @content.blank? @status = false @error = "Please provide content of .gitlab-ci.yml" else - @config_processor = Ci::GitlabCiYamlProcessor.new params[:content] + @config_processor = Ci::GitlabCiYamlProcessor.new(@content) @stages = @config_processor.stages @builds = @config_processor.builds @status = true diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 3004722bce0..935f7d75c6a 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -8,7 +8,7 @@ class ProjectsController < ApplicationController before_action :assign_ref_vars, :tree, only: [:show], if: :repo_exists? # Authorize - before_action :authorize_admin_project!, only: [:edit, :update] + before_action :authorize_admin_project!, only: [:edit, :update, :housekeeping] before_action :event_filter, only: [:show, :activity] layout :determine_layout @@ -166,6 +166,15 @@ class ProjectsController < ApplicationController end end + def housekeeping + ::Projects::HousekeepingService.new(@project).execute + + respond_to do |format| + flash[:notice] = "Housekeeping successfully started." + format.html { redirect_to project_path(@project) } + end + end + def toggle_star current_user.toggle_star(@project) @project.reload diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb index 3d5e8b6fbe7..4d56b48e3f8 100644 --- a/app/finders/issuable_finder.rb +++ b/app/finders/issuable_finder.rb @@ -79,9 +79,9 @@ class IssuableFinder if project? @projects = project elsif current_user && params[:authorized_only].presence && !current_user_related? - @projects = current_user.authorized_projects + @projects = current_user.authorized_projects.reorder(nil) else - @projects = ProjectsFinder.new.execute(current_user) + @projects = ProjectsFinder.new.execute(current_user).reorder(nil) end end diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index a7080ddfefb..43262d579e9 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -103,9 +103,12 @@ module IssuesHelper content_tag :div, "", class: "icon emoji-icon emoji-#{unicode}", - "data-emoji" => name, - "data-aliases" => aliases.join(" "), - "data-unicode-name" => unicode + title: name, + data: { + aliases: aliases.join(' '), + emoji: name, + unicode_name: unicode + } end def emoji_author_list(notes, current_user) diff --git a/app/helpers/sorting_helper.rb b/app/helpers/sorting_helper.rb index 99d7df64a83..241179b0212 100644 --- a/app/helpers/sorting_helper.rb +++ b/app/helpers/sorting_helper.rb @@ -63,11 +63,11 @@ module SortingHelper end def sort_value_oldest_created - 'created_asc' + 'id_asc' end def sort_value_recently_created - 'created_desc' + 'id_desc' end def sort_value_milestone_soon diff --git a/app/models/concerns/sortable.rb b/app/models/concerns/sortable.rb index 7391a77383c..8b47b9e0abd 100644 --- a/app/models/concerns/sortable.rb +++ b/app/models/concerns/sortable.rb @@ -11,6 +11,7 @@ module Sortable default_scope { order_id_desc } scope :order_id_desc, -> { reorder(id: :desc) } + scope :order_id_asc, -> { reorder(id: :asc) } scope :order_created_desc, -> { reorder(created_at: :desc) } scope :order_created_asc, -> { reorder(created_at: :asc) } scope :order_updated_desc, -> { reorder(updated_at: :desc) } @@ -28,6 +29,8 @@ module Sortable when 'updated_desc' then order_updated_desc when 'created_asc' then order_created_asc when 'created_desc' then order_created_desc + when 'id_desc' then order_id_desc + when 'id_asc' then order_id_asc else all end diff --git a/app/models/issue.rb b/app/models/issue.rb index 80ecd15077f..f52e47f3e62 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -33,7 +33,9 @@ class Issue < ActiveRecord::Base belongs_to :project validates :project, presence: true - scope :of_group, ->(group) { where(project_id: group.project_ids) } + scope :of_group, + ->(group) { where(project_id: group.projects.select(:id).reorder(nil)) } + scope :cared, ->(user) { where(assignee_id: user) } scope :open_for, ->(user) { opened.assigned_to(user) } diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 5723ff36e02..c63d0c01653 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -131,7 +131,7 @@ class MergeRequest < ActiveRecord::Base validate :validate_branches validate :validate_fork - scope :of_group, ->(group) { where("source_project_id in (:group_project_ids) OR target_project_id in (:group_project_ids)", group_project_ids: group.project_ids) } + scope :of_group, ->(group) { where("source_project_id in (:group_project_ids) OR target_project_id in (:group_project_ids)", group_project_ids: group.projects.select(:id).reorder(nil)) } scope :by_branch, ->(branch_name) { where("(source_branch LIKE :branch) OR (target_branch LIKE :branch)", branch: branch_name) } scope :cared, ->(user) { where('assignee_id = :user OR author_id = :user', user: user.id) } scope :by_milestone, ->(milestone) { where(milestone_id: milestone) } diff --git a/app/services/create_branch_service.rb b/app/services/create_branch_service.rb index f139872c728..c0e08a151f2 100644 --- a/app/services/create_branch_service.rb +++ b/app/services/create_branch_service.rb @@ -31,7 +31,6 @@ class CreateBranchService < BaseService if new_branch push_data = build_push_data(project, current_user, new_branch) - EventCreateService.new.push(project, current_user, push_data) project.execute_hooks(push_data.dup, :push_hooks) project.execute_services(push_data.dup, :push_hooks) diff --git a/app/services/create_tag_service.rb b/app/services/create_tag_service.rb index 2452999382a..55985380d31 100644 --- a/app/services/create_tag_service.rb +++ b/app/services/create_tag_service.rb @@ -23,6 +23,7 @@ class CreateTagService < BaseService EventCreateService.new.push(project, current_user, push_data) project.execute_hooks(push_data.dup, :tag_push_hooks) project.execute_services(push_data.dup, :tag_push_hooks) + CreateCommitBuildsService.new.execute(project, current_user, push_data) if release_description CreateReleaseService.new(@project, @current_user). diff --git a/app/services/delete_branch_service.rb b/app/services/delete_branch_service.rb index 22bf9dd935e..004b3ce7286 100644 --- a/app/services/delete_branch_service.rb +++ b/app/services/delete_branch_service.rb @@ -27,7 +27,6 @@ class DeleteBranchService < BaseService if repository.rm_branch(current_user, branch_name) push_data = build_push_data(branch) - EventCreateService.new.push(project, current_user, push_data) project.execute_hooks(push_data.dup, :push_hooks) project.execute_services(push_data.dup, :push_hooks) diff --git a/app/services/projects/housekeeping_service.rb b/app/services/projects/housekeeping_service.rb new file mode 100644 index 00000000000..0db85ac2142 --- /dev/null +++ b/app/services/projects/housekeeping_service.rb @@ -0,0 +1,20 @@ +# Projects::HousekeepingService class +# +# Used for git housekeeping +# +# Ex. +# Projects::HousekeepingService.new(project).execute +# +module Projects + class HousekeepingService < BaseService + include Gitlab::ShellAdapter + + def initialize(project) + @project = project + end + + def execute + GitlabShellWorker.perform_async(:gc, @project.path_with_namespace) + end + end +end diff --git a/app/views/ci/lints/show.html.haml b/app/views/ci/lints/show.html.haml index a144c43be47..0044d779c31 100644 --- a/app/views/ci/lints/show.html.haml +++ b/app/views/ci/lints/show.html.haml @@ -4,12 +4,12 @@ .row = form_tag ci_lint_path, method: :post do .form-group - = label_tag :content, 'Content of .gitlab-ci.yml', class: 'control-label text-nowrap' + = label_tag(:content, 'Content of .gitlab-ci.yml', class: 'control-label text-nowrap') .col-sm-12 - = text_area_tag :content, nil, class: 'form-control span1', rows: 7, require: true + = text_area_tag(:content, @content, class: 'form-control span1', rows: 7, require: true) .col-sm-12 .pull-left.prepend-top-10 - = submit_tag 'Validate', class: 'btn btn-success submit-yml' + = submit_tag('Validate', class: 'btn btn-success submit-yml') .row.prepend-top-20 .col-sm-12 diff --git a/app/views/events/_event_last_push.html.haml b/app/views/events/_event_last_push.html.haml index ffc37ad6178..abea86b026a 100644 --- a/app/views/events/_event_last_push.html.haml +++ b/app/views/events/_event_last_push.html.haml @@ -1,5 +1,5 @@ - if show_last_push_widget?(event) - .gray-content-block.clear-block + .gray-content-block.clear-block.last-push-widget .event-last-push .event-last-push-text %span You pushed to diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index a607d860d7d..48a544fc834 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -6,6 +6,12 @@ = auto_discovery_link_tag(:atom, group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity") .cover-block + .cover-controls + - if @group && can?(current_user, :admin_group, @group) + = link_to icon('pencil'), edit_group_path(@group), class: 'btn' + - if current_user + = link_to icon('rss'), group_path(@group, { format: :atom, private_token: current_user.private_token }), title: "Feed", class: 'btn rss-btn' + .avatar-holder = link_to group_icon(@group), target: '_blank' do = image_tag group_icon(@group), class: "avatar group-avatar s90" @@ -34,9 +40,6 @@ .gray-content-block.activity-filter-block - if current_user = render "events/event_last_push", event: @last_push - .pull-right - = link_to group_path(@group, { format: :atom, private_token: current_user.private_token }), title: "Feed", class: 'btn rss-btn' do - %i.fa.fa-rss = render 'shared/event_filter' diff --git a/app/views/layouts/_init_auto_complete.html.haml b/app/views/layouts/_init_auto_complete.html.haml index 035fe0056d3..96b38485425 100644 --- a/app/views/layouts/_init_auto_complete.html.haml +++ b/app/views/layouts/_init_auto_complete.html.haml @@ -1,4 +1,6 @@ - project = @target_project || @project -:javascript - GitLab.GfmAutoComplete.dataSource = "#{autocomplete_sources_namespace_project_path(project.namespace, project, type: @noteable.class, type_id: params[:id])}" - GitLab.GfmAutoComplete.setup(); + +- if @noteable + :javascript + GitLab.GfmAutoComplete.dataSource = "#{autocomplete_sources_namespace_project_path(project.namespace, project, type: @noteable.class, type_id: params[:id])}" + GitLab.GfmAutoComplete.setup(); diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml index 0f61e623396..53eec76129b 100644 --- a/app/views/projects/_home_panel.html.haml +++ b/app/views/projects/_home_panel.html.haml @@ -52,5 +52,5 @@ = render 'projects/buttons/notifications' -:coffeescript - new Star()
\ No newline at end of file +:javascript + new Star(); diff --git a/app/views/projects/_zen.html.haml b/app/views/projects/_zen.html.haml index 7e6301abde8..d5829568275 100644 --- a/app/views/projects/_zen.html.haml +++ b/app/views/projects/_zen.html.haml @@ -1,13 +1,12 @@ .zennable - %input#zen-toggle-comment.zen-toggle-comment(tabindex="-1" type="checkbox") .zen-backdrop - classes << ' js-gfm-input markdown-area' - if defined?(f) && f - = f.text_area attr, class: classes, placeholder: '' + = f.text_area attr, class: classes - else - = text_area_tag attr, nil, class: classes, placeholder: '' - %a.zen-enter-link(tabindex="-1" href="#") + = text_area_tag attr, nil, class: classes + %a.js-zen-enter(tabindex="-1" href="#") = icon('expand') Edit in fullscreen - %a.zen-leave-link(href="#") + %a.js-zen-leave(tabindex="-1" href="#") = icon('compress') diff --git a/app/views/projects/builds/index.html.haml b/app/views/projects/builds/index.html.haml index 2fa5ad80fda..3bbfdb1e3b0 100644 --- a/app/views/projects/builds/index.html.haml +++ b/app/views/projects/builds/index.html.haml @@ -40,7 +40,7 @@ %thead %tr %th Status - %th Runner + %th Build ID %th Commit %th Ref %th Stage diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index 650629ef1b9..31e752c6649 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -174,6 +174,19 @@ .danger-settings + .panel.panel-default + .panel-heading Housekeeping + .errors-holder + .panel-body + %p + Runs a number of housekeeping tasks within the current repository, + such as compressing file revisions and removing unreachable objects. + %br + + .form-actions + = link_to 'Housekeeping', housekeeping_namespace_project_path(@project.namespace, @project), + method: :post, class: "btn btn-default" + - if can? current_user, :archive_project, @project - if @project.archived? .panel.panel-success diff --git a/app/views/projects/find_file/show.html.haml b/app/views/projects/find_file/show.html.haml index 2930209fb56..40a2a61d8a1 100644 --- a/app/views/projects/find_file/show.html.haml +++ b/app/views/projects/find_file/show.html.haml @@ -18,10 +18,10 @@ %tbody = spinner nil, true -:coffeescript - projectFindFile = new ProjectFindFile($(".file-finder-holder"), { - url: "#{escape_javascript(namespace_project_files_path(@project.namespace, @project, @ref, @options.merge(format: :json)))}" - treeUrl: "#{escape_javascript(namespace_project_tree_path(@project.namespace, @project, @ref))}" +:javascript + var projectFindFile = new ProjectFindFile($(".file-finder-holder"), { + url: "#{escape_javascript(namespace_project_files_path(@project.namespace, @project, @ref, @options.merge(format: :json)))}", + treeUrl: "#{escape_javascript(namespace_project_tree_path(@project.namespace, @project, @ref))}", blobUrlTemplate: "#{escape_javascript(namespace_project_blob_path(@project.namespace, @project, @id || @commit.id))}" - }) - new ShortcutsFindFile(projectFindFile) + }); + new ShortcutsFindFile(projectFindFile); diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml index be06738eac9..0e3e9275fc1 100644 --- a/app/views/shared/issuable/_filter.html.haml +++ b/app/views/shared/issuable/_filter.html.haml @@ -1,25 +1,29 @@ .issues-filters .issues-state-filters %ul.center-top-menu + - if defined?(type) && type == :merge_requests + - page_context_word = 'merge requests' + - else + - page_context_word = 'issues' %li{class: ("active" if params[:state] == 'opened')} - = link_to page_filter_path(state: 'opened') do + = link_to page_filter_path(state: 'opened'), title: "Filter by #{page_context_word} that are currently opened." do #{state_filters_text_for(:opened, @project)} - if defined?(type) && type == :merge_requests %li{class: ("active" if params[:state] == 'merged')} - = link_to page_filter_path(state: 'merged') do + = link_to page_filter_path(state: 'merged'), title: 'Filter by merge requests that are currently merged.' do #{state_filters_text_for(:merged, @project)} %li{class: ("active" if params[:state] == 'closed')} - = link_to page_filter_path(state: 'closed') do + = link_to page_filter_path(state: 'closed'), title: 'Filter by merge requests that are currently closed and unmerged.' do #{state_filters_text_for(:closed, @project)} - else %li{class: ("active" if params[:state] == 'closed')} - = link_to page_filter_path(state: 'closed') do + = link_to page_filter_path(state: 'closed'), title: 'Filter by issues that are currently closed.' do #{state_filters_text_for(:closed, @project)} %li{class: ("active" if params[:state] == 'all')} - = link_to page_filter_path(state: 'all') do + = link_to page_filter_path(state: 'all'), title: "Show all #{page_context_word}." do #{state_filters_text_for(:all, @project)} .issues-details-filters.gray-content-block diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml index 86249851a82..5db8056b77c 100644 --- a/app/views/shared/projects/_project.html.haml +++ b/app/views/shared/projects/_project.html.haml @@ -4,8 +4,12 @@ - skip_namespace = false unless local_assigns[:skip_namespace] == true - css_class = '' unless local_assigns[:css_class] - css_class += " no-description" unless project.description.present? +- ci_commit = project.ci_commit(project.commit.sha) if ci && !project.empty_repo? && project.commit +- cache_key = [project.namespace, project, controller.controller_name, controller.action_name, current_application_settings, 'v2.2'] +- cache_key.push(ci_commit.status) if ci_commit + %li.project-row{ class: css_class } - = cache [project.namespace, project, controller.controller_name, controller.action_name, current_application_settings, 'v2.2'] do + = cache(cache_key) do = link_to project_path(project), class: dom_class(project) do - if avatar .dash-project-avatar @@ -19,10 +23,9 @@ = project.name .project-controls - - if ci && !project.empty_repo? && project.commit - - if ci_commit = project.ci_commit(project.commit.sha) - = render_ci_status(ci_commit) - + - if ci_commit + = render_ci_status(ci_commit) + - if stars %span %i.fa.fa-star diff --git a/app/views/votes/_votes_block.html.haml b/app/views/votes/_votes_block.html.haml index ce0a0113403..b1f8645eea0 100644 --- a/app/views/votes/_votes_block.html.haml +++ b/app/views/votes/_votes_block.html.haml @@ -20,27 +20,29 @@ = emoji_icon(emoji["name"], emoji["unicode"], emoji["aliases"]) - if current_user - :coffeescript - post_emoji_url = "#{award_toggle_namespace_project_notes_path(@project.namespace, @project)}" - noteable_type = "#{votable.class.name.underscore}" - noteable_id = "#{votable.id}" - aliases = #{AwardEmoji.aliases.to_json} + :javascript + var post_emoji_url = "#{award_toggle_namespace_project_notes_path(@project.namespace, @project)}"; + var noteable_type = "#{votable.class.name.underscore}"; + var noteable_id = "#{votable.id}"; + var aliases = #{AwardEmoji.aliases.to_json}; window.awards_handler = new AwardsHandler( post_emoji_url, noteable_type, noteable_id, aliases - ) + ); - $(".awards").on "click", ".emoji-menu-content li", (e) -> - emoji = $(this).find(".emoji-icon").data("emoji") - awards_handler.addAward(emoji) + $(".awards").on("click", ".emoji-menu-content li", function(e) { + var emoji = $(this).find(".emoji-icon").data("emoji"); + awards_handler.addAward(emoji); + }); - $(".awards").on "click", ".award", (e) -> - emoji = $(this).find(".icon").data("emoji") - awards_handler.addAward(emoji) + $(".awards").on("click", ".award", function(e) { + var emoji = $(this).find(".icon").data("emoji"); + awards_handler.addAward(emoji); + }); - $(".award").tooltip() + $(".award").tooltip(); - $(".emoji-menu-content").niceScroll({cursorwidth: "7px", autohidemode: false}) + $(".emoji-menu-content").niceScroll({cursorwidth: "7px", autohidemode: false}); diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 2d9f730c183..d6e2c9380a5 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -204,6 +204,11 @@ production: &base bind_dn: '_the_full_dn_of_the_user_you_will_bind_with' password: '_the_password_of_the_bind_user' + # Set a timeout, in seconds, for LDAP queries. This helps avoid blocking + # a request if the LDAP server becomes unresponsive. + # A value of 0 means there is no timeout. + timeout: 10 + # This setting specifies if LDAP server is Active Directory LDAP server. # For non AD servers it skips the AD specific queries. # If your LDAP server is not AD, set this to false. diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index 4fbd84ee890..a9c5b2caf0a 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -108,6 +108,7 @@ if Settings.ldap['enabled'] || Rails.env.test? Settings.ldap['servers'].each do |key, server| server['label'] ||= 'LDAP' + server['timeout'] ||= 10.seconds server['block_auto_created_users'] = false if server['block_auto_created_users'].nil? server['allow_username_or_email_login'] = false if server['allow_username_or_email_login'].nil? server['active_directory'] = true if server['active_directory'].nil? diff --git a/config/initializers/haml.rb b/config/initializers/haml.rb index 7e8ddb3716b..1516476815a 100644 --- a/config/initializers/haml.rb +++ b/config/initializers/haml.rb @@ -1 +1,7 @@ Haml::Template.options[:ugly] = true + +# Remove the `:coffee` and `:coffeescript` filters +# +# See https://git.io/vztMu and http://stackoverflow.com/a/17571242/223897 +Haml::Filters.remove_filter('coffee') +Haml::Filters.remove_filter('coffeescript') diff --git a/config/routes.rb b/config/routes.rb index 4fcea1185c0..3d5c70987c8 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -375,6 +375,7 @@ Rails.application.routes.draw do delete :remove_fork post :archive post :unarchive + post :housekeeping post :toggle_star post :markdown_preview get :autocomplete_sources diff --git a/db/migrate/20160106162223_add_index_milestones_title.rb b/db/migrate/20160106162223_add_index_milestones_title.rb new file mode 100644 index 00000000000..767885e2aac --- /dev/null +++ b/db/migrate/20160106162223_add_index_milestones_title.rb @@ -0,0 +1,5 @@ +class AddIndexMilestonesTitle < ActiveRecord::Migration + def change + add_index :milestones, :title + end +end diff --git a/doc/ci/docker/using_docker_images.md b/doc/ci/docker/using_docker_images.md index 31458d61674..63fe840b369 100644 --- a/doc/ci/docker/using_docker_images.md +++ b/doc/ci/docker/using_docker_images.md @@ -174,7 +174,7 @@ The alias hostname for the service is made from the image name following these rules: 1. Everything after `:` is stripped -2. Backslash (`/`) is replaced with double underscores (`__`) +2. Slash (`/`) is replaced with double underscores (`__`) ## Configuring services diff --git a/doc/ci/runners/README.md b/doc/ci/runners/README.md index 68dcfe23ffb..295d953db11 100644 --- a/doc/ci/runners/README.md +++ b/doc/ci/runners/README.md @@ -62,8 +62,9 @@ Now simply register the runner as any runner: sudo gitlab-runner register ``` -Note that you will have to enable `Allows shared runners` for each project -that you want to make use of a shared runner. This is by default `off`. +Shared runners are enabled by default as of GitLab 8.2, but can be disabled with the +`DISABLE SHARED RUNNERS` button. Previous versions of GitLab defaulted shared runners to +disabled. ## Registering a Specific Runner diff --git a/doc/install/installation.md b/doc/install/installation.md index dd59733cf4d..8c4e092c636 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -348,7 +348,7 @@ GitLab Shell is an SSH access and repository management software developed speci cd /home/git sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-workhorse.git cd gitlab-workhorse - sudo -u git -H git checkout 0.5.1 + sudo -u git -H git checkout 0.5.3 sudo -u git -H make ### Initialize Database and Activate Advanced Features diff --git a/doc/integration/ldap.md b/doc/integration/ldap.md index 845f588f913..f256477196b 100644 --- a/doc/integration/ldap.md +++ b/doc/integration/ldap.md @@ -48,6 +48,11 @@ main: # 'main' is the GitLab 'provider ID' of this LDAP server bind_dn: '_the_full_dn_of_the_user_you_will_bind_with' password: '_the_password_of_the_bind_user' + # Set a timeout, in seconds, for LDAP queries. This helps avoid blocking + # a request if the LDAP server becomes unresponsive. + # A value of 0 means there is no timeout. + timeout: 10 + # This setting specifies if LDAP server is Active Directory LDAP server. # For non AD servers it skips the AD specific queries. # If your LDAP server is not AD, set this to false. diff --git a/doc/update/8.2-to-8.3.md b/doc/update/8.2-to-8.3.md index 3748941b781..a3950df5fef 100644 --- a/doc/update/8.2-to-8.3.md +++ b/doc/update/8.2-to-8.3.md @@ -78,7 +78,7 @@ which should already be on your system from GitLab 8.1. ```bash cd /home/git/gitlab-workhorse sudo -u git -H git fetch --all -sudo -u git -H git checkout 0.5.1 +sudo -u git -H git checkout 0.5.3 sudo -u git -H make ``` diff --git a/lib/gitlab/backend/shell.rb b/lib/gitlab/backend/shell.rb index 459e3d6bcdb..4c15d58d680 100644 --- a/lib/gitlab/backend/shell.rb +++ b/lib/gitlab/backend/shell.rb @@ -150,6 +150,18 @@ module Gitlab "#{path}.git", tag_name]) end + # Gc repository + # + # path - project path with namespace + # + # Ex. + # gc("gitlab/gitlab-ci") + # + def gc(path) + Gitlab::Utils.system_silent([gitlab_shell_projects_path, 'gc', + "#{path}.git"]) + end + # Add new key to gitlab-shell # # Ex. diff --git a/lib/gitlab/ldap/access.rb b/lib/gitlab/ldap/access.rb index c438a3d167b..b2bdbc10d7f 100644 --- a/lib/gitlab/ldap/access.rb +++ b/lib/gitlab/ldap/access.rb @@ -5,7 +5,7 @@ module Gitlab module LDAP class Access - attr_reader :adapter, :provider, :user + attr_reader :provider, :user def self.open(user, &block) Gitlab::LDAP::Adapter.open(user.ldap_identity.provider) do |adapter| @@ -32,7 +32,7 @@ module Gitlab end def allowed? - if Gitlab::LDAP::Person.find_by_dn(user.ldap_identity.extern_uid, adapter) + if ldap_user return true unless ldap_config.active_directory # Block user in GitLab if he/she was blocked in AD @@ -59,6 +59,10 @@ module Gitlab def ldap_config Gitlab::LDAP::Config.new(provider) end + + def ldap_user + @ldap_user ||= Gitlab::LDAP::Person.find_by_dn(user.ldap_identity.extern_uid, adapter) + end end end end diff --git a/lib/gitlab/ldap/adapter.rb b/lib/gitlab/ldap/adapter.rb index 577a890a7d9..df65179bfea 100644 --- a/lib/gitlab/ldap/adapter.rb +++ b/lib/gitlab/ldap/adapter.rb @@ -70,19 +70,25 @@ module Gitlab end def ldap_search(*args) - results = ldap.search(*args) + # Net::LDAP's `time` argument doesn't work. Use Ruby `Timeout` instead. + Timeout.timeout(config.timeout) do + results = ldap.search(*args) - if results.nil? - response = ldap.get_operation_result + if results.nil? + response = ldap.get_operation_result - unless response.code.zero? - Rails.logger.warn("LDAP search error: #{response.message}") - end + unless response.code.zero? + Rails.logger.warn("LDAP search error: #{response.message}") + end - [] - else - results + [] + else + results + end end + rescue Timeout::Error + Rails.logger.warn("LDAP search timed out after #{config.timeout} seconds") + [] end end end diff --git a/lib/gitlab/ldap/config.rb b/lib/gitlab/ldap/config.rb index 101a3285f4b..aff7ccb157f 100644 --- a/lib/gitlab/ldap/config.rb +++ b/lib/gitlab/ldap/config.rb @@ -88,6 +88,10 @@ module Gitlab options['attributes'] end + def timeout + options['timeout'].to_i + end + protected def base_config Gitlab.config.ldap diff --git a/lib/gitlab/metrics/rack_middleware.rb b/lib/gitlab/metrics/rack_middleware.rb index e7a2f26d48b..6f179789d3e 100644 --- a/lib/gitlab/metrics/rack_middleware.rb +++ b/lib/gitlab/metrics/rack_middleware.rb @@ -39,10 +39,8 @@ module Gitlab end def tag_controller(trans, env) - controller = env[CONTROLLER_KEY] - label = "#{controller.class.name}##{controller.action_name}" - - trans.add_tag(:action, label) + controller = env[CONTROLLER_KEY] + trans.action = "#{controller.class.name}##{controller.action_name}" end end end diff --git a/lib/gitlab/metrics/sidekiq_middleware.rb b/lib/gitlab/metrics/sidekiq_middleware.rb index ad441decfa2..fd98aa3412e 100644 --- a/lib/gitlab/metrics/sidekiq_middleware.rb +++ b/lib/gitlab/metrics/sidekiq_middleware.rb @@ -5,19 +5,14 @@ module Gitlab # This middleware is intended to be used as a server-side middleware. class SidekiqMiddleware def call(worker, message, queue) - trans = Transaction.new + trans = Transaction.new("#{worker.class.name}#perform") begin trans.run { yield } ensure - tag_worker(trans, worker) trans.finish end end - - def tag_worker(trans, worker) - trans.add_tag(:action, "#{worker.class.name}#perform") - end end end end diff --git a/lib/gitlab/metrics/transaction.rb b/lib/gitlab/metrics/transaction.rb index 73131cc6ef2..86606b1c6d6 100644 --- a/lib/gitlab/metrics/transaction.rb +++ b/lib/gitlab/metrics/transaction.rb @@ -6,11 +6,15 @@ module Gitlab attr_reader :tags, :values + attr_accessor :action + def self.current Thread.current[THREAD_KEY] end - def initialize + # action - A String describing the action performed, usually the class + # plus method name. + def initialize(action = nil) @metrics = [] @started_at = nil @@ -18,6 +22,7 @@ module Gitlab @values = Hash.new(0) @tags = {} + @action = action end def duration @@ -70,7 +75,15 @@ module Gitlab end def submit - Metrics.submit_metrics(@metrics.map(&:to_hash)) + metrics = @metrics.map do |metric| + hash = metric.to_hash + + hash[:tags][:action] ||= @action if @action + + hash + end + + Metrics.submit_metrics(metrics) end def sidekiq? diff --git a/spec/features/ci_lint_spec.rb b/spec/features/ci_lint_spec.rb index e6e73e5e67c..30e29d9d552 100644 --- a/spec/features/ci_lint_spec.rb +++ b/spec/features/ci_lint_spec.rb @@ -35,5 +35,13 @@ describe 'CI Lint' do expect(page).to have_content('Error: Please provide content of .gitlab-ci.yml') end end + + describe 'YAML revalidate' do + let(:yaml_content) { 'my yaml content' } + + it 'loads previous YAML content after validation' do + expect(page).to have_field('content', with: 'my yaml content', type: 'textarea') + end + end end end diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index a2fb3e4c75d..e844e681ebf 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -127,15 +127,15 @@ describe 'Issues', feature: true do it 'sorts by newest' do visit namespace_project_issues_path(project.namespace, project, sort: sort_value_recently_created) - expect(first_issue).to include('foo') - expect(last_issue).to include('baz') + expect(first_issue).to include('baz') + expect(last_issue).to include('foo') end it 'sorts by oldest' do visit namespace_project_issues_path(project.namespace, project, sort: sort_value_oldest_created) - expect(first_issue).to include('baz') - expect(last_issue).to include('foo') + expect(first_issue).to include('foo') + expect(last_issue).to include('baz') end it 'sorts by most recently updated' do @@ -190,8 +190,8 @@ describe 'Issues', feature: true do sort: sort_value_oldest_created, assignee_id: user2.id) - expect(first_issue).to include('bar') - expect(last_issue).to include('foo') + expect(first_issue).to include('foo') + expect(last_issue).to include('bar') expect(page).not_to have_content 'baz' end end diff --git a/spec/javascripts/fixtures/zen_mode.html.haml b/spec/javascripts/fixtures/zen_mode.html.haml index e867e4de2b9..1701652c61e 100644 --- a/spec/javascripts/fixtures/zen_mode.html.haml +++ b/spec/javascripts/fixtures/zen_mode.html.haml @@ -1,9 +1,8 @@ .zennable - %input#zen-toggle-comment.zen-toggle-comment{ tabindex: '-1', type: 'checkbox' } .zen-backdrop - %textarea#note_note.js-gfm-input.markdown-area{placeholder: 'Leave a comment'} - %a.zen-enter-link{tabindex: '-1'} + %textarea#note_note.js-gfm-input.markdown-area + %a.js-zen-enter(tabindex="-1" href="#") %i.fa.fa-expand - Edit in fullscreen - %a.zen-leave-link + Edit in fullscreen + %a.js-zen-leave(tabindex="-1" href="#") %i.fa.fa-compress diff --git a/spec/javascripts/zen_mode_spec.js.coffee b/spec/javascripts/zen_mode_spec.js.coffee index 4cb3836755f..b790fce01ed 100644 --- a/spec/javascripts/zen_mode_spec.js.coffee +++ b/spec/javascripts/zen_mode_spec.js.coffee @@ -15,14 +15,6 @@ describe 'ZenMode', -> # Set this manually because we can't actually scroll the window @zen.scroll_position = 456 - # Ohmmmmmmm - enterZen = -> - $('.zen-toggle-comment').prop('checked', true).trigger('change') - - # Wh- what was that?! - exitZen = -> - $('.zen-toggle-comment').prop('checked', false).trigger('change') - describe 'on enter', -> it 'pauses Mousetrap', -> spyOn(Mousetrap, 'pause') @@ -35,16 +27,14 @@ describe 'ZenMode', -> expect('textarea').not.toHaveAttr('style') describe 'in use', -> - beforeEach -> - enterZen() + beforeEach -> enterZen() it 'exits on Escape', -> - $(document).trigger(jQuery.Event('keydown', {keyCode: 27})) - expect($('.zen-toggle-comment').prop('checked')).toBe(false) + escapeKeydown() + expect($('.zen-backdrop')).not.toHaveClass('fullscreen') describe 'on exit', -> - beforeEach -> - enterZen() + beforeEach -> enterZen() it 'unpauses Mousetrap', -> spyOn(Mousetrap, 'unpause') @@ -52,6 +42,10 @@ describe 'ZenMode', -> expect(Mousetrap.unpause).toHaveBeenCalled() it 'restores the scroll position', -> - spyOn(@zen, 'restoreScroll') + spyOn(@zen, 'scrollTo') exitZen() - expect(@zen.restoreScroll).toHaveBeenCalledWith(456) + expect(@zen.scrollTo).toHaveBeenCalled() + +enterZen = -> $('a.js-zen-enter').click() # Ohmmmmmmm +exitZen = -> $('a.js-zen-leave').click() +escapeKeydown = -> $('textarea').trigger($.Event('keydown', {keyCode: 27})) diff --git a/spec/lib/gitlab/metrics/rack_middleware_spec.rb b/spec/lib/gitlab/metrics/rack_middleware_spec.rb index 4e6dfc73df2..b99be4e1060 100644 --- a/spec/lib/gitlab/metrics/rack_middleware_spec.rb +++ b/spec/lib/gitlab/metrics/rack_middleware_spec.rb @@ -57,7 +57,7 @@ describe Gitlab::Metrics::RackMiddleware do middleware.tag_controller(transaction, env) - expect(transaction.tags[:action]).to eq('TestController#show') + expect(transaction.action).to eq('TestController#show') end end end diff --git a/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb b/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb index 5882e7d81c7..e520a968999 100644 --- a/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb +++ b/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb @@ -5,22 +5,15 @@ describe Gitlab::Metrics::SidekiqMiddleware do describe '#call' do it 'tracks the transaction' do - worker = Class.new.new + worker = double(:worker, class: double(:class, name: 'TestWorker')) + + expect(Gitlab::Metrics::Transaction).to receive(:new). + with('TestWorker#perform'). + and_call_original expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:finish) middleware.call(worker, 'test', :test) { nil } end end - - describe '#tag_worker' do - it 'adds the worker class and action to the transaction' do - trans = Gitlab::Metrics::Transaction.new - worker = double(:worker, class: double(:class, name: 'TestWorker')) - - expect(trans).to receive(:add_tag).with(:action, 'TestWorker#perform') - - middleware.tag_worker(trans, worker) - end - end end diff --git a/spec/lib/gitlab/metrics/transaction_spec.rb b/spec/lib/gitlab/metrics/transaction_spec.rb index 3a27f897735..6bdeb719491 100644 --- a/spec/lib/gitlab/metrics/transaction_spec.rb +++ b/spec/lib/gitlab/metrics/transaction_spec.rb @@ -96,5 +96,22 @@ describe Gitlab::Metrics::Transaction do transaction.submit end + + it 'adds the action as a tag for every metric' do + transaction.action = 'Foo#bar' + transaction.track_self + + hash = { + series: 'rails_transactions', + tags: { action: 'Foo#bar' }, + values: { duration: 0.0 }, + timestamp: an_instance_of(Fixnum) + } + + expect(Gitlab::Metrics).to receive(:submit_metrics). + with([hash]) + + transaction.submit + end end end |