Commit 5fcbe127 authored by Mike Greiling's avatar Mike Greiling

Merge branch 'master' into go-go-gadget-webpack

* master: (83 commits)
  Fix small typo on new branch button spec
  Abillity to promote project labels to group labels
  Update and pin the `jwt` gem to ~> 1.5.6
  refactor merge request build service
  Update index.md
  Clarify that Auto Deploy requires a public project.
  cop for gem fetched from a git source
  Add CHANGELOG entry
  Remove new branch button for confidential issues
  Remove flash warning from login page
  add complete changelog
  Add project ID index to `project_authorizations` table to optimize queries
  Fix disable storing of sensitive information when importing a new repo
  Fix notification when global=disabled, group=watch
  Ensure rake is called within the correct bundle context
  Fix 8.16.0 release date.
  Improve search within group logic
  Add changelog item about new attributes in group api
  Update group api doc with full_name and full_path attributes
  Add tests for nested groups in search service and search helper
  ...
parents ecdcd1be 2c358b4b
......@@ -273,7 +273,7 @@ rake db:migrate:reset:
<<: *use-db
<<: *dedicated-runner
script:
- rake db:migrate:reset
- bundle exec rake db:migrate:reset
rake db:seed_fu:
stage: test
......@@ -303,7 +303,7 @@ karma:
<<: *dedicated-runner
script:
- npm link istanbul
- rake karma
- bundle exec rake karma
artifacts:
name: coverage-javascript
expire_in: 31d
......@@ -354,10 +354,10 @@ migration paths:
- cp config/resque.yml.example config/resque.yml
- sed -i 's/localhost/redis/g' config/resque.yml
- bundle install --without postgres production --jobs $(nproc) $FLAGS --retry=3
- rake db:drop db:create db:schema:load db:seed_fu
- bundle exec rake db:drop db:create db:schema:load db:seed_fu
- git checkout $CI_BUILD_REF
- source scripts/prepare_build.sh
- rake db:migrate
- bundle exec rake db:migrate
coverage:
stage: post-test
......
......@@ -18,7 +18,7 @@ entry.
- Prevent users from deleting system deploy keys via the project deploy key API.
- Upgrade omniauth gem to 1.3.2.
## 8.16.0 (2017-02-22)
## 8.16.0 (2017-01-22)
- Add LDAP Rake task to rename a provider. !2181
- Validate label's title length. !5767 (Tomáš Kukrál)
......
......@@ -35,7 +35,7 @@ gem 'omniauth-twitter', '~> 1.2.0'
gem 'omniauth_crowd', '~> 2.2.0'
gem 'omniauth-authentiq', '~> 0.2.0'
gem 'rack-oauth2', '~> 1.2.1'
gem 'jwt'
gem 'jwt', '~> 1.5.6'
# Spam and anti-bot protection
gem 'recaptcha', '~> 3.0', require: 'recaptcha/rails'
......
......@@ -375,7 +375,7 @@ GEM
json (1.8.3)
json-schema (2.6.2)
addressable (~> 2.3.8)
jwt (1.5.4)
jwt (1.5.6)
kaminari (0.17.0)
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
......@@ -900,7 +900,7 @@ DEPENDENCIES
jquery-rails (~> 4.1.0)
jquery-ui-rails (~> 5.0.0)
json-schema (~> 2.6.2)
jwt
jwt (~> 1.5.6)
kaminari (~> 0.17.0)
knapsack (~> 1.11.0)
kubeclient (~> 2.2.0)
......@@ -1007,4 +1007,4 @@ DEPENDENCIES
wikicloth (= 0.8.1)
BUNDLED WITH
1.13.7
1.14.2
......@@ -12,106 +12,54 @@ etc.).
## Common actions
### Issue team
- Looks for issues without [workflow labels](#how-we-handle-issues) and triages
issue
- Closes invalid issues with a comment (duplicates,
[fixed in newer version](#issue-fixed-in-newer-version),
[issue report for old version](#issue-report-for-old-version), not a problem
in GitLab, etc.)
- Asks for feedback from issue reporter
([invalid issue reports](#improperly-formatted-issue),
[format code](#code-format), etc.)
- Monitors all issues for feedback (but especially ones commented on since
automatically watching them)
- Closes issues with no feedback from the reporter for two weeks
### Merge marshall & merge request coach
- Responds to merge requests the issue team mentions them in and monitors for
new merge requests
- Provides feedback to the merge request submitter to improve the merge request
(style, tests, etc.)
- Mark merge requests `Ready for Merge` when they meet the
[contribution acceptance criteria]
- Mention developer(s) based on the
[list of members and their specialities][team]
- Closes merge requests with no feedback from the reporter for two weeks
## Priorities of the issue team
1. Mentioning people (critical)
1. Workflow labels (normal)
1. Functional labels (minor)
1. Assigning issues (avoid if possible)
## Mentioning people
### Issue triaging
Our issue triage policies are [described in our handbook]. You are very welcome
to help the GitLab team triage issues. We also organize [issue bash events] once
every quarter.
The most important thing is making sure valid issues receive feedback from the
development team. Therefore the priority is mentioning developers that can help
on those issues. Please select someone with relevant experience from
[GitLab core team][core-team]. If there is nobody mentioned with that expertise
[GitLab team][team]. If there is nobody mentioned with that expertise
look in the commit history for the affected files to find someone. Avoid
mentioning the lead developer, this is the person that is least likely to give a
timely response. If the involvement of the lead developer is needed the other
core team members will mention this person.
## Workflow labels
[described in our handbook]: https://about.gitlab.com/handbook/engineering/issues/issue-triage-policies/
[issue bash events]: https://gitlab.com/gitlab-org/gitlab-ce/issues/17815
Workflow labels are purposely not very detailed since that would be hard to keep
updated as you would need to re-evaluate them after every comment. We optionally
use functional labels on demand when we want to group related issues to get an
overview (for example all issues related to RVM, to tackle them in one go) and
to add details to the issue.
### Merge request coaching
- ~"Awaiting Feedback" Feedback pending from the reporter
- ~UX needs help from a UX designer
- ~Frontend needs help from a Front-end engineer. Please follow the
["Implement design & UI elements" guidelines].
- ~"Accepting Merge Requests" is a low priority, well-defined issue that we
encourage people to contribute to. Not exclusive with other labels.
- ~"feature proposal" is a proposal for a new feature for GitLab. People are encouraged to vote
in support or comment for further detail. Do not use `feature request`.
- ~bug is an issue reporting undesirable or incorrect behavior.
- ~customer is an issue reported by enterprise subscribers. This label should
be accompanied by *bug* or *feature proposal* labels.
Several people from the [GitLab team][team] are helping community members to get
their contributions accepted by meeting our [Definition of done][CONTRIBUTING.md#definition-of-done].
Example workflow: when a UX designer provided a design but it needs frontend work they remove the UX label and add the frontend label.
What you can expect from them is described at https://about.gitlab.com/jobs/merge-request-coach/.
## Workflow labels
## Functional labels
Labelling issues is described in the [GitLab Inc engineering workflow].
These labels describe what development specialities are involved such as: `CI`,
`Core`, `Documentation`, `Frontend`, `Issues`, `Merge Requests`, `Omnibus`,
`Release`, `Repository`, `UX`.
[GitLab Inc engineering workflow]: https://about.gitlab.com/handbook/engineering/workflow/#labelling-issues
## Assigning issues
If an issue is complex and needs the attention of a specific person, assignment is a good option but assigning issues might discourage other people from contributing to that issue. We need all the contributions we can get so this should never be discouraged. Also, an assigned person might not have time for a few weeks, so others should feel free to takeover.
## Label colors
- Light orange `#fef2c0`: workflow labels for issue team members (awaiting
feedback, awaiting confirmation of fix)
- Bright orange `#eb6420`: workflow labels for core team members (attached MR,
awaiting developer action/feedback)
- Light blue `#82C5FF`: functional labels
- Green labels `#009800`: issues that can generally be ignored. For example,
issues given the following labels normally can be closed immediately:
- Support (see copy & paste response:
[Support requests and configuration questions](#support-requests-and-configuration-questions)
## Be kind
Be kind to people trying to contribute. Be aware that people may be a non-native
English speaker, they might not understand things or they might be very
sensitive as to how you word things. Use Emoji to express your feelings (heart,
star, smile, etc.). Some good tips about giving feedback to merge requests is in
the [Thoughtbot code review guide].
star, smile, etc.). Some good tips about code reviews can be found in our
[Code Review Guidelines].
[Code Review Guidelines]: https://docs.gitlab.com/ce/development/code_review.html
## Feature Freeze
5 working days before the 22nd the stable branches for the upcoming release will
On the 7th of each month, the stable branches for the upcoming release will
be frozen for major changes. Merge requests may still be merged into master
during this period. By freezing the stable branches prior to a release there's
no need to worry about last minute merge requests potentially breaking a lot of
......@@ -120,10 +68,9 @@ things.
What is considered to be a major change is determined on a case by case basis as
this definition depends very much on the context of changes. For example, a 5
line change might have a big impact on the entire application. Ultimately the
decision will be made by those reviewing a merge request and the release
manager.
decision will be made by the maintainers and the release managers.
During the feature freeze all merge requests that are meant to go into the next
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. Merge requests without a milestone and this label will
not be merged into any stable branches.
......@@ -189,7 +136,6 @@ prevent duplication with the GitLab.com issue tracker.
Since this is an older issue I'll be closing this for now. If you think this is
still an issue I encourage you to open it on the \[GitLab.com issue tracker\]\(https://gitlab.com/gitlab-org/gitlab-ce/issues).
[core-team]: https://about.gitlab.com/core-team/
[team]: https://about.gitlab.com/team/
[contribution acceptance criteria]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#contribution-acceptance-criteria
["Implement design & UI elements" guidelines]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#implement-design-ui-elements
......
......@@ -2,7 +2,6 @@
/* global autosize */
var autosize = require('vendor/autosize');
require('vendor/jquery.ba-resize');
(function() {
$(function() {
......
......@@ -29,6 +29,12 @@
watch: {
detail: {
handler () {
if (this.issue.id !== this.detail.issue.id) {
$('.js-issue-board-sidebar', this.$el).each((i, el) => {
$(el).data('glDropdown').clearMenu();
});
}
this.issue = this.detail.issue;
},
deep: true
......
......@@ -8,7 +8,6 @@
/* global ShortcutsIssuable */
/* global ZenMode */
/* global Milestone */
/* global GLForm */
/* global IssuableForm */
/* global LabelsSelect */
/* global MilestoneSelect */
......@@ -64,17 +63,6 @@
new UsernameValidator();
new ActiveTabMemoizer();
break;
case 'sessions:create':
if (!gon.u2f) break;
window.gl.u2fAuthenticate = new gl.U2FAuthenticate(
$("#js-authenticate-u2f"),
'#js-login-u2f-form',
gon.u2f,
document.querySelector('#js-login-2fa-device'),
document.querySelector('.js-2fa-form'),
);
window.gl.u2fAuthenticate.start();
break;
case 'projects:boards:show':
case 'projects:boards:index':
shortcut_handler = new ShortcutsNavigation();
......@@ -110,7 +98,7 @@
case 'projects:milestones:edit':
new ZenMode();
new gl.DueDateSelectors();
new GLForm($('.milestone-form'));
new gl.GLForm($('.milestone-form'));
break;
case 'groups:milestones:new':
new ZenMode();
......@@ -121,7 +109,7 @@
case 'projects:issues:new':
case 'projects:issues:edit':
shortcut_handler = new ShortcutsNavigation();
new GLForm($('.issue-form'));
new gl.GLForm($('.issue-form'));
new IssuableForm($('.issue-form'));
new LabelsSelect();
new MilestoneSelect();
......@@ -131,7 +119,7 @@
case 'projects:merge_requests:edit':
new gl.Diff();
shortcut_handler = new ShortcutsNavigation();
new GLForm($('.merge-request-form'));
new gl.GLForm($('.merge-request-form'));
new IssuableForm($('.merge-request-form'));
new LabelsSelect();
new MilestoneSelect();
......@@ -139,11 +127,11 @@
break;
case 'projects:tags:new':
new ZenMode();
new GLForm($('.tag-form'));
new gl.GLForm($('.tag-form'));
break;
case 'projects:releases:edit':
new ZenMode();
new GLForm($('.release-form'));
new gl.GLForm($('.release-form'));
break;
case 'projects:merge_requests:show':
new gl.Diff();
......@@ -280,6 +268,17 @@
break;
}
switch (path.first()) {
case 'sessions':
case 'omniauth_callbacks':
if (!gon.u2f) break;
gl.u2fAuthenticate = new gl.U2FAuthenticate(
$('#js-authenticate-u2f'),
'#js-login-u2f-form',
gon.u2f,
document.querySelector('#js-login-2fa-device'),
document.querySelector('.js-2fa-form'),
);
gl.u2fAuthenticate.start();
case 'admin':
new Admin();
switch (path[1]) {
......@@ -332,7 +331,7 @@
new gl.Wikis();
shortcut_handler = new ShortcutsNavigation();
new ZenMode();
new GLForm($('.wiki-form'));
new gl.GLForm($('.wiki-form'));
break;
case 'snippets':
shortcut_handler = new ShortcutsNavigation();
......@@ -357,7 +356,7 @@
}
// If we haven't installed a custom shortcut handler, install the default one
if (!shortcut_handler) {
return new Shortcuts();
new Shortcuts();
}
};
......
......@@ -512,12 +512,17 @@
// Append the menu into the dropdown
GitLabDropdown.prototype.appendMenu = function(html) {
return this.clearMenu().append(html);
};
GitLabDropdown.prototype.clearMenu = function() {
var selector;
selector = '.dropdown-content';
if (this.dropdown.find(".dropdown-toggle-page").length) {
selector = ".dropdown-page-one .dropdown-content";
}
return $(selector, this.dropdown).empty().append(html);
return $(selector, this.dropdown).empty();
};
GitLabDropdown.prototype.renderItem = function(data, group, index) {
......
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-new, max-len */
/* global GitLab */
/* global DropzoneInput */
/* global autosize */
var autosize = require('vendor/autosize');
(function() {
this.GLForm = (function() {
function GLForm(form) {
this.form = form;
this.textarea = this.form.find('textarea.js-gfm-input');
// Before we start, we should clean up any previous data for this form
this.destroy();
// Setup the form
this.setupForm();
this.form.data('gl-form', this);
}
GLForm.prototype.destroy = function() {
// Clean form listeners
this.clearEventListeners();
return this.form.data('gl-form', null);
};
GLForm.prototype.setupForm = function() {
var isNewForm;
isNewForm = this.form.is(':not(.gfm-form)');
this.form.removeClass('js-new-note-form');
if (isNewForm) {
this.form.find('.div-dropzone').remove();
this.form.addClass('gfm-form');
// remove notify commit author checkbox for non-commit notes
gl.utils.disableButtonIfEmptyField(this.form.find('.js-note-text'), this.form.find('.js-comment-button'));
gl.GfmAutoComplete.setup(this.form.find('.js-gfm-input'));
new DropzoneInput(this.form);
autosize(this.textarea);
// form and textarea event listeners
this.addEventListeners();
}
gl.text.init(this.form);
// hide discard button
this.form.find('.js-note-discard').hide();
return this.form.show();
};
GLForm.prototype.clearEventListeners = function() {
this.textarea.off('focus');
this.textarea.off('blur');
return gl.text.removeListeners(this.form);
};
GLForm.prototype.addEventListeners = function() {
this.textarea.on('focus', function() {
return $(this).closest('.md-area').addClass('is-focused');
});
return this.textarea.on('blur', function() {
return $(this).closest('.md-area').removeClass('is-focused');
});
};
return GLForm;
})();
}).call(this);
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-new, max-len */
/* global GitLab */
/* global DropzoneInput */
/* global autosize */
(() => {
const global = window.gl || (window.gl = {});
function GLForm(form) {
this.form = form;
this.textarea = this.form.find('textarea.js-gfm-input');
// Before we start, we should clean up any previous data for this form
this.destroy();
// Setup the form
this.setupForm();
this.form.data('gl-form', this);
}
GLForm.prototype.destroy = function() {
// Clean form listeners
this.clearEventListeners();
return this.form.data('gl-form', null);
};
GLForm.prototype.setupForm = function() {
var isNewForm;
isNewForm = this.form.is(':not(.gfm-form)');
this.form.removeClass('js-new-note-form');
if (isNewForm) {
this.form.find('.div-dropzone').remove();
this.form.addClass('gfm-form');
// remove notify commit author checkbox for non-commit notes
gl.utils.disableButtonIfEmptyField(this.form.find('.js-note-text'), this.form.find('.js-comment-button'));
gl.GfmAutoComplete.setup(this.form.find('.js-gfm-input'));
new DropzoneInput(this.form);
autosize(this.textarea);
// form and textarea event listeners
this.addEventListeners();
}
gl.text.init(this.form);
// hide discard button
this.form.find('.js-note-discard').hide();
this.form.show();
if (this.isAutosizeable) this.setupAutosize();
};
GLForm.prototype.setupAutosize = function () {
this.textarea.off('autosize:resized')
.on('autosize:resized', this.setHeightData.bind(this));
this.textarea.off('mouseup.autosize')
.on('mouseup.autosize', this.destroyAutosize.bind(this));
setTimeout(() => {
autosize(this.textarea);
this.textarea.css('resize', 'vertical');
}, 0);
};
GLForm.prototype.setHeightData = function () {
this.textarea.data('height', this.textarea.outerHeight());
};
GLForm.prototype.destroyAutosize = function () {
const outerHeight = this.textarea.outerHeight();
if (this.textarea.data('height') === outerHeight) return;
autosize.destroy(this.textarea);
this.textarea.data('height', outerHeight);
this.textarea.outerHeight(outerHeight);
this.textarea.css('max-height', window.outerHeight);
};
GLForm.prototype.clearEventListeners = function() {
this.textarea.off('focus');
this.textarea.off('blur');
return gl.text.removeListeners(this.form);
};
GLForm.prototype.addEventListeners = function() {
this.textarea.on('focus', function() {
return $(this).closest('.md-area').addClass('is-focused');
});
return this.textarea.on('blur', function() {
return $(this).closest('.md-area').removeClass('is-focused');
});
};
global.GLForm = GLForm;
})();
......@@ -59,11 +59,11 @@
} else {
avatar = gon.default_avatar_url;
}
return "<div class='group-result'> <div class='group-name'>" + group.name + "</div> <div class='group-path'>" + group.path + "</div> </div>";
return "<div class='group-result'> <div class='group-name'>" + group.full_name + "</div> <div class='group-path'>" + group.full_path + "</div> </div>";
};
GroupsSelect.prototype.formatSelection = function(group) {
return group.name;
return group.full_name;
};
return GroupsSelect;
......
......@@ -8,6 +8,7 @@
this.prioritizedLabels = prioritizedLabels || $('.js-prioritized-labels');
this.otherLabels = otherLabels || $('.js-other-labels');
this.errorMessage = 'Unable to update label prioritization at this time';
this.emptyState = document.querySelector('#js-priority-labels-empty-state');
this.prioritizedLabels.sortable({
items: 'li',
placeholder: 'list-placeholder',
......@@ -29,7 +30,12 @@
const action = $btn.parents('.js-prioritized-labels').length ? 'remove' : 'add';
const $tooltip = $(`#${$btn.find('.has-tooltip:visible').attr('aria-describedby')}`);
$tooltip.tooltip('destroy');
return _this.toggleLabelPriority($label, action);
_this.toggleLabelPriority($label, action);
_this.toggleEmptyState($label, $btn, action);
}
toggleEmptyState($label, $btn, action) {
this.emptyState.classList.toggle('hidden', !!this.prioritizedLabels[0].querySelector(':scope > li'));
}
toggleLabelPriority($label, action, persistState) {
......
/* eslint-disable no-restricted-properties, func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, no-use-before-define, camelcase, no-unused-expressions, quotes, max-len, one-var, one-var-declaration-per-line, default-case, prefer-template, consistent-return, no-alert, no-return-assign, no-param-reassign, prefer-arrow-callback, no-else-return, comma-dangle, no-new, brace-style, no-lonely-if, vars-on-top, no-unused-vars, no-sequences, no-shadow, newline-per-chained-call, no-useless-escape */
/* global Flash */
/* global GLForm */
/* global Autosave */
/* global ResolveService */
/* global mrRefreshWidgetUrl */
......@@ -421,7 +420,7 @@ require('vendor/task_list');
Notes.prototype.setupNoteForm = function(form) {
var textarea;
new GLForm(form);
new gl.GLForm(form);
textarea = form.find(".js-note-text");
return new Autosave(textarea, ["Note", form.find("#note_noteable_type").val(), form.find("#note_noteable_id").val(), form.find("#note_commit_id").val(), form.find("#note_type").val(), form.find("#note_line_code").val(), form.find("#note_position").val()]);
};
......@@ -885,7 +884,7 @@ require('vendor/task_list');
var targetId = $originalContentEl.data('target-id');
var targetType = $originalContentEl.data('target-type');
new GLForm($editForm.find('form'));
new gl.GLForm($editForm.find('form'));
$editForm.find('form')
.attr('action', postUrl)
......
......@@ -13,12 +13,12 @@
filterable: true,
fieldName: 'group_id',
search: {
fields: ['name']
fields: ['full_name']
},
data: function(term, callback) {
return Api.groups(term, {}, function(data) {
data.unshift({
name: 'Any'
full_name: 'Any'
});
data.splice(1, 0, 'divider');
return callback(data);
......@@ -28,10 +28,10 @@
return obj.id;
},
text: function(obj) {
return obj.name;
return obj.full_name;
},
toggleLabel: function(obj) {
return ($groupDropdown.data('default-label')) + " " + obj.name;
return ($groupDropdown.data('default-label')) + " " + obj.full_name;
},
clicked: (function(_this) {
return function() {
......
......@@ -85,7 +85,7 @@
},
success: (data) => {
$target.remove();
$('.prepend-top-default').html('<div class="nothing-here-block">You\'re all done!</div>');
$('.js-todos-all').html('<div class="nothing-here-block">You\'re all done!</div>');
return this.updateBadges(data);
}
});
......
......@@ -278,6 +278,10 @@
display: inline-block;
}
.btn {
margin: $btn-side-margin $btn-side-margin 0 0;
}
@media(max-width: $screen-xs-max) {
margin-top: 50px;
text-align: center;
......@@ -286,6 +290,12 @@
width: 100%;
}
}
@media(min-width: $screen-xs-max) {
&.labels .text-content {
margin-top: 70px;
}
}
}
.flex-container-block {
......
......@@ -162,6 +162,10 @@
}
}
}
&.panel-without-border {
border: 0;
}
}
.panel-succes .panel-heading,
......
......@@ -494,31 +494,27 @@
// Action Icons in big pipeline-graph nodes
> .ci-action-icon-container .ci-action-icon-wrapper {
i {
color: $border-color;
border-radius: 100%;
border: 1px solid $border-color;
padding: 5px 6px;
font-size: 13px;
background: $white-light;
height: 30px;
width: 30px;
&::before {
position: relative;