diff options
author | Filipa Lacerda <filipa@gitlab.com> | 2017-08-31 09:33:08 +0100 |
---|---|---|
committer | Filipa Lacerda <filipa@gitlab.com> | 2017-08-31 09:33:08 +0100 |
commit | f1ef373b3ba4f46cbe4b1225d0b5019a0fce688f (patch) | |
tree | 30860f20069f453570fd6cf50f07ff7d86c2eb37 /app | |
parent | 7a0a9c23028aa487078bac6499bd86f3356c84a0 (diff) | |
parent | 3e092caa91853afeab3bb01be10869e45c39de5d (diff) | |
download | gitlab-ce-37179-dashboard-project-dropdown.tar.gz |
Merge branch 'master' into 37179-dashboard-project-dropdown37179-dashboard-project-dropdown
* master: (65 commits)
Upgrade mail and nokogiri gems due to security issues
Link out to stackoverflow answer on setting swappiness
Document swappiness recomendations in the requirements doc
Fix invalid attribute used for time-ago-tooltip component
Update latest artifacts doc
Add changelog entry for flipping verify_certificates
Default LDAP config verify_certificates to true
Update share project with groups docs
remove accidental console.log from karma tests
update specs to match reorganized monitoring components
Remove tooltips from new sidebar
Use `git update-ref --stdin -z` to delete refs
Don't use public_send in destroy_conditionally! helper
Remove unused expressions policy from ci/cd config
Simplify code for appending strategies in CI/CD config
Raise exception when simplifiable ci entry incomplete
Add changelog entry
Fix MySQL failure for emoji autocomplete
max-width for lazy-loaded images (this was removed in the original MR through merge resolution most probably)
Make namespace dropdown on new project page consistent
...
Diffstat (limited to 'app')
30 files changed, 234 insertions, 171 deletions
diff --git a/app/assets/javascripts/fly_out_nav.js b/app/assets/javascripts/fly_out_nav.js index 32cb42c8b10..81697af189b 100644 --- a/app/assets/javascripts/fly_out_nav.js +++ b/app/assets/javascripts/fly_out_nav.js @@ -1,4 +1,3 @@ -import Cookies from 'js-cookie'; import bp from './breakpoints'; const HIDE_INTERVAL_TIMEOUT = 300; @@ -8,9 +7,11 @@ const IS_SHOWING_FLY_OUT_CLASS = 'is-showing-fly-out'; let currentOpenMenu = null; let menuCornerLocs; let timeoutId; +let sidebar; export const mousePos = []; +export const setSidebar = (el) => { sidebar = el; }; export const setOpenMenu = (menu = null) => { currentOpenMenu = menu; }; export const slope = (a, b) => (b.y - a.y) / (b.x - a.x); @@ -20,10 +21,8 @@ let headerHeight = 50; export const getHeaderHeight = () => headerHeight; export const canShowActiveSubItems = (el) => { - const isHiddenByMedia = bp.getBreakpointSize() === 'sm' || bp.getBreakpointSize() === 'md'; - - if (el.classList.contains('active') && !isHiddenByMedia) { - return Cookies.get('sidebar_collapsed') === 'true'; + if (el.classList.contains('active') && (sidebar && !sidebar.classList.contains('sidebar-icons-only'))) { + return false; } return true; @@ -143,13 +142,13 @@ export const documentMouseMove = (e) => { }; export default () => { - const sidebar = document.querySelector('.sidebar-top-level-items'); + sidebar = document.querySelector('.nav-sidebar'); if (!sidebar) return; const items = [...sidebar.querySelectorAll('.sidebar-top-level-items > li')]; - sidebar.addEventListener('mouseleave', () => { + sidebar.querySelector('.sidebar-top-level-items').addEventListener('mouseleave', () => { clearTimeout(timeoutId); timeoutId = setTimeout(() => { diff --git a/app/assets/javascripts/issue_show/components/edited.vue b/app/assets/javascripts/issue_show/components/edited.vue index d59e6d11032..992b7064c13 100644 --- a/app/assets/javascripts/issue_show/components/edited.vue +++ b/app/assets/javascripts/issue_show/components/edited.vue @@ -37,7 +37,7 @@ export default { Edited <time-ago-tooltip v-if="updatedAt" - placement="bottom" + tooltip-placement="bottom" :time="updatedAt" /> <span diff --git a/app/assets/javascripts/monitoring/components/monitoring.vue b/app/assets/javascripts/monitoring/components/dashboard.vue index a6a2d3119e3..74244faa5d9 100644 --- a/app/assets/javascripts/monitoring/components/monitoring.vue +++ b/app/assets/javascripts/monitoring/components/dashboard.vue @@ -3,8 +3,9 @@ import _ from 'underscore'; import statusCodes from '../../lib/utils/http_status'; import MonitoringService from '../services/monitoring_service'; - import monitoringRow from './monitoring_row.vue'; - import monitoringState from './monitoring_state.vue'; + import GraphGroup from './graph_group.vue'; + import GraphRow from './graph_row.vue'; + import EmptyState from './empty_state.vue'; import MonitoringStore from '../stores/monitoring_store'; import eventHub from '../event_hub'; @@ -31,8 +32,9 @@ }, components: { - monitoringRow, - monitoringState, + GraphGroup, + GraphRow, + EmptyState, }, methods: { @@ -94,7 +96,6 @@ this.updatedAspectRatios = 0; } }, - }, created() { @@ -118,40 +119,27 @@ }, }; </script> + <template> - <div - class="prometheus-graphs" - v-if="!showEmptyState"> - <div - class="row" + <div v-if="!showEmptyState" class="prometheus-graphs"> + <graph-group v-for="(groupData, index) in store.groups" - :key="index"> - <div - class="col-md-12"> - <div - class="panel panel-default prometheus-panel"> - <div - class="panel-heading"> - <h4>{{groupData.group}}</h4> - </div> - <div - class="panel-body"> - <monitoring-row - v-for="(row, index) in groupData.metrics" - :key="index" - :row-data="row" - :update-aspect-ratio="updateAspectRatio" - :deployment-data="store.deploymentData" - /> - </div> - </div> - </div> - </div> + :key="index" + :name="groupData.group" + > + <graph-row + v-for="(row, index) in groupData.metrics" + :key="index" + :row-data="row" + :update-aspect-ratio="updateAspectRatio" + :deployment-data="store.deploymentData" + /> + </graph-group> </div> - <monitoring-state + <empty-state + v-else :selected-state="state" :documentation-path="documentationPath" :settings-path="settingsPath" - v-else /> </template> diff --git a/app/assets/javascripts/monitoring/components/monitoring_state.vue b/app/assets/javascripts/monitoring/components/empty_state.vue index 598021aa4df..a8708be76de 100644 --- a/app/assets/javascripts/monitoring/components/monitoring_state.vue +++ b/app/assets/javascripts/monitoring/components/empty_state.vue @@ -62,49 +62,33 @@ }, }; </script> + <template> - <div - class="prometheus-state"> - <div - class="row"> - <div - class="col-md-4 col-md-offset-4 state-svg" - v-html="currentState.svg"> - </div> + <div class="prometheus-state"> + <div class="row"> + <div class="col-md-4 col-md-offset-4 state-svg" v-html="currentState.svg"></div> </div> - <div - class="row"> - <div - class="col-md-6 col-md-offset-3"> - <h4 - class="text-center state-title"> + <div class="row"> + <div class="col-md-6 col-md-offset-3"> + <h4 class="text-center state-title"> {{currentState.title}} </h4> </div> </div> - <div - class="row"> - <div - class="col-md-6 col-md-offset-3"> - <div - class="description-text text-center state-description"> - {{currentState.description}} - <a - :href="settingsPath" - v-if="showButtonDescription"> - Prometheus server - </a> + <div class="row"> + <div class="col-md-6 col-md-offset-3"> + <div class="description-text text-center state-description"> + {{currentState.description}} + <a v-if="showButtonDescription" :href="settingsPath"> + Prometheus server + </a> </div> </div> </div> - <div - class="row state-button-section"> - <div - class="col-md-4 col-md-offset-4 text-center state-button"> - <a - class="btn btn-success" - :href="buttonPath"> - {{currentState.buttonText}} + <div class="row state-button-section"> + <div class="col-md-4 col-md-offset-4 text-center state-button"> + <a class="btn btn-success" :href="buttonPath"> + {{currentState.buttonText}} </a> </div> </div> diff --git a/app/assets/javascripts/monitoring/components/monitoring_column.vue b/app/assets/javascripts/monitoring/components/graph.vue index a31c26fb4fc..6f6da9e1463 100644 --- a/app/assets/javascripts/monitoring/components/monitoring_column.vue +++ b/app/assets/javascripts/monitoring/components/graph.vue @@ -1,8 +1,8 @@ <script> import d3 from 'd3'; - import monitoringLegends from './monitoring_legends.vue'; - import monitoringFlag from './monitoring_flag.vue'; - import monitoringDeployment from './monitoring_deployment.vue'; + import GraphLegend from './graph/legend.vue'; + import GraphFlag from './graph/flag.vue'; + import GraphDeployment from './graph/deployment.vue'; import MonitoringMixin from '../mixins/monitoring_mixins'; import eventHub from '../event_hub'; import measurements from '../utils/measurements'; @@ -14,7 +14,7 @@ export default { props: { - columnData: { + graphData: { type: Object, required: true, }, @@ -66,9 +66,9 @@ }, components: { - monitoringLegends, - monitoringFlag, - monitoringDeployment, + GraphLegend, + GraphFlag, + GraphDeployment, }, computed: { @@ -97,7 +97,7 @@ methods: { draw() { const breakpointSize = bp.getBreakpointSize(); - const query = this.columnData.queries[0]; + const query = this.graphData.queries[0]; this.margin = measurements.large.margin; if (breakpointSize === 'xs' || breakpointSize === 'sm') { this.graphHeight = 300; @@ -106,7 +106,7 @@ } this.data = query.result[0].values; this.unitOfDisplay = query.unit || ''; - this.yAxisLabel = this.columnData.y_label || 'Values'; + this.yAxisLabel = this.graphData.y_label || 'Values'; this.legendTitle = query.label || 'Average'; this.graphWidth = this.$refs.baseSvg.clientWidth - this.margin.left - this.margin.right; @@ -224,7 +224,7 @@ :class="classType"> <h5 class="text-center graph-title"> - {{columnData.title}} + {{graphData.title}} </h5> <div class="prometheus-svg-container" @@ -240,7 +240,7 @@ class="y-axis" transform="translate(70, 20)"> </g> - <monitoring-legends + <graph-legend :graph-width="graphWidth" :graph-height="graphHeight" :margin="margin" @@ -268,13 +268,13 @@ stroke-width="2" transform="translate(-5, 20)"> </path> - <monitoring-deployment + <graph-deployment :show-deploy-info="showDeployInfo" :deployment-data="reducedDeploymentData" :graph-height="graphHeight" :graph-height-offset="graphHeightOffset" /> - <monitoring-flag + <graph-flag v-if="showFlag" :current-x-coordinate="currentXCoordinate" :current-y-coordinate="currentYCoordinate" diff --git a/app/assets/javascripts/monitoring/components/monitoring_deployment.vue b/app/assets/javascripts/monitoring/components/graph/deployment.vue index dadbcd1aaa6..3623d2ed946 100644 --- a/app/assets/javascripts/monitoring/components/monitoring_deployment.vue +++ b/app/assets/javascripts/monitoring/components/graph/deployment.vue @@ -1,5 +1,5 @@ <script> - import { dateFormat, timeFormat } from '../utils/date_time_formatters'; + import { dateFormat, timeFormat } from '../../utils/date_time_formatters'; export default { props: { diff --git a/app/assets/javascripts/monitoring/components/monitoring_flag.vue b/app/assets/javascripts/monitoring/components/graph/flag.vue index 61cbeeebb17..c4d4647d240 100644 --- a/app/assets/javascripts/monitoring/components/monitoring_flag.vue +++ b/app/assets/javascripts/monitoring/components/graph/flag.vue @@ -1,5 +1,5 @@ <script> - import { dateFormat, timeFormat } from '../utils/date_time_formatters'; + import { dateFormat, timeFormat } from '../../utils/date_time_formatters'; export default { props: { diff --git a/app/assets/javascripts/monitoring/components/monitoring_legends.vue b/app/assets/javascripts/monitoring/components/graph/legend.vue index 922a5e1bf0e..d08f9cbffd4 100644 --- a/app/assets/javascripts/monitoring/components/monitoring_legends.vue +++ b/app/assets/javascripts/monitoring/components/graph/legend.vue @@ -74,7 +74,7 @@ }; </script> <template> - <g + <g class="axis-label-container"> <line class="label-x-axis-line" @@ -100,7 +100,7 @@ :width="yLabelWidth" :height="yLabelHeight"> </rect> - <text + <text class="label-axis-text y-label-text" text-anchor="middle" :transform="textTransform" diff --git a/app/assets/javascripts/monitoring/components/graph_group.vue b/app/assets/javascripts/monitoring/components/graph_group.vue new file mode 100644 index 00000000000..32c90fda8cc --- /dev/null +++ b/app/assets/javascripts/monitoring/components/graph_group.vue @@ -0,0 +1,21 @@ +<script> +export default { + props: { + name: { + type: String, + required: true, + }, + }, +}; +</script> + +<template> + <div class="panel panel-default prometheus-panel"> + <div class="panel-heading"> + <h4>{{name}}</h4> + </div> + <div class="panel-body"> + <slot /> + </div> + </div> +</template> diff --git a/app/assets/javascripts/monitoring/components/monitoring_row.vue b/app/assets/javascripts/monitoring/components/graph_row.vue index e5528f17880..bdb9149c3b4 100644 --- a/app/assets/javascripts/monitoring/components/monitoring_row.vue +++ b/app/assets/javascripts/monitoring/components/graph_row.vue @@ -1,5 +1,5 @@ <script> - import monitoringColumn from './monitoring_column.vue'; + import Graph from './graph.vue'; export default { props: { @@ -17,7 +17,7 @@ }, }, components: { - monitoringColumn, + Graph, }, computed: { bootstrapClass() { @@ -26,12 +26,12 @@ }, }; </script> + <template> - <div - class="prometheus-row row"> - <monitoring-column - v-for="(column, index) in rowData" - :column-data="column" + <div class="prometheus-row row"> + <graph + v-for="(graphData, index) in rowData" + :graph-data="graphData" :class-type="bootstrapClass" :key="index" :update-aspect-ratio="updateAspectRatio" diff --git a/app/assets/javascripts/monitoring/monitoring_bundle.js b/app/assets/javascripts/monitoring/monitoring_bundle.js index 5d5cb56af72..ef280e02092 100644 --- a/app/assets/javascripts/monitoring/monitoring_bundle.js +++ b/app/assets/javascripts/monitoring/monitoring_bundle.js @@ -1,10 +1,10 @@ import Vue from 'vue'; -import Monitoring from './components/monitoring.vue'; +import Dashboard from './components/dashboard.vue'; document.addEventListener('DOMContentLoaded', () => new Vue({ el: '#prometheus-graphs', components: { - 'monitoring-dashboard': Monitoring, + Dashboard, }, - render: createElement => createElement('monitoring-dashboard'), + render: createElement => createElement('dashboard'), })); diff --git a/app/assets/javascripts/new_sidebar.js b/app/assets/javascripts/new_sidebar.js index b18d12b48b5..05e3f33f5ed 100644 --- a/app/assets/javascripts/new_sidebar.js +++ b/app/assets/javascripts/new_sidebar.js @@ -15,6 +15,7 @@ export default class NewNavSidebar { this.$openSidebar = $('.toggle-mobile-nav'); this.$closeSidebar = $('.close-nav-button'); this.$sidebarToggle = $('.js-toggle-sidebar'); + this.$topLevelLinks = $('.sidebar-top-level-items > li > a'); } bindEvents() { @@ -50,6 +51,10 @@ export default class NewNavSidebar { this.$page.toggleClass('page-with-icon-sidebar', breakpoint === 'sm' ? true : collapsed); } NewNavSidebar.setCollapsedCookie(collapsed); + + this.$topLevelLinks.attr('title', function updateTopLevelTitle() { + return collapsed ? this.getAttribute('aria-label') : ''; + }); } render() { diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss index 4cf2f46c6d3..5871383a57b 100644 --- a/app/assets/stylesheets/framework/dropdowns.scss +++ b/app/assets/stylesheets/framework/dropdowns.scss @@ -189,7 +189,7 @@ width: auto; top: 100%; left: 0; - z-index: 9; + z-index: 200; min-width: 240px; max-width: 500px; margin-top: 2px; @@ -797,3 +797,5 @@ margin-top: 2px; } } + +@include new-style-dropdown('.js-namespace-select + '); diff --git a/app/assets/stylesheets/framework/selects.scss b/app/assets/stylesheets/framework/selects.scss index 8018eb8ba84..a39927eb0df 100644 --- a/app/assets/stylesheets/framework/selects.scss +++ b/app/assets/stylesheets/framework/selects.scss @@ -267,6 +267,7 @@ // TODO: change global style .ajax-project-dropdown, +body[data-page="projects:new"] #select2-drop, body[data-page="projects:blob:new"] #select2-drop, body[data-page="profiles:show"] #select2-drop, body[data-page="projects:blob:edit"] #select2-drop { diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss index b2423bc1a66..3c0b4c82d19 100644 --- a/app/assets/stylesheets/framework/typography.scss +++ b/app/assets/stylesheets/framework/typography.scss @@ -25,6 +25,7 @@ min-width: inherit; min-height: inherit; background-color: inherit; + max-width: 100%; } p a:not(.no-attachment-icon) img { diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index 334bec8dd7e..9d51c0b7a8a 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -612,6 +612,8 @@ } .mr-version-controls { + @include new-style-dropdown; + position: relative; background: $gray-light; color: $gl-text-color; diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb index 54f78fc8719..59be955599d 100644 --- a/app/controllers/autocomplete_controller.rb +++ b/app/controllers/autocomplete_controller.rb @@ -55,7 +55,7 @@ class AutocompleteController < ApplicationController .limit(AWARD_EMOJI_MAX) .where(user: current_user) .group(:name) - .order(count: :desc, name: :asc) + .order('count_all DESC, name ASC') .count # Transform from hash to array to guarantee json order diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb index ee701076a14..3308ab0c259 100644 --- a/app/helpers/tab_helper.rb +++ b/app/helpers/tab_helper.rb @@ -119,4 +119,8 @@ module TabHelper 'active' if current_controller?('oauth/applications') end + + def sidebar_link(href, title: nil, css: nil, &block) + link_to capture(&block), href, title: (title if collapsed_sidebar?), class: css, aria: { label: title } + end end diff --git a/app/models/environment.rb b/app/models/environment.rb index e9ebf0637f3..435eeaf0e2e 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -114,7 +114,7 @@ class Environment < ActiveRecord::Base end def ref_path - "refs/environments/#{Shellwords.shellescape(name)}" + "refs/#{Repository::REF_ENVIRONMENTS}/#{Shellwords.shellescape(name)}" end def formatted_external_url diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 7f73de67625..5be2f6d4e82 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -803,7 +803,7 @@ class MergeRequest < ActiveRecord::Base end def ref_path - "refs/merge-requests/#{iid}/head" + "refs/#{Repository::REF_MERGE_REQUEST}/#{iid}/head" end def ref_fetched? diff --git a/app/models/project.rb b/app/models/project.rb index d5324ceac31..9d7bea4eb66 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -372,11 +372,7 @@ class Project < ActiveRecord::Base if Gitlab::ImportSources.importer_names.include?(project.import_type) && project.repo_exists? project.run_after_commit do - begin - Projects::HousekeepingService.new(project).execute - rescue Projects::HousekeepingService::LeaseTaken => e - Rails.logger.info("Could not perform housekeeping for project #{project.full_path} (#{project.id}): #{e}") - end + Projects::AfterImportService.new(project).execute end end end diff --git a/app/models/repository.rb b/app/models/repository.rb index cb7aba89020..d29d2a83708 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -1,6 +1,18 @@ require 'securerandom' class Repository + REF_MERGE_REQUEST = 'merge-requests'.freeze + REF_KEEP_AROUND = 'keep-around'.freeze + REF_ENVIRONMENTS = 'environments'.freeze + + RESERVED_REFS_NAMES = %W[ + heads + tags + #{REF_ENVIRONMENTS} + #{REF_KEEP_AROUND} + #{REF_ENVIRONMENTS} + ].freeze + include Gitlab::ShellAdapter include RepositoryMirroring @@ -60,6 +72,10 @@ class Repository @project = project end + def ==(other) + @disk_path == other.disk_path + end + def raw_repository return nil unless full_path @@ -75,6 +91,10 @@ class Repository ) end + def inspect + "#<#{self.class.name}:#{@disk_path}>" + end + # # Git repository can contains some hidden refs like: # /refs/notes/* @@ -234,10 +254,10 @@ class Repository begin write_ref(keep_around_ref_name(sha), sha) rescue Rugged::ReferenceError => ex - Rails.logger.error "Unable to create keep-around reference for repository #{path}: #{ex}" + Rails.logger.error "Unable to create #{REF_KEEP_AROUND} reference for repository #{path}: #{ex}" rescue Rugged::OSError => ex raise unless ex.message =~ /Failed to create locked file/ && ex.message =~ /File exists/ - Rails.logger.error "Unable to create keep-around reference for repository #{path}: #{ex}" + Rails.logger.error "Unable to create #{REF_KEEP_AROUND} reference for repository #{path}: #{ex}" end end @@ -992,25 +1012,22 @@ class Repository end def with_repo_branch_commit(start_repository, start_branch_name) - return yield(nil) if start_repository.empty_repo? + return yield nil if start_repository.empty_repo? - branch_name_or_sha = - if start_repository == self - start_branch_name - else - tmp_ref = fetch_ref( - start_repository.path_to_repo, - "#{Gitlab::Git::BRANCH_REF_PREFIX}#{start_branch_name}", - "refs/tmp/#{SecureRandom.hex}/head" - ) + if start_repository == self + yield commit(start_branch_name) + else + sha = start_repository.commit(start_branch_name).sha - start_repository.commit(start_branch_name).sha + if branch_commit = commit(sha) + yield branch_commit + else + with_repo_tmp_commit( + start_repository, start_branch_name, sha) do |tmp_commit| + yield tmp_commit + end end - - yield(commit(branch_name_or_sha)) - - ensure - rugged.references.delete(tmp_ref) if tmp_ref + end end def add_remote(name, url) @@ -1159,7 +1176,7 @@ class Repository end def keep_around_ref_name(sha) - "refs/keep-around/#{sha}" + "refs/#{REF_KEEP_AROUND}/#{sha}" end def repository_event(event, tags = {}) @@ -1219,4 +1236,16 @@ class Repository .commits_by_message(query, revision: ref, path: path, limit: limit, offset: offset) .map { |c| commit(c) } end + + def with_repo_tmp_commit(start_repository, start_branch_name, sha) + tmp_ref = fetch_ref( + start_repository.path_to_repo, + "#{Gitlab::Git::BRANCH_REF_PREFIX}#{start_branch_name}", + "refs/tmp/#{SecureRandom.hex}/head" + ) + + yield commit(sha) + ensure + delete_refs(tmp_ref) if tmp_ref + end end diff --git a/app/services/projects/after_import_service.rb b/app/services/projects/after_import_service.rb new file mode 100644 index 00000000000..e6a68d983ef --- /dev/null +++ b/app/services/projects/after_import_service.rb @@ -0,0 +1,29 @@ +module Projects + class AfterImportService + RESERVED_REFS_REGEXP = + %r{\Arefs/(?:#{Regexp.union(*Repository::RESERVED_REFS_NAMES)})/} + + def initialize(project) + @project = project + end + + def execute + Projects::HousekeepingService.new(@project).execute do + repository.delete_refs(*garbage_refs) + end + rescue Projects::HousekeepingService::LeaseTaken => e + Rails.logger.info( + "Could not perform housekeeping for project #{@project.full_path} (#{@project.id}): #{e}") + end + + private + + def garbage_refs + @garbage_refs ||= repository.all_ref_names_except(RESERVED_REFS_REGEXP) + end + + def repository + @repository ||= @project.repository + end + end +end diff --git a/app/services/projects/housekeeping_service.rb b/app/services/projects/housekeeping_service.rb index d66ef676088..dcef8b66215 100644 --- a/app/services/projects/housekeeping_service.rb +++ b/app/services/projects/housekeeping_service.rb @@ -26,6 +26,8 @@ module Projects lease_uuid = try_obtain_lease raise LeaseTaken unless lease_uuid.present? + yield if block_given? + execute_gitlab_shell_gc(lease_uuid) end diff --git a/app/views/layouts/nav/_new_admin_sidebar.html.haml b/app/views/layouts/nav/_new_admin_sidebar.html.haml index 9294529f496..3b53117deb6 100644 --- a/app/views/layouts/nav/_new_admin_sidebar.html.haml +++ b/app/views/layouts/nav/_new_admin_sidebar.html.haml @@ -7,7 +7,7 @@ .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 + = sidebar_link admin_root_path, title: _('Overview'), css: 'shortcuts-tree' do .nav-icon-container = custom_icon('overview') %span.nav-item-name @@ -48,7 +48,7 @@ ConvDev Index = nav_link(controller: %w(conversational_development_index system_info background_jobs logs health_check requests_profiles)) do - = link_to admin_conversational_development_index_path, title: 'Monitoring' do + = sidebar_link admin_conversational_development_index_path, title: _('Monitoring') do .nav-icon-container = custom_icon('monitoring') %span.nav-item-name @@ -77,28 +77,28 @@ Requests Profiles = nav_link(controller: :broadcast_messages) do - = link_to admin_broadcast_messages_path, title: 'Messages' do + = sidebar_link admin_broadcast_messages_path, title: _('Messages') do .nav-icon-container = custom_icon('messages') %span.nav-item-name Messages = nav_link(controller: [:hooks, :hook_logs]) do - = link_to admin_hooks_path, title: 'Hooks' do + = sidebar_link admin_hooks_path, title: _('Hooks') do .nav-icon-container = custom_icon('system_hooks') %span.nav-item-name System Hooks = nav_link(controller: :applications) do - = link_to admin_applications_path, title: 'Applications' do + = sidebar_link admin_applications_path, title: _('Applications') do .nav-icon-container = custom_icon('applications') %span.nav-item-name Applications = nav_link(controller: :abuse_reports) do - = link_to admin_abuse_reports_path, title: "Abuse Reports" do + = sidebar_link admin_abuse_reports_path, title: _("Abuse Reports") do .nav-icon-container = custom_icon('abuse_reports') %span.nav-item-name @@ -107,42 +107,42 @@ - if akismet_enabled? = nav_link(controller: :spam_logs) do - = link_to admin_spam_logs_path, title: "Spam Logs" do + = sidebar_link admin_spam_logs_path, title: _("Spam Logs") do .nav-icon-container = custom_icon('spam_logs') %span.nav-item-name Spam Logs = nav_link(controller: :deploy_keys) do - = link_to admin_deploy_keys_path, title: 'Deploy Keys' do + = sidebar_link admin_deploy_keys_path, title: _('Deploy Keys') do .nav-icon-container = custom_icon('key') %span.nav-item-name Deploy Keys = nav_link(controller: :services) do - = link_to admin_application_settings_services_path, title: 'Service Templates' do + = sidebar_link admin_application_settings_services_path, title: _('Service Templates') do .nav-icon-container = custom_icon('service_templates') %span.nav-item-name Service Templates = nav_link(controller: :labels) do - = link_to admin_labels_path, title: 'Labels' do + = sidebar_link admin_labels_path, title: _('Labels') do .nav-icon-container = custom_icon('labels') %span.nav-item-name Labels = nav_link(controller: :appearances) do - = link_to admin_appearances_path, title: 'Appearances' do + = sidebar_link admin_appearances_path, title: _('Appearances') do .nav-icon-container = custom_icon('appearance') %span.nav-item-name Appearance = nav_link(controller: :application_settings) do - = link_to admin_application_settings_path, title: 'Settings' do + = sidebar_link admin_application_settings_path, title: _('Settings') do .nav-icon-container = custom_icon('settings') %span.nav-item-name diff --git a/app/views/layouts/nav/_new_group_sidebar.html.haml b/app/views/layouts/nav/_new_group_sidebar.html.haml index d90aea2e361..5a1511b262f 100644 --- a/app/views/layouts/nav/_new_group_sidebar.html.haml +++ b/app/views/layouts/nav/_new_group_sidebar.html.haml @@ -8,7 +8,7 @@ = @group.name %ul.sidebar-top-level-items = nav_link(path: ['groups#show', 'groups#activity', 'groups#subgroups'], html_options: { class: 'home' }) do - = link_to group_path(@group), title: 'Group overview' do + = sidebar_link group_path(@group), title: _('Group overview') do .nav-icon-container = custom_icon('project') %span.nav-item-name @@ -26,7 +26,7 @@ Activity = nav_link(path: ['groups#issues', 'labels#index', 'milestones#index']) do - = link_to issues_group_path(@group), title: 'Issues' do + = sidebar_link issues_group_path(@group), title: _('Issues') do .nav-icon-container = custom_icon('issues') %span.nav-item-name @@ -51,7 +51,7 @@ Milestones = nav_link(path: 'groups#merge_requests') do - = link_to merge_requests_group_path(@group), title: 'Merge Requests' do + = sidebar_link merge_requests_group_path(@group), title: _('Merge Requests') do .nav-icon-container = custom_icon('mr_bold') %span.nav-item-name @@ -59,14 +59,14 @@ Merge Requests %span.badge.count= number_with_delimiter(merge_requests.count) = nav_link(path: 'group_members#index') do - = link_to group_group_members_path(@group), title: 'Members' do + = sidebar_link group_group_members_path(@group), title: _('Members') do .nav-icon-container = custom_icon('members') %span.nav-item-name Members - if current_user && can?(current_user, :admin_group, @group) = nav_link(path: %w[groups#projects groups#edit ci_cd#show]) do - = link_to edit_group_path(@group), title: 'Settings' do + = sidebar_link edit_group_path(@group), title: _('Settings') do .nav-icon-container = custom_icon('settings') %span.nav-item-name diff --git a/app/views/layouts/nav/_new_profile_sidebar.html.haml b/app/views/layouts/nav/_new_profile_sidebar.html.haml index 85b2c7630c8..ccb6d1492f1 100644 --- a/app/views/layouts/nav/_new_profile_sidebar.html.haml +++ b/app/views/layouts/nav/_new_profile_sidebar.html.haml @@ -7,76 +7,76 @@ .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 + = sidebar_link profile_path, title: _('Profile Settings') do .nav-icon-container = custom_icon('profile') %span.nav-item-name Profile = nav_link(controller: [:accounts, :two_factor_auths]) do - = link_to profile_account_path, title: 'Account' do + = sidebar_link profile_account_path, title: _('Account') do .nav-icon-container = custom_icon('account') %span.nav-item-name Account - if current_application_settings.user_oauth_applications? = nav_link(controller: 'oauth/applications') do - = link_to applications_profile_path, title: 'Applications' do + = sidebar_link applications_profile_path, title: _('Applications') do .nav-icon-container = custom_icon('applications') %span.nav-item-name Applications = nav_link(controller: :chat_names) do - = link_to profile_chat_names_path, title: 'Chat' do + = sidebar_link profile_chat_names_path, title: _('Chat') do .nav-icon-container = custom_icon('chat') %span.nav-item-name Chat = nav_link(controller: :personal_access_tokens) do - = link_to profile_personal_access_tokens_path, title: 'Access Tokens' do + = sidebar_link profile_personal_access_tokens_path, title: _('Access Tokens') do .nav-icon-container = custom_icon('access_tokens') %span.nav-item-name Access Tokens = nav_link(controller: :emails) do - = link_to profile_emails_path, title: 'Emails' do + = sidebar_link profile_emails_path, title: _('Emails') do .nav-icon-container = custom_icon('emails') %span.nav-item-name Emails - unless current_user.ldap_user? = nav_link(controller: :passwords) do - = link_to edit_profile_password_path, title: 'Password' do + = sidebar_link edit_profile_password_path, title: _('Password') do .nav-icon-container = custom_icon('lock') %span.nav-item-name Password = nav_link(controller: :notifications) do - = link_to profile_notifications_path, title: 'Notifications' do + = sidebar_link profile_notifications_path, title: _('Notifications') do .nav-icon-container = custom_icon('notifications') %span.nav-item-name Notifications = nav_link(controller: :keys) do - = link_to profile_keys_path, title: 'SSH Keys' do + = sidebar_link profile_keys_path, title: _('SSH Keys') do .nav-icon-container = custom_icon('key') %span.nav-item-name SSH Keys = nav_link(controller: :gpg_keys) do - = link_to profile_gpg_keys_path, title: 'GPG Keys' do + = sidebar_link profile_gpg_keys_path, title: _('GPG Keys') do .nav-icon-container = custom_icon('key_2') %span.nav-item-name GPG Keys = nav_link(controller: :preferences) do - = link_to profile_preferences_path, title: 'Preferences' do + = sidebar_link profile_preferences_path, title: _('Preferences') do .nav-icon-container = custom_icon('preferences') %span.nav-item-name Preferences = nav_link(path: 'profiles#audit_log') do - = link_to audit_log_profile_path, title: 'Authentication log' do + = sidebar_link audit_log_profile_path, title: _('Authentication log') do .nav-icon-container = custom_icon('authentication_log') %span.nav-item-name diff --git a/app/views/layouts/nav/_new_project_sidebar.html.haml b/app/views/layouts/nav/_new_project_sidebar.html.haml index 341943cf833..53dbf9e2f2b 100644 --- a/app/views/layouts/nav/_new_project_sidebar.html.haml +++ b/app/views/layouts/nav/_new_project_sidebar.html.haml @@ -9,7 +9,7 @@ = @project.name %ul.sidebar-top-level-items = nav_link(path: ['projects#show', 'projects#activity', 'cycle_analytics#show'], html_options: { class: 'home' }) do - = link_to project_path(@project), title: 'Project overview', class: 'shortcuts-project' do + = sidebar_link project_path(@project), title: _('Project overview'), css: 'shortcuts-project' do .nav-icon-container = custom_icon('project') %span.nav-item-name @@ -31,7 +31,7 @@ - if project_nav_tab? :files = nav_link(controller: %w(tree blob blame edit_tree new_tree find_file commit commits compare projects/repositories tags branches releases graphs network)) do - = link_to project_tree_path(@project), title: 'Repository', class: 'shortcuts-tree' do + = sidebar_link project_tree_path(@project), title: _('Repository'), css: 'shortcuts-tree' do .nav-icon-container = custom_icon('doc_text') %span.nav-item-name @@ -72,7 +72,7 @@ - if project_nav_tab? :container_registry = nav_link(controller: %w[projects/registry/repositories]) do - = link_to project_container_registry_index_path(@project), title: 'Container Registry', class: 'shortcuts-container-registry' do + = sidebar_link project_container_registry_index_path(@project), title: _('Container Registry'), css: 'shortcuts-container-registry' do .nav-icon-container = custom_icon('container_registry') %span.nav-item-name @@ -80,7 +80,7 @@ - if project_nav_tab? :issues = nav_link(controller: @project.issues_enabled? ? [:issues, :labels, :milestones, :boards] : :issues) do - = link_to project_issues_path(@project), title: 'Issues', class: 'shortcuts-issues' do + = sidebar_link project_issues_path(@project), title: _('Issues'), css: 'shortcuts-issues' do .nav-icon-container = custom_icon('issues') %span.nav-item-name @@ -112,7 +112,7 @@ - if project_nav_tab? :merge_requests = nav_link(controller: @project.issues_enabled? ? :merge_requests : [:merge_requests, :labels, :milestones]) do - = link_to project_merge_requests_path(@project), title: 'Merge Requests', class: 'shortcuts-merge_requests' do + = sidebar_link project_merge_requests_path(@project), title: _('Merge Requests'), css: 'shortcuts-merge_requests' do .nav-icon-container = custom_icon('mr_bold') %span.nav-item-name @@ -122,7 +122,7 @@ - if project_nav_tab? :pipelines = nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :environments, :artifacts]) do - = link_to project_pipelines_path(@project), title: 'CI / CD', class: 'shortcuts-pipelines' do + = sidebar_link project_pipelines_path(@project), title: _('CI / CD'), css: 'shortcuts-pipelines' do .nav-icon-container = custom_icon('pipeline') %span.nav-item-name @@ -161,7 +161,7 @@ - if project_nav_tab? :wiki = nav_link(controller: :wikis) do - = link_to get_project_wiki_path(@project), title: 'Wiki', class: 'shortcuts-wiki' do + = sidebar_link get_project_wiki_path(@project), title: _('Wiki'), css: 'shortcuts-wiki' do .nav-icon-container = custom_icon('wiki') %span.nav-item-name @@ -169,7 +169,7 @@ - if project_nav_tab? :snippets = nav_link(controller: :snippets) do - = link_to project_snippets_path(@project), title: 'Snippets', class: 'shortcuts-snippets' do + = sidebar_link project_snippets_path(@project), title: _('Snippets'), css: 'shortcuts-snippets' do .nav-icon-container = custom_icon('snippets') %span.nav-item-name @@ -177,7 +177,7 @@ - if project_nav_tab? :settings = nav_link(path: %w[projects#edit project_members#index integrations#show services#edit repository#show ci_cd#show pages#show]) do - = link_to edit_project_path(@project), title: 'Settings', class: 'shortcuts-tree' do + = sidebar_link edit_project_path(@project), title: _('Settings'), css: 'shortcuts-tree' do .nav-icon-container = custom_icon('settings') %span.nav-item-name diff --git a/app/views/profiles/gpg_keys/index.html.haml b/app/views/profiles/gpg_keys/index.html.haml index 720a97cddb7..8dbb8aef31b 100644 --- a/app/views/profiles/gpg_keys/index.html.haml +++ b/app/views/profiles/gpg_keys/index.html.haml @@ -12,7 +12,7 @@ Add a GPG key %p.profile-settings-content Before you can add a GPG key you need to - = link_to 'generate it.', help_page_path('user/project/gpg_signed_commits/index.md') + = link_to 'generate it.', help_page_path('user/project/repository/gpg_signed_commits/index.md') = render 'form' %hr %h5 diff --git a/app/views/projects/commit/_signature_badge.html.haml b/app/views/projects/commit/_signature_badge.html.haml index a3783b31b86..d06b29db838 100644 --- a/app/views/projects/commit/_signature_badge.html.haml +++ b/app/views/projects/commit/_signature_badge.html.haml @@ -12,7 +12,7 @@ %span.monospace= signature.gpg_key_primary_keyid - = link_to('Learn more about signing commits', help_page_path('user/project/gpg_signed_commits/index.md'), class: 'gpg-popover-help-link') + = link_to('Learn more about signing commits', help_page_path('user/project/repository/gpg_signed_commits/index.md'), class: 'gpg-popover-help-link') %button{ class: css_classes, data: { toggle: 'popover', html: 'true', placement: 'auto top', title: title, content: content } } = label |