diff --git a/.gitlab/merge_request_templates/Database Changes.md b/.gitlab/merge_request_templates/Database Changes.md new file mode 100644 index 00000000000..2a5c8267872 --- /dev/null +++ b/.gitlab/merge_request_templates/Database Changes.md @@ -0,0 +1,73 @@ +Remove this section and replace it with a description of your MR. Also follow the +checklist below and check off any tasks that are done. If a certain task can not +be done you should explain so in the MR body. You are free to remove any +sections that do not apply to your MR. + +When gathering statistics (e.g. the output of `EXPLAIN ANALYZE`) you should make +sure your database has enough data. Having around 10 000 rows in the tables +being queries should provide a reasonable estimate of how a query will behave. +Also make sure that PostgreSQL uses the following settings: + +* `random_page_cost`: `1` +* `work_mem`: `16MB` +* `maintenance_work_mem`: at least `64MB` +* `shared_buffers`: at least `256MB` + +If you have access to GitLab.com's staging environment you should also run your +measurements there, and include the results in this MR. + +## Database Checklist + +When adding migrations: + +- [ ] Updated `db/schema.rb` +- [ ] Added a `down` method so the migration can be reverted +- [ ] Added the output of the migration(s) to the MR body +- [ ] Added the execution time of the migration(s) to the MR body +- [ ] Added tests for the migration in `spec/migrations` if necessary (e.g. when + migrating data) +- [ ] Made sure the migration won't interfere with a running GitLab cluster, + for example by disabling transactions for long running migrations + +When adding or modifying queries to improve performance: + +- [ ] Included the raw SQL queries of the relevant queries +- [ ] Included the output of `EXPLAIN ANALYZE` and execution timings of the + relevant queries +- [ ] Added tests for the relevant changes + +When adding indexes: + +- [ ] Described the need for these indexes in the MR body +- [ ] Made sure existing indexes can not be reused instead + +When adding foreign keys to existing tables: + +- [ ] Included a migration to remove orphaned rows in the source table +- [ ] Removed any instances of `dependent: ...` that may no longer be necessary + +When adding tables: + +- [ ] Ordered columns based on their type sizes in descending order +- [ ] Added foreign keys if necessary +- [ ] Added indexes if necessary + +When removing columns, tables, indexes or other structures: + +- [ ] Removed these in a post-deployment migration +- [ ] Made sure the application no longer uses (or ignores) these structures + +## General Checklist + +- [ ] [Changelog entry](https://docs.gitlab.com/ce/development/changelog.html) added, if necessary +- [ ] [Documentation created/updated](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/development/doc_styleguide.md) +- [ ] API support added +- [ ] Tests added for this feature/bug +- Review + - [ ] Has been reviewed by UX + - [ ] Has been reviewed by Frontend + - [ ] Has been reviewed by Backend + - [ ] Has been reviewed by Database +- [ ] Conform by the [merge request performance guides](http://docs.gitlab.com/ce/development/merge_request_performance_guidelines.html) +- [ ] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#style-guides) +- [ ] [Squashed related commits together](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits) diff --git a/.rubocop.yml b/.rubocop.yml index 876828f68f1..84e4a3c2e49 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -207,6 +207,13 @@ Layout/SpaceAroundKeyword: Layout/SpaceAroundOperators: Enabled: true +# Checks that block braces have or don't have a space before the opening +# brace depending on configuration. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: space, no_space +Layout/SpaceBeforeBlockBraces: + Enabled: true + # No spaces before commas. Layout/SpaceBeforeComma: Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 9caef3bde08..78ab7f7204f 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -26,13 +26,6 @@ Layout/IndentArray: Layout/IndentHash: Enabled: false -# Offense count: 174 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: space, no_space -Layout/SpaceBeforeBlockBraces: - Enabled: false - # Offense count: 8 # Cop supports --auto-correct. # Configuration parameters: AllowForAlignment. diff --git a/CHANGELOG.md b/CHANGELOG.md index 7493f2562e8..6a9c751937e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ documentation](doc/development/changelog.md) for instructions on adding your own entry. +## 9.4.4 (2017-08-09) + +- Remove hidden symlinks from project import files. +- Disallow Git URLs that include a username or hostname beginning with a non-alphanumeric character. + ## 9.4.3 (2017-07-31) - Fix Prometheus client PID reuse bug. !13130 @@ -226,6 +231,11 @@ entry. - Log rescued exceptions to Sentry. - Remove remaining N+1 queries in merge requests API with emojis and labels. +## 9.3.10 (2017-08-09) + +- Remove hidden symlinks from project import files. +- Disallow Git URLs that include a username or hostname beginning with a non-alphanumeric character. + ## 9.3.9 (2017-07-20) - Fix an infinite loop when handling user-supplied regular expressions. @@ -498,6 +508,11 @@ entry. - Remove foreigh key on ci_trigger_schedules only if it exists. - Allow translation of Pipeline Schedules. +## 9.2.10 (2017-08-09) + +- Remove hidden symlinks from project import files. +- Disallow Git URLs that include a username or hostname beginning with a non-alphanumeric character. + ## 9.2.9 (2017-07-20) - Fix an infinite loop when handling user-supplied regular expressions. @@ -753,6 +768,11 @@ entry. - Fix preemptive scroll bar on user activity calendar. - Pipeline chat notifications convert seconds to minutes and hours. +## 9.1.10 (2017-08-09) + +- Remove hidden symlinks from project import files. +- Disallow Git URLs that include a username or hostname beginning with a non-alphanumeric character. + ## 9.1.9 (2017-07-20) - Fix an infinite loop when handling user-supplied regular expressions. @@ -1076,6 +1096,11 @@ entry. - Only send chat notifications for the default branch. - Don't fill in the default kubernetes namespace. +## 9.0.13 (2017-08-09) + +- Remove hidden symlinks from project import files. +- Disallow Git URLs that include a username or hostname beginning with a non-alphanumeric character. + ## 9.0.12 (2017-07-20) - Fix an infinite loop when handling user-supplied regular expressions. @@ -1456,6 +1481,11 @@ entry. - Change development tanuki favicon colors to match logo color order. - API issues - support filtering by iids. +## 8.17.8 (2017-08-09) + +- Remove hidden symlinks from project import files. +- Disallow Git URLs that include a username or hostname beginning with a non-alphanumeric character. + ## 8.17.7 (2017-07-19) - Renders 404 if given project is not readable by the user on Todos dashboard. diff --git a/Gemfile.lock b/Gemfile.lock index b865ff6ee32..79d1bc51358 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -744,6 +744,7 @@ GEM rubocop-gitlab-security (0.0.6) rubocop (>= 0.47.1) rubocop-rspec (1.15.1) + rubocop (>= 0.42.0) ruby-fogbugz (0.2.1) crack (~> 0.4) ruby-prof (0.16.2) diff --git a/PROCESS.md b/PROCESS.md index 2b3d142bf77..e5b17784d20 100644 --- a/PROCESS.md +++ b/PROCESS.md @@ -119,6 +119,12 @@ only be left until after the freeze if: are aware of it. * It is in the correct milestone, with the ~Deliverable label. +If a merge request is not ready, but the developers and Product Manager +responsible for the feature think it is essential that it is in the release, +they can [ask for an exception](#asking-for-an-exception) in advance. This is +preferable to merging something that we are not confident in, but should still +be a rare case: most features can be allowed to slip a release. + All Community Edition merge requests from GitLab team members merged on the freeze date (the 7th) should have a corresponding Enterprise Edition merge request, even if there are no conflicts. This is to reduce the size of the @@ -128,11 +134,26 @@ information, see ### After the 7th -Once the stable branch is frozen, only fixes for [regressions](#regressions) -and security issues will be cherry-picked into the stable branch. -Any merge requests cherry-picked into the stable branch for a previous release will also be picked into the latest stable branch. -These fixes will be shipped in the next RC for that release if it is before the 22nd. -If the fixes are are completed on or after the 22nd, they will be shipped in a patch for that release. +Once the stable branch is frozen, the only MRs that can be cherry-picked into +the stable branch are: + +* Fixes for [regressions](#regressions) +* Fixes for security issues +* New or updated translations (as long as they do not touch application code) + +Any merge requests cherry-picked into the stable branch for a previous release +will also be picked into the latest stable branch. These fixes will be shipped +in the next RC for that release if it is before the 22nd. If the fixes are are +completed on or after the 22nd, they will be shipped in a patch for that +release. + +During the feature freeze all merge requests that are meant to go into the upcoming +release should have the correct milestone assigned _and_ have the label +~"Pick into Stable" set, so that release managers can find and pick them. +Merge requests without a milestone and this label will +not be merged into any stable branches. + +### Asking for an exception If you think a merge request should go into an RC or patch even though it does not meet these requirements, you can ask for an exception to be made. Exceptions require sign-off from 3 people besides the developer: @@ -152,11 +173,7 @@ When in doubt, we err on the side of _not_ cherry-picking. For example, it is likely that an exception will be made for a trivial 1-5 line performance improvement (e.g. adding a database index or adding `includes` to a query), but not for a new feature, no matter how relatively small or thoroughly tested. -During the feature freeze all merge requests that are meant to go into the upcoming -release should have the correct milestone assigned _and_ have the label -~"Pick into Stable" set, so that release managers can find and pick them. -Merge requests without a milestone and this label will -not be merged into any stable branches. +All MRs which have had exceptions granted must be merged by the 15th. ### Regressions diff --git a/app/assets/javascripts/boards/components/modal/list.js b/app/assets/javascripts/boards/components/modal/list.js index 363269c0d5d..b4a45feee4d 100644 --- a/app/assets/javascripts/boards/components/modal/list.js +++ b/app/assets/javascripts/boards/components/modal/list.js @@ -1,7 +1,7 @@ /* global ListIssue */ -/* global bp */ import Vue from 'vue'; +import bp from '../../../breakpoints'; const ModalStore = gl.issueBoards.ModalStore; diff --git a/app/assets/javascripts/breakpoints.js b/app/assets/javascripts/breakpoints.js index 2c1f988d987..7951348d8b2 100644 --- a/app/assets/javascripts/breakpoints.js +++ b/app/assets/javascripts/breakpoints.js @@ -1,66 +1,19 @@ -/* eslint-disable func-names, space-before-function-paren, wrap-iife, one-var, no-var, one-var-declaration-per-line, quotes, no-shadow, prefer-arrow-callback, prefer-template, consistent-return, no-return-assign, new-parens, no-param-reassign, max-len */ +export const breakpoints = { + lg: 1200, + md: 992, + sm: 768, + xs: 0, +}; -var Breakpoints = (function() { - var BreakpointInstance, instance; +const BreakpointInstance = { + windowWidth: () => window.innerWidth, + getBreakpointSize() { + const windowWidth = this.windowWidth(); - function Breakpoints() {} + const breakpoint = Object.keys(breakpoints).find(key => windowWidth > breakpoints[key]); - instance = null; + return breakpoint; + }, +}; - BreakpointInstance = (function() { - var BREAKPOINTS; - - BREAKPOINTS = ["xs", "sm", "md", "lg"]; - - function BreakpointInstance() { - this.setup(); - } - - BreakpointInstance.prototype.setup = function() { - var allDeviceSelector, els; - allDeviceSelector = BREAKPOINTS.map(function(breakpoint) { - return ".device-" + breakpoint; - }); - if ($(allDeviceSelector.join(",")).length) { - return; - } - // Create all the elements - els = $.map(BREAKPOINTS, function(breakpoint) { - return "
"; - }); - return $("body").append(els.join('')); - }; - - BreakpointInstance.prototype.visibleDevice = function() { - var allDeviceSelector; - allDeviceSelector = BREAKPOINTS.map(function(breakpoint) { - return ".device-" + breakpoint; - }); - return $(allDeviceSelector.join(",")).filter(":visible"); - }; - - BreakpointInstance.prototype.getBreakpointSize = function() { - var $visibleDevice; - $visibleDevice = this.visibleDevice; - // TODO: Consider refactoring in light of turbolinks removal. - // the page refreshed via turbolinks - if (!$visibleDevice().length) { - this.setup(); - } - $visibleDevice = this.visibleDevice(); - return $visibleDevice.attr("class").split("visible-")[1]; - }; - - return BreakpointInstance; - })(); - - Breakpoints.get = function() { - return instance != null ? instance : instance = new BreakpointInstance; - }; - - return Breakpoints; -})(); - -$(() => { window.bp = Breakpoints.get(); }); - -window.Breakpoints = Breakpoints; +export default BreakpointInstance; diff --git a/app/assets/javascripts/build.js b/app/assets/javascripts/build.js index 940326dcd33..ae1a23132a7 100644 --- a/app/assets/javascripts/build.js +++ b/app/assets/javascripts/build.js @@ -1,8 +1,7 @@ /* eslint-disable func-names, wrap-iife, no-use-before-define, consistent-return, prefer-rest-params */ -/* global Breakpoints */ - import _ from 'underscore'; +import bp from './breakpoints'; import { bytesToKiB } from './lib/utils/number_utils'; window.Build = (function () { @@ -34,8 +33,6 @@ window.Build = (function () { this.$scrollBottomBtn = $('.js-scroll-down'); clearTimeout(Build.timeout); - // Init breakpoint checker - this.bp = Breakpoints.get(); this.initSidebar(); this.populateJobs(this.buildStage); @@ -230,7 +227,7 @@ window.Build = (function () { }; Build.prototype.shouldHideSidebarForViewport = function () { - const bootstrapBreakpoint = this.bp.getBreakpointSize(); + const bootstrapBreakpoint = bp.getBreakpointSize(); return bootstrapBreakpoint === 'xs' || bootstrapBreakpoint === 'sm'; }; diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index 7cc7636cca3..8c5a4367440 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -76,6 +76,7 @@ import initLegacyFilters from './init_legacy_filters'; import initIssuableSidebar from './init_issuable_sidebar'; import GpgBadges from './gpg_badges'; import UserFeatureHelper from './helpers/user_feature_helper'; +import initChangesDropdown from './init_changes_dropdown'; (function() { var Dispatcher; @@ -228,6 +229,7 @@ import UserFeatureHelper from './helpers/user_feature_helper'; break; case 'projects:compare:show': new gl.Diff(); + initChangesDropdown(); break; case 'projects:branches:new': case 'projects:branches:create': @@ -320,6 +322,7 @@ import UserFeatureHelper from './helpers/user_feature_helper'; container: '.js-commit-pipeline-graph', }).bindEvents(); initNotes(); + initChangesDropdown(); $('.commit-info.branches').load(document.querySelector('.js-commit-box').dataset.commitPath); break; case 'projects:commit:pipelines': diff --git a/app/assets/javascripts/due_date_select.js b/app/assets/javascripts/due_date_select.js index 2856c8e2862..ee71728184f 100644 --- a/app/assets/javascripts/due_date_select.js +++ b/app/assets/javascripts/due_date_select.js @@ -1,7 +1,7 @@ /* eslint-disable wrap-iife, func-names, space-before-function-paren, comma-dangle, prefer-template, consistent-return, class-methods-use-this, arrow-body-style, no-unused-vars, no-underscore-dangle, no-new, max-len, no-sequences, no-unused-expressions, no-param-reassign */ /* global dateFormat */ -/* global Pikaday */ +import Pikaday from 'pikaday'; import DateFix from './lib/utils/datefix'; class DueDateSelect { diff --git a/app/assets/javascripts/fly_out_nav.js b/app/assets/javascripts/fly_out_nav.js index aabea56408a..56744a440e7 100644 --- a/app/assets/javascripts/fly_out_nav.js +++ b/app/assets/javascripts/fly_out_nav.js @@ -1,6 +1,5 @@ -/* global bp */ import Cookies from 'js-cookie'; -import './breakpoints'; +import bp from './breakpoints'; export const canShowActiveSubItems = (el) => { const isHiddenByMedia = bp.getBreakpointSize() === 'sm' || bp.getBreakpointSize() === 'md'; @@ -49,7 +48,8 @@ export const hideSubLevelItems = (el) => { el.classList.remove('is-showing-fly-out'); el.classList.remove('is-over'); - subItems.style.display = 'none'; + subItems.style.display = ''; + subItems.style.transform = ''; subItems.classList.remove('is-above'); }; diff --git a/app/assets/javascripts/init_changes_dropdown.js b/app/assets/javascripts/init_changes_dropdown.js new file mode 100644 index 00000000000..f785ed29e6c --- /dev/null +++ b/app/assets/javascripts/init_changes_dropdown.js @@ -0,0 +1,10 @@ +import stickyMonitor from './lib/utils/sticky'; + +export default () => { + stickyMonitor(document.querySelector('.js-diff-files-changed')); + + $('.js-diff-stats-dropdown').glDropdown({ + filterable: true, + remoteFilter: false, + }); +}; diff --git a/app/assets/javascripts/issuable_context.js b/app/assets/javascripts/issuable_context.js index 26392db4b5b..70c364e51fe 100644 --- a/app/assets/javascripts/issuable_context.js +++ b/app/assets/javascripts/issuable_context.js @@ -1,7 +1,6 @@ /* eslint-disable func-names, space-before-function-paren, wrap-iife, no-new, comma-dangle, quotes, prefer-arrow-callback, consistent-return, one-var, no-var, one-var-declaration-per-line, no-underscore-dangle, max-len */ -/* global bp */ - import Cookies from 'js-cookie'; +import bp from './breakpoints'; import UsersSelect from './users_select'; const PARTICIPANTS_ROW_COUNT = 7; diff --git a/app/assets/javascripts/issuable_form.js b/app/assets/javascripts/issuable_form.js index 9ac1325fc95..3f848e0859b 100644 --- a/app/assets/javascripts/issuable_form.js +++ b/app/assets/javascripts/issuable_form.js @@ -2,8 +2,8 @@ /* global GitLab */ /* global Autosave */ /* global dateFormat */ -/* global Pikaday */ +import Pikaday from 'pikaday'; import UsersSelect from './users_select'; import GfmAutoComplete from './gfm_auto_complete'; import ZenMode from './zen_mode'; diff --git a/app/assets/javascripts/jobs/components/header.vue b/app/assets/javascripts/jobs/components/header.vue index 5b9cf577189..3f6f40d47ba 100644 --- a/app/assets/javascripts/jobs/components/header.vue +++ b/app/assets/javascripts/jobs/components/header.vue @@ -40,7 +40,7 @@ label: 'New issue', path: this.job.new_issue_path, cssClass: 'js-new-issue btn btn-new btn-inverted visible-md-block visible-lg-block', - type: 'ujs-link', + type: 'link', }); } diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index 42092a34c2f..37f531c78f4 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -1,5 +1,4 @@ /* eslint-disable func-names, space-before-function-paren, no-var, quotes, consistent-return, prefer-arrow-callback, comma-dangle, object-shorthand, no-new, max-len, no-multi-spaces, import/newline-after-import, import/first */ -/* global bp */ /* global Flash */ /* global ConfirmDangerModal */ /* global Aside */ @@ -7,7 +6,6 @@ import jQuery from 'jquery'; import _ from 'underscore'; import Cookies from 'js-cookie'; -import Pikaday from 'pikaday'; import Dropzone from 'dropzone'; import Sortable from 'vendor/Sortable'; @@ -20,7 +18,6 @@ import 'vendor/fuzzaldrin-plus'; window.jQuery = jQuery; window.$ = jQuery; window._ = _; -window.Pikaday = Pikaday; window.Dropzone = Dropzone; window.Sortable = Sortable; @@ -68,7 +65,7 @@ import './api'; import './aside'; import './autosave'; import loadAwardsHandler from './awards_handler'; -import './breakpoints'; +import bp from './breakpoints'; import './broadcast_message'; import './build'; import './build_artifacts'; diff --git a/app/assets/javascripts/member_expiration_date.js b/app/assets/javascripts/member_expiration_date.js index e034729bd39..cc9016e74da 100644 --- a/app/assets/javascripts/member_expiration_date.js +++ b/app/assets/javascripts/member_expiration_date.js @@ -1,5 +1,7 @@ -/* global Pikaday */ /* global dateFormat */ + +import Pikaday from 'pikaday'; + (() => { // Add datepickers to all `js-access-expiration-date` elements. If those elements are // children of an element with the `clearable-input` class, and have a sibling diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js index 4ffd71d9de5..5a9b3d19f84 100644 --- a/app/assets/javascripts/merge_request_tabs.js +++ b/app/assets/javascripts/merge_request_tabs.js @@ -1,13 +1,12 @@ /* eslint-disable no-new, class-methods-use-this */ -/* global Breakpoints */ /* global Flash */ /* global notes */ import Cookies from 'js-cookie'; -import './breakpoints'; import './flash'; import BlobForkSuggestion from './blob/blob_fork_suggestion'; -import stickyMonitor from './lib/utils/sticky'; +import initChangesDropdown from './init_changes_dropdown'; +import bp from './breakpoints'; /* eslint-disable max-len */ // MergeRequestTabs @@ -134,7 +133,7 @@ import stickyMonitor from './lib/utils/sticky'; this.destroyPipelinesView(); } else if (this.isDiffAction(action)) { this.loadDiff($target.attr('href')); - if (Breakpoints.get().getBreakpointSize() !== 'lg') { + if (bp.getBreakpointSize() !== 'lg') { this.shrinkView(); } if (this.diffViewType() === 'parallel') { @@ -145,7 +144,7 @@ import stickyMonitor from './lib/utils/sticky'; this.resetViewContainer(); this.mountPipelinesView(); } else { - if (Breakpoints.get().getBreakpointSize() !== 'xs') { + if (bp.getBreakpointSize() !== 'xs') { this.expandView(); } this.resetViewContainer(); @@ -267,9 +266,7 @@ import stickyMonitor from './lib/utils/sticky'; const $container = $('#diffs'); $container.html(data.html); - this.initChangesDropdown(); - - stickyMonitor(document.querySelector('.js-diff-files-changed')); + initChangesDropdown(); if (typeof gl.diffNotesCompileComponents !== 'undefined') { gl.diffNotesCompileComponents(); @@ -319,13 +316,6 @@ import stickyMonitor from './lib/utils/sticky'; }); } - initChangesDropdown() { - $('.js-diff-stats-dropdown').glDropdown({ - filterable: true, - remoteFilter: false, - }); - } - // Show or hide the loading spinner // // status - Boolean, true to show, false to hide @@ -401,7 +391,7 @@ import stickyMonitor from './lib/utils/sticky'; // Screen space on small screens is usually very sparse // So we dont affix the tabs on these - if (Breakpoints.get().getBreakpointSize() === 'xs' || !$tabs.length) return; + if (bp.getBreakpointSize() === 'xs' || !$tabs.length) return; /** If the browser does not support position sticky, it returns the position as static. diff --git a/app/assets/javascripts/monitoring/components/monitoring_column.vue b/app/assets/javascripts/monitoring/components/monitoring_column.vue index c376baea79c..407af51cb7a 100644 --- a/app/assets/javascripts/monitoring/components/monitoring_column.vue +++ b/app/assets/javascripts/monitoring/components/monitoring_column.vue @@ -1,5 +1,4 @@