diff --git a/CHANGELOG b/CHANGELOG index 4abe86f8ced..cb95cdef042 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -20,6 +20,10 @@ v 8.5.1 - Changed padding & background color for highlighted notes - Re-add the newrelic_rpm gem which was removed without any deprecation or warning (Stan Hu) - Update sentry-raven gem to 0.15.6 + - Add build coverage in project's builds page (Steffen Köhler) + +v 8.5.2 + - Fix error 500 when commenting on a commit v 8.5.0 - Fix duplicate "me" in tooltip of the "thumbsup" awards Emoji (Stan Hu) @@ -100,6 +104,9 @@ v 8.5.0 - Show label row when filtering issues or merge requests by label (Nuttanart Pornprasitsakul) - Add Todos +v 8.4.5 + - No CE-specific changes + v 8.4.4 - Update omniauth-saml gem to 1.4.2 - Prevent long-running backup tasks from timing out the database connection diff --git a/Gemfile.lock b/Gemfile.lock index bd220146bf7..d0f780e9519 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -962,8 +962,8 @@ DEPENDENCIES mysql2 (~> 0.3.16) nested_form (~> 0.3.2) net-ssh (~> 3.0.1) - nokogiri (~> 1.6.7, >= 1.6.7.2) newrelic_rpm (~> 3.14) + nokogiri (~> 1.6.7, >= 1.6.7.2) nprogress-rails (~> 0.1.6.7) oauth2 (~> 1.0.0) octokit (~> 3.8.0) diff --git a/app/assets/javascripts/autosave.js.coffee b/app/assets/javascripts/autosave.js.coffee index 5d3fe81da74..28f8e103664 100644 --- a/app/assets/javascripts/autosave.js.coffee +++ b/app/assets/javascripts/autosave.js.coffee @@ -16,11 +16,11 @@ class @Autosave try text = window.localStorage.getItem @key - catch + catch e return @field.val text if text?.length > 0 - @field.trigger "input" + @field.trigger "input" save: -> return unless window.localStorage? @@ -35,5 +35,5 @@ class @Autosave reset: -> return unless window.localStorage? - try + try window.localStorage.removeItem @key diff --git a/app/assets/javascripts/merge_request_tabs.js.coffee b/app/assets/javascripts/merge_request_tabs.js.coffee index 6f569f9e1aa..40cfa59a229 100644 --- a/app/assets/javascripts/merge_request_tabs.js.coffee +++ b/app/assets/javascripts/merge_request_tabs.js.coffee @@ -70,6 +70,7 @@ class @MergeRequestTabs @loadCommits($target.attr('href')) else if action == 'diffs' @loadDiff($target.attr('href')) + @shrinkView() else if action == 'builds' @loadBuilds($target.attr('href')) @@ -185,3 +186,14 @@ class @MergeRequestTabs expandViewContainer: -> $('.container-fluid').removeClass('container-limited') + + shrinkView: -> + $gutterIcon = $('.gutter-toggle i') + + # Wait until listeners are set + setTimeout( -> + # Only when sidebar is collapsed + if $gutterIcon.is('.fa-angle-double-right') + $gutterIcon.closest('a').trigger('click') + , 0) + diff --git a/app/assets/javascripts/sidebar.js.coffee b/app/assets/javascripts/sidebar.js.coffee index ae59480af9e..cff309c5972 100644 --- a/app/assets/javascripts/sidebar.js.coffee +++ b/app/assets/javascripts/sidebar.js.coffee @@ -8,4 +8,10 @@ $(document).on("click", '.toggle-nav-collapse', (e) -> $('.sidebar-wrapper').toggleClass("sidebar-collapsed sidebar-expanded") $('.toggle-nav-collapse i').toggleClass("fa-angle-right fa-angle-left") $.cookie("collapsed_nav", $('.page-with-sidebar').hasClass(collapsed), { path: '/' }) + + setTimeout ( -> + niceScrollBars = $('.nicescroll').niceScroll(); + niceScrollBars.updateScrollBar(); + ), 300 + ) diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss index 531dedb89fe..e624982c5c9 100644 --- a/app/assets/stylesheets/framework/header.scss +++ b/app/assets/stylesheets/framework/header.scss @@ -142,9 +142,13 @@ header { } @media (max-width: $screen-md-max) { - .header-collapsed, .header-expanded { - @include collapsed-header; + .header-collapsed { + margin-left: $sidebar_collapsed_width; } + + .header-expanded { + margin-left: $sidebar_width; + } } @media(min-width: $screen-md-max) { diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss index b141928f706..e0ccd6f100f 100644 --- a/app/assets/stylesheets/framework/sidebar.scss +++ b/app/assets/stylesheets/framework/sidebar.scss @@ -12,6 +12,10 @@ height: 100%; transition-duration: .3s; } + + &.right-sidebar-expanded { + padding-right: $gutter_width; + } } .sidebar-wrapper { @@ -45,19 +49,6 @@ overflow: hidden; transition-duration: .3s; - .home { - z-index: 1; - position: absolute; - left: 0px; - } - - #logo { - z-index: 2; - position: absolute; - width: 58px; - cursor: pointer; - } - a { float: left; height: $header-height; @@ -83,7 +74,7 @@ width: 158px; float: left; margin: 0; - margin-left: 50px; + margin-left: 14px; font-size: 19px; line-height: 41px; font-weight: normal; @@ -194,6 +185,10 @@ @mixin expanded-sidebar { padding-left: $sidebar_width; + &.right-sidebar-collapsed { + padding-right: $sidebar_collapsed_width; + } + .sidebar-wrapper { width: $sidebar_width; @@ -213,17 +208,13 @@ } } -@mixin expanded-gutter { - padding-right: $gutter_width; -} - -@mixin collapsed-gutter { - padding-right: $sidebar_collapsed_width; -} - @mixin collapsed-sidebar { padding-left: $sidebar_collapsed_width; + &.right-sidebar-collapsed { + padding-right: $sidebar_collapsed_width; + } + .sidebar-wrapper { width: $sidebar_collapsed_width; @@ -287,47 +278,10 @@ background: #f2f6f7; } -// page is small enough -@media (max-width: $screen-md-max) { - .page-sidebar-collapsed { - @include collapsed-sidebar; - } - - .page-sidebar-expanded { - @include collapsed-sidebar; - } - - .page-gutter { - &.right-sidebar-collapsed { - @include collapsed-gutter; - } - &.right-sidebar-expanded { - @include expanded-gutter; - } - } - - .collapse-nav { - display: none; - } +.page-sidebar-collapsed { + @include collapsed-sidebar; } -// page is large enough -@media(min-width: $screen-md-max) { - - .page-gutter { - &.right-sidebar-collapsed { - @include collapsed-gutter; - } - &.right-sidebar-expanded { - @include expanded-gutter; - } - } - - .page-sidebar-collapsed { - @include collapsed-sidebar; - } - - .page-sidebar-expanded { - @include expanded-sidebar; - } -} \ No newline at end of file +.page-sidebar-expanded { + @include expanded-sidebar; +} diff --git a/app/services/notes/create_service.rb b/app/services/notes/create_service.rb index b970439b921..2bb312bb252 100644 --- a/app/services/notes/create_service.rb +++ b/app/services/notes/create_service.rb @@ -13,6 +13,5 @@ module Notes note end - end end diff --git a/app/services/todo_service.rb b/app/services/todo_service.rb index dc270602ebc..4392e2d17fe 100644 --- a/app/services/todo_service.rb +++ b/app/services/todo_service.rb @@ -130,8 +130,8 @@ class TodoService end def handle_note(note, author) - # Skip system notes, like status changes and cross-references - return if note.system + # Skip system notes, notes on commit, and notes on project snippet + return if note.system? || ['Commit', 'Snippet'].include?(note.noteable_type) project = note.project target = note.noteable diff --git a/app/views/projects/builds/index.html.haml b/app/views/projects/builds/index.html.haml index 5e3bd14565e..14f1d3226bb 100644 --- a/app/views/projects/builds/index.html.haml +++ b/app/views/projects/builds/index.html.haml @@ -51,9 +51,11 @@ %th Name %th Duration %th Finished at + - if @project.build_coverage_enabled? + %th Coverage %th - @builds.each do |build| - = render 'projects/commit_statuses/commit_status', commit_status: build, commit_sha: true, stage: true, allow_retry: true + = render 'projects/commit_statuses/commit_status', commit_status: build, commit_sha: true, stage: true, coverage: @project.build_coverage_enabled?, allow_retry: true = paginate @builds, theme: 'gitlab' diff --git a/doc/development/architecture.md b/doc/development/architecture.md index 6101a71a8de..12e33406cb6 100644 --- a/doc/development/architecture.md +++ b/doc/development/architecture.md @@ -42,7 +42,7 @@ Gitlab-shell communicates with Sidekiq via the “communication board” (Redis) ## System Layout -When referring to ~git in the pictures it means the home directory of the git user which is typically /home/git. +When referring to `~git` in the pictures it means the home directory of the git user which is typically /home/git. GitLab is primarily installed within the `/home/git` user home directory as `git` user. Within the home directory is where the gitlabhq server software resides as well as the repositories (though the repository location is configurable). diff --git a/doc/legal/individual_contributor_license_agreement.md b/doc/legal/individual_contributor_license_agreement.md index f97c252fd7c..59803aea080 100644 --- a/doc/legal/individual_contributor_license_agreement.md +++ b/doc/legal/individual_contributor_license_agreement.md @@ -18,7 +18,7 @@ You accept and agree to the following terms and conditions for Your present and 6. You are not expected to provide support for Your Contributions, except to the extent You desire to provide support. You may provide support for free, for a fee, or not at all. Unless required by applicable law or agreed to in writing, You provide Your Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON- INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. -7. Should You wish to submit work that is not Your original creation, You may submit it to GitLab B.V. separately from any Contribution, identifying the complete details of its source and of any license or other restriction (including, but not limited to, related patents, trademarks, and license agreements) of which you are personally aware, and conspicuously marking the work as "Submitted on behalf of a third-party: [[]named here]". +7. Should You wish to submit work that is not Your original creation, You may submit it to GitLab B.V. separately from any Contribution, identifying the complete details of its source and of any license or other restriction (including, but not limited to, related patents, trademarks, and license agreements) of which you are personally aware, and conspicuously marking the work as "Submitted on behalf of a third-party: [insert_name_here]". 8. You agree to notify GitLab B.V. of any facts or circumstances of which you become aware that would make these representations inaccurate in any respect. diff --git a/doc/permissions/permissions.md b/doc/permissions/permissions.md index 168e7d143ee..f717b30c12e 100644 --- a/doc/permissions/permissions.md +++ b/doc/permissions/permissions.md @@ -26,6 +26,7 @@ documentation](../workflow/add-user/add-user.md). | Create code snippets | | ✓ | ✓ | ✓ | ✓ | | Manage issue tracker | | ✓ | ✓ | ✓ | ✓ | | Manage labels | | ✓ | ✓ | ✓ | ✓ | +| See a commit status | | ✓ | ✓ | ✓ | ✓ | | Manage merge requests | | | ✓ | ✓ | ✓ | | Create new merge request | | | ✓ | ✓ | ✓ | | Create new branches | | | ✓ | ✓ | ✓ | @@ -35,6 +36,7 @@ documentation](../workflow/add-user/add-user.md). | Add tags | | | ✓ | ✓ | ✓ | | Write a wiki | | | ✓ | ✓ | ✓ | | Cancel and retry builds | | | ✓ | ✓ | ✓ | +| Create or update commit status | | | ✓ | ✓ | ✓ | | Create new milestones | | | | ✓ | ✓ | | Add new team members | | | | ✓ | ✓ | | Push to protected branches | | | | ✓ | ✓ | diff --git a/doc/workflow/importing/migrating_from_svn.md b/doc/workflow/importing/migrating_from_svn.md index b355a91b5a6..4828bb5dce6 100644 --- a/doc/workflow/importing/migrating_from_svn.md +++ b/doc/workflow/importing/migrating_from_svn.md @@ -69,6 +69,7 @@ branches and tags. ```bash git remote add origin git@gitlab.com:/.git git push --all origin +git push --tags origin ``` ## Contribute to this guide diff --git a/features/project/builds/summary.feature b/features/project/builds/summary.feature index 4f3fd194d00..3c029a973df 100644 --- a/features/project/builds/summary.feature +++ b/features/project/builds/summary.feature @@ -3,6 +3,7 @@ Feature: Project Builds Summary Given I sign in as a user And I own a project And project has CI enabled + And project has coverage enabled And project has a recent build Scenario: I browse build details page @@ -12,6 +13,7 @@ Feature: Project Builds Summary Scenario: I browse project builds page When I visit project builds page + Then I see coverage Then I see button to CI Lint Scenario: I erase a build diff --git a/features/steps/project/builds/summary.rb b/features/steps/project/builds/summary.rb index 4688a0e2096..e9e2359146e 100644 --- a/features/steps/project/builds/summary.rb +++ b/features/steps/project/builds/summary.rb @@ -4,6 +4,12 @@ class Spinach::Features::ProjectBuildsSummary < Spinach::FeatureSteps include SharedBuilds include RepoHelpers + step 'I see coverage' do + page.within('td.coverage') do + expect(page).to have_content "99.9%" + end + end + step 'I see button to CI Lint' do page.within('.nav-controls') do ci_lint_tool_link = page.find_link('CI Lint') diff --git a/features/steps/shared/builds.rb b/features/steps/shared/builds.rb index 0bd5d93b997..f33ed7834fe 100644 --- a/features/steps/shared/builds.rb +++ b/features/steps/shared/builds.rb @@ -5,9 +5,13 @@ module SharedBuilds @project.enable_ci end + step 'project has coverage enabled' do + @project.update_attribute(:build_coverage_regex, /Coverage (\d+)%/) + end + step 'project has a recent build' do @ci_commit = create(:ci_commit, project: @project, sha: @project.commit.sha) - @build = create(:ci_build, commit: @ci_commit) + @build = create(:ci_build_with_coverage, commit: @ci_commit) end step 'recent build is successful' do diff --git a/features/support/capybara.rb b/features/support/capybara.rb index 38069ff8835..f33379f76c9 100644 --- a/features/support/capybara.rb +++ b/features/support/capybara.rb @@ -6,7 +6,7 @@ timeout = (ENV['CI'] || ENV['CI_SERVER']) ? 90 : 15 Capybara.javascript_driver = :poltergeist Capybara.register_driver :poltergeist do |app| - Capybara::Poltergeist::Driver.new(app, js_errors: true, timeout: timeout) + Capybara::Poltergeist::Driver.new(app, js_errors: true, timeout: timeout, window_size: [1366, 768]) end Capybara.default_wait_time = timeout diff --git a/spec/factories/ci/builds.rb b/spec/factories/ci/builds.rb index a46466798d6..a7a54d44521 100644 --- a/spec/factories/ci/builds.rb +++ b/spec/factories/ci/builds.rb @@ -53,6 +53,10 @@ FactoryGirl.define do tag true end + factory :ci_build_with_coverage do + coverage 99.9 + end + trait :trace do after(:create) do |build, evaluator| build.trace = 'BUILD TRACE' @@ -68,7 +72,7 @@ FactoryGirl.define do build.artifacts_metadata = fixture_file_upload(Rails.root.join('spec/fixtures/ci_build_artifacts_metadata.gz'), 'application/x-gzip') - + build.save! end end diff --git a/spec/services/todo_service_spec.rb b/spec/services/todo_service_spec.rb index df3aa955f24..96420acb31d 100644 --- a/spec/services/todo_service_spec.rb +++ b/spec/services/todo_service_spec.rb @@ -110,6 +110,8 @@ describe TodoService, services: true do let!(:first_todo) { create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author) } let!(:second_todo) { create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author) } let(:note) { create(:note, project: project, noteable: issue, author: john_doe, note: mentions) } + let(:note_on_commit) { create(:note_on_commit, project: project, author: john_doe, note: mentions) } + let(:note_on_project_snippet) { create(:note_on_project_snippet, project: project, author: john_doe, note: mentions) } let(:award_note) { create(:note, :award, project: project, noteable: issue, author: john_doe, note: 'thumbsup') } let(:system_note) { create(:system_note, project: project, noteable: issue) } @@ -145,6 +147,14 @@ describe TodoService, services: true do should_not_create_todo(user: john_doe, target: issue, author: john_doe, action: Todo::MENTIONED, note: note) should_not_create_todo(user: stranger, target: issue, author: john_doe, action: Todo::MENTIONED, note: note) end + + it 'does not create todo when leaving a note on commit' do + should_not_create_any_todo { service.new_note(note_on_commit, john_doe) } + end + + it 'does not create todo when leaving a note on snippet' do + should_not_create_any_todo { service.new_note(note_on_project_snippet, john_doe) } + end end end diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb index a698f484df1..65d59e6813c 100644 --- a/spec/support/capybara.rb +++ b/spec/support/capybara.rb @@ -7,7 +7,7 @@ timeout = (ENV['CI'] || ENV['CI_SERVER']) ? 90 : 10 Capybara.javascript_driver = :poltergeist Capybara.register_driver :poltergeist do |app| - Capybara::Poltergeist::Driver.new(app, js_errors: true, timeout: timeout) + Capybara::Poltergeist::Driver.new(app, js_errors: true, timeout: timeout, window_size: [1366, 768]) end Capybara.default_wait_time = timeout