summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml57
-rw-r--r--.gitlab/issue_templates/Bug.md24
-rw-r--r--CONTRIBUTING.md2
-rw-r--r--LICENSE2
-rw-r--r--app/assets/javascripts/copy_as_gfm.js.es63
-rw-r--r--app/assets/javascripts/diff_notes/components/comment_resolve_btn.js.es611
-rw-r--r--app/assets/javascripts/diff_notes/components/jump_to_discussion.js.es611
-rw-r--r--app/assets/javascripts/diff_notes/components/resolve_btn.js.es619
-rw-r--r--app/assets/javascripts/diff_notes/components/resolve_count.js.es62
-rw-r--r--app/assets/javascripts/diff_notes/components/resolve_discussion_btn.js.es613
-rw-r--r--app/assets/javascripts/diff_notes/diff_notes_bundle.js.es64
-rw-r--r--app/assets/javascripts/diff_notes/services/resolve.js.es648
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es62
-rw-r--r--app/assets/javascripts/notes.js2
-rw-r--r--app/assets/stylesheets/pages/issuable.scss13
-rw-r--r--app/assets/stylesheets/pages/issues.scss2
-rw-r--r--app/assets/stylesheets/pages/merge_requests.scss9
-rw-r--r--app/models/project_services/jira_service.rb10
-rw-r--r--app/views/discussions/_resolve_all.html.haml3
-rw-r--r--app/views/projects/issues/_issue.html.haml107
-rw-r--r--app/views/projects/merge_requests/_merge_request.html.haml119
-rw-r--r--app/views/projects/merge_requests/_show.html.haml3
-rw-r--r--app/views/projects/notes/_note.html.haml3
-rw-r--r--changelogs/unreleased/27610-issue-number-alignment.yml4
-rw-r--r--changelogs/unreleased/fixes-namespace-api-documentation.yml4
-rw-r--r--changelogs/unreleased/issue_26701.yml4
-rw-r--r--changelogs/unreleased/upgrade-babel-v6.yml4
-rw-r--r--config/dependency_decisions.yml6
-rw-r--r--config/webpack.config.js6
-rw-r--r--doc/api/groups.md50
-rw-r--r--doc/api/oauth2.md6
-rw-r--r--doc/api/projects.md45
-rw-r--r--doc/gitlab-basics/img/profile_settings.pngbin3045 -> 5842 bytes
-rw-r--r--doc/gitlab-basics/img/profile_settings_ssh_keys_single_key.pngbin8133 -> 24639 bytes
-rw-r--r--features/snippets/user.feature34
-rw-r--r--features/steps/snippets/user.rb55
-rw-r--r--package.json7
-rw-r--r--spec/features/copy_as_gfm_spec.rb2
-rw-r--r--spec/features/snippets/user_snippets_spec.rb49
-rw-r--r--spec/javascripts/filtered_search/dropdown_user_spec.js.es64
-rw-r--r--spec/models/project_services/jira_service_spec.rb2
41 files changed, 304 insertions, 447 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 5ab3648d9f2..733710bb005 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -163,64 +163,7 @@ spinach 7 10: *spinach-knapsack
spinach 8 10: *spinach-knapsack
spinach 9 10: *spinach-knapsack
-# Execute all testing suites against Ruby 2.1
-.ruby-21: &ruby-21
- image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.1-git-2.7-phantomjs-2.1"
- <<: *use-db
- only:
- - master@gitlab-org/gitlab-ce
- - master@gitlab-org/gitlab-ee
- - master@gitlab/gitlabhq
- - master@gitlab/gitlab-ee
- cache:
- key: "ruby21"
- paths:
- - vendor/ruby
-
-.rspec-knapsack-ruby21: &rspec-knapsack-ruby21
- <<: *rspec-knapsack
- <<: *dedicated-runner
- <<: *ruby-21
-
-.spinach-knapsack-ruby21: &spinach-knapsack-ruby21
- <<: *spinach-knapsack
- <<: *dedicated-runner
- <<: *ruby-21
-
-rspec 0 20 ruby21: *rspec-knapsack-ruby21
-rspec 1 20 ruby21: *rspec-knapsack-ruby21
-rspec 2 20 ruby21: *rspec-knapsack-ruby21
-rspec 3 20 ruby21: *rspec-knapsack-ruby21
-rspec 4 20 ruby21: *rspec-knapsack-ruby21
-rspec 5 20 ruby21: *rspec-knapsack-ruby21
-rspec 6 20 ruby21: *rspec-knapsack-ruby21
-rspec 7 20 ruby21: *rspec-knapsack-ruby21
-rspec 8 20 ruby21: *rspec-knapsack-ruby21
-rspec 9 20 ruby21: *rspec-knapsack-ruby21
-rspec 10 20 ruby21: *rspec-knapsack-ruby21
-rspec 11 20 ruby21: *rspec-knapsack-ruby21
-rspec 12 20 ruby21: *rspec-knapsack-ruby21
-rspec 13 20 ruby21: *rspec-knapsack-ruby21
-rspec 14 20 ruby21: *rspec-knapsack-ruby21
-rspec 15 20 ruby21: *rspec-knapsack-ruby21
-rspec 16 20 ruby21: *rspec-knapsack-ruby21
-rspec 17 20 ruby21: *rspec-knapsack-ruby21
-rspec 18 20 ruby21: *rspec-knapsack-ruby21
-rspec 19 20 ruby21: *rspec-knapsack-ruby21
-
-spinach 0 10 ruby21: *spinach-knapsack-ruby21
-spinach 1 10 ruby21: *spinach-knapsack-ruby21
-spinach 2 10 ruby21: *spinach-knapsack-ruby21
-spinach 3 10 ruby21: *spinach-knapsack-ruby21
-spinach 4 10 ruby21: *spinach-knapsack-ruby21
-spinach 5 10 ruby21: *spinach-knapsack-ruby21
-spinach 6 10 ruby21: *spinach-knapsack-ruby21
-spinach 7 10 ruby21: *spinach-knapsack-ruby21
-spinach 8 10 ruby21: *spinach-knapsack-ruby21
-spinach 9 10 ruby21: *spinach-knapsack-ruby21
-
# Other generic tests
-
.ruby-static-analysis: &ruby-static-analysis
variables:
SIMPLECOV: "false"
diff --git a/.gitlab/issue_templates/Bug.md b/.gitlab/issue_templates/Bug.md
index 6d7d88c6791..34c2e097ba8 100644
--- a/.gitlab/issue_templates/Bug.md
+++ b/.gitlab/issue_templates/Bug.md
@@ -6,13 +6,13 @@
(How one can reproduce the issue - this is very important)
-### Expected behavior
+### What is the current *bug* behavior?
-(What you should see instead)
+(What actually happens)
-### Actual behavior
+### What is the expected *correct* behavior?
-(What actually happens)
+(What you should see instead)
### Relevant logs and/or screenshots
@@ -23,23 +23,23 @@ logs, and code as it's very hard to read otherwise.)
(If you are reporting a bug on GitLab.com, write: This bug happens on GitLab.com)
-#### Results of GitLab application Check
+#### Results of GitLab environment info
(For installations with omnibus-gitlab package run and paste the output of:
-`sudo gitlab-rake gitlab:check SANITIZE=true`)
+`sudo gitlab-rake gitlab:env:info`)
(For installations from source run and paste the output of:
-`sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production SANITIZE=true`)
-
-(we will only investigate if the tests are passing)
+`sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production`)
-#### Results of GitLab environment info
+#### Results of GitLab application Check
(For installations with omnibus-gitlab package run and paste the output of:
-`sudo gitlab-rake gitlab:env:info`)
+`sudo gitlab-rake gitlab:check SANITIZE=true`)
(For installations from source run and paste the output of:
-`sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production`)
+`sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production SANITIZE=true`)
+
+(we will only investigate if the tests are passing)
### Possible fixes
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 7c08c29d8a3..72cd57ad7ff 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -15,7 +15,7 @@
- [Issue weight](#issue-weight)
- [Regression issues](#regression-issues)
- [Technical debt](#technical-debt)
- - [Stewardship][#stewardship]
+ - [Stewardship](#stewardship)
- [Merge requests](#merge-requests)
- [Merge request guidelines](#merge-request-guidelines)
- [Contribution acceptance criteria](#contribution-acceptance-criteria)
diff --git a/LICENSE b/LICENSE
index 1dc1bdb7411..ad4f2872db5 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2011-2016 GitLab B.V.
+Copyright (c) 2011-2017 GitLab B.V.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/app/assets/javascripts/copy_as_gfm.js.es6 b/app/assets/javascripts/copy_as_gfm.js.es6
index 2bfe57b4100..4bd537a6f28 100644
--- a/app/assets/javascripts/copy_as_gfm.js.es6
+++ b/app/assets/javascripts/copy_as_gfm.js.es6
@@ -91,6 +91,9 @@ require('./lib/utils/common_utils');
},
},
SanitizationFilter: {
+ 'a[name]:not([href]):empty'(el, text) {
+ return el.outerHTML;
+ },
'dl'(el, text) {
let lines = text.trim().split('\n');
// Add two spaces to the front of subsequent list items lines,
diff --git a/app/assets/javascripts/diff_notes/components/comment_resolve_btn.js.es6 b/app/assets/javascripts/diff_notes/components/comment_resolve_btn.js.es6
index 2514459e65e..d948dff58ec 100644
--- a/app/assets/javascripts/diff_notes/components/comment_resolve_btn.js.es6
+++ b/app/assets/javascripts/diff_notes/components/comment_resolve_btn.js.es6
@@ -1,6 +1,6 @@
/* eslint-disable comma-dangle, object-shorthand, func-names, no-else-return, quotes, no-lonely-if, max-len */
-/* global Vue */
/* global CommentsStore */
+const Vue = require('vue');
(() => {
const CommentAndResolveBtn = Vue.extend({
@@ -9,13 +9,11 @@
},
data() {
return {
- textareaIsEmpty: true
+ textareaIsEmpty: true,
+ discussion: {},
};
},
computed: {
- discussion: function () {
- return CommentsStore.state[this.discussionId];
- },
showButton: function () {
if (this.discussion) {
return this.discussion.isResolvable();
@@ -42,6 +40,9 @@
}
}
},
+ created() {
+ this.discussion = CommentsStore.state[this.discussionId];
+ },
mounted: function () {
const $textarea = $(`#new-discussion-note-form-${this.discussionId} .note-textarea`);
this.textareaIsEmpty = $textarea.val() === '';
diff --git a/app/assets/javascripts/diff_notes/components/jump_to_discussion.js.es6 b/app/assets/javascripts/diff_notes/components/jump_to_discussion.js.es6
index c3898873eaa..57cb0d0ae6e 100644
--- a/app/assets/javascripts/diff_notes/components/jump_to_discussion.js.es6
+++ b/app/assets/javascripts/diff_notes/components/jump_to_discussion.js.es6
@@ -1,7 +1,7 @@
/* eslint-disable comma-dangle, object-shorthand, func-names, no-else-return, guard-for-in, no-restricted-syntax, one-var, space-before-function-paren, no-lonely-if, no-continue, brace-style, max-len, quotes */
-/* global Vue */
/* global DiscussionMixins */
/* global CommentsStore */
+const Vue = require('vue');
(() => {
const JumpToDiscussion = Vue.extend({
@@ -12,12 +12,10 @@
data: function () {
return {
discussions: CommentsStore.state,
+ discussion: {},
};
},
computed: {
- discussion: function () {
- return this.discussions[this.discussionId];
- },
allResolved: function () {
return this.unresolvedDiscussionCount === 0;
},
@@ -186,7 +184,10 @@
offset: -($('.navbar-gitlab').outerHeight() + $('.layout-nav').outerHeight())
});
}
- }
+ },
+ created() {
+ this.discussion = this.discussions[this.discussionId];
+ },
});
Vue.component('jump-to-discussion', JumpToDiscussion);
diff --git a/app/assets/javascripts/diff_notes/components/resolve_btn.js.es6 b/app/assets/javascripts/diff_notes/components/resolve_btn.js.es6
index 5852b8bbdb7..d1873d6c7a2 100644
--- a/app/assets/javascripts/diff_notes/components/resolve_btn.js.es6
+++ b/app/assets/javascripts/diff_notes/components/resolve_btn.js.es6
@@ -1,8 +1,8 @@
/* eslint-disable comma-dangle, object-shorthand, func-names, quote-props, no-else-return, camelcase, no-new, max-len */
-/* global Vue */
/* global CommentsStore */
/* global ResolveService */
/* global Flash */
+const Vue = require('vue');
(() => {
const ResolveBtn = Vue.extend({
@@ -10,14 +10,14 @@
noteId: Number,
discussionId: String,
resolved: Boolean,
- projectPath: String,
canResolve: Boolean,
resolvedBy: String
},
data: function () {
return {
discussions: CommentsStore.state,
- loading: false
+ loading: false,
+ note: {},
};
},
watch: {
@@ -30,13 +30,6 @@
discussion: function () {
return this.discussions[this.discussionId];
},
- note: function () {
- if (this.discussion) {
- return this.discussion.getNote(this.noteId);
- } else {
- return undefined;
- }
- },
buttonText: function () {
if (this.isResolved) {
return `Resolved by ${this.resolvedByName}`;
@@ -73,10 +66,10 @@
if (this.isResolved) {
promise = ResolveService
- .unresolve(this.projectPath, this.noteId);
+ .unresolve(this.noteId);
} else {
promise = ResolveService
- .resolve(this.projectPath, this.noteId);
+ .resolve(this.noteId);
}
promise.then((response) => {
@@ -106,6 +99,8 @@
},
created: function () {
CommentsStore.create(this.discussionId, this.noteId, this.canResolve, this.resolved, this.resolvedBy);
+
+ this.note = this.discussion.getNote(this.noteId);
}
});
diff --git a/app/assets/javascripts/diff_notes/components/resolve_count.js.es6 b/app/assets/javascripts/diff_notes/components/resolve_count.js.es6
index 72cdae812bc..de9367f2136 100644
--- a/app/assets/javascripts/diff_notes/components/resolve_count.js.es6
+++ b/app/assets/javascripts/diff_notes/components/resolve_count.js.es6
@@ -1,7 +1,7 @@
/* eslint-disable comma-dangle, object-shorthand, func-names, no-param-reassign */
-/* global Vue */
/* global DiscussionMixins */
/* global CommentsStore */
+const Vue = require('vue');
((w) => {
w.ResolveCount = Vue.extend({
diff --git a/app/assets/javascripts/diff_notes/components/resolve_discussion_btn.js.es6 b/app/assets/javascripts/diff_notes/components/resolve_discussion_btn.js.es6
index ee5f62b2d9e..7c5fcd04d2d 100644
--- a/app/assets/javascripts/diff_notes/components/resolve_discussion_btn.js.es6
+++ b/app/assets/javascripts/diff_notes/components/resolve_discussion_btn.js.es6
@@ -1,25 +1,22 @@
/* eslint-disable object-shorthand, func-names, space-before-function-paren, comma-dangle, no-else-return, quotes, max-len */
-/* global Vue */
/* global CommentsStore */
/* global ResolveService */
+const Vue = require('vue');
+
(() => {
const ResolveDiscussionBtn = Vue.extend({
props: {
discussionId: String,
mergeRequestId: Number,
- projectPath: String,
canResolve: Boolean,
},
data: function() {
return {
- discussions: CommentsStore.state
+ discussion: {},
};
},
computed: {
- discussion: function () {
- return this.discussions[this.discussionId];
- },
showButton: function () {
if (this.discussion) {
return this.discussion.isResolvable();
@@ -51,11 +48,13 @@
},
methods: {
resolve: function () {
- ResolveService.toggleResolveForDiscussion(this.projectPath, this.mergeRequestId, this.discussionId);
+ ResolveService.toggleResolveForDiscussion(this.mergeRequestId, this.discussionId);
}
},
created: function () {
CommentsStore.createDiscussion(this.discussionId, this.canResolve);
+
+ this.discussion = CommentsStore.state[this.discussionId];
}
});
diff --git a/app/assets/javascripts/diff_notes/diff_notes_bundle.js.es6 b/app/assets/javascripts/diff_notes/diff_notes_bundle.js.es6
index f0edfb8aaf1..190461451d5 100644
--- a/app/assets/javascripts/diff_notes/diff_notes_bundle.js.es6
+++ b/app/assets/javascripts/diff_notes/diff_notes_bundle.js.es6
@@ -3,6 +3,7 @@
/* global ResolveCount */
function requireAll(context) { return context.keys().map(context); }
+const Vue = require('vue');
requireAll(require.context('./models', false, /^\.\/.*\.(js|es6)$/));
requireAll(require.context('./stores', false, /^\.\/.*\.(js|es6)$/));
requireAll(require.context('./services', false, /^\.\/.*\.(js|es6)$/));
@@ -10,11 +11,14 @@ requireAll(require.context('./mixins', false, /^\.\/.*\.(js|es6)$/));
requireAll(require.context('./components', false, /^\.\/.*\.(js|es6)$/));
$(() => {
+ const projectPath = document.querySelector('.merge-request').dataset.projectPath;
const COMPONENT_SELECTOR = 'resolve-btn, resolve-discussion-btn, jump-to-discussion, comment-and-resolve-btn';
window.gl = window.gl || {};
window.gl.diffNoteApps = {};
+ window.ResolveService = new gl.DiffNotesResolveServiceClass(projectPath);
+
gl.diffNotesCompileComponents = () => {
const $components = $(COMPONENT_SELECTOR).filter(function () {
return $(this).closest('resolve-count').length !== 1;
diff --git a/app/assets/javascripts/diff_notes/services/resolve.js.es6 b/app/assets/javascripts/diff_notes/services/resolve.js.es6
index a52c476352d..090c454e9e4 100644
--- a/app/assets/javascripts/diff_notes/services/resolve.js.es6
+++ b/app/assets/javascripts/diff_notes/services/resolve.js.es6
@@ -1,45 +1,37 @@
/* eslint-disable class-methods-use-this, one-var, camelcase, no-new, comma-dangle, no-param-reassign, max-len */
-/* global Vue */
/* global Flash */
/* global CommentsStore */
-((w) => {
- class ResolveServiceClass {
- constructor() {
- this.noteResource = Vue.resource('notes{/noteId}/resolve');
- this.discussionResource = Vue.resource('merge_requests{/mergeRequestId}/discussions{/discussionId}/resolve');
- }
+const Vue = window.Vue = require('vue');
+window.Vue.use(require('vue-resource'));
+require('../../vue_shared/vue_resource_interceptor');
- setCSRF() {
- Vue.http.headers.common['X-CSRF-Token'] = $.rails.csrfToken();
- }
+(() => {
+ window.gl = window.gl || {};
- prepareRequest(root) {
- this.setCSRF();
- Vue.http.options.root = root;
+ class ResolveServiceClass {
+ constructor(root) {
+ this.noteResource = Vue.resource(`${root}/notes{/noteId}/resolve`);
+ this.discussionResource = Vue.resource(`${root}/merge_requests{/mergeRequestId}/discussions{/discussionId}/resolve`);
}
- resolve(projectPath, noteId) {
- this.prepareRequest(projectPath);
-
+ resolve(noteId) {
return this.noteResource.save({ noteId }, {});
}
- unresolve(projectPath, noteId) {
- this.prepareRequest(projectPath);
-
+ unresolve(noteId) {
return this.noteResource.delete({ noteId }, {});
}
- toggleResolveForDiscussion(projectPath, mergeRequestId, discussionId) {
+ toggleResolveForDiscussion(mergeRequestId, discussionId) {
const discussion = CommentsStore.state[discussionId];
const isResolved = discussion.isResolved();
let promise;
if (isResolved) {
- promise = this.unResolveAll(projectPath, mergeRequestId, discussionId);
+ promise = this.unResolveAll(mergeRequestId, discussionId);
} else {
- promise = this.resolveAll(projectPath, mergeRequestId, discussionId);
+ promise = this.resolveAll(mergeRequestId, discussionId);
}
promise.then((response) => {
@@ -62,11 +54,9 @@
});
}
- resolveAll(projectPath, mergeRequestId, discussionId) {
+ resolveAll(mergeRequestId, discussionId) {
const discussion = CommentsStore.state[discussionId];
- this.prepareRequest(projectPath);
-
discussion.loading = true;
return this.discussionResource.save({
@@ -75,11 +65,9 @@
}, {});
}
- unResolveAll(projectPath, mergeRequestId, discussionId) {
+ unResolveAll(mergeRequestId, discussionId) {
const discussion = CommentsStore.state[discussionId];
- this.prepareRequest(projectPath);
-
discussion.loading = true;
return this.discussionResource.delete({
@@ -89,5 +77,5 @@
}
}
- w.ResolveService = new ResolveServiceClass();
-})(window);
+ gl.DiffNotesResolveServiceClass = ResolveServiceClass;
+})();
diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6
index 859d6515531..e8c2df03a46 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6
+++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6
@@ -4,7 +4,7 @@
class FilteredSearchDropdown {
constructor(droplab, dropdown, input, filter) {
this.droplab = droplab;
- this.hookId = input.getAttribute('data-id');
+ this.hookId = input && input.getAttribute('data-id');
this.input = input;
this.filter = filter;
this.dropdown = dropdown;
diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js
index d108da29af7..3579843baed 100644
--- a/app/assets/javascripts/notes.js
+++ b/app/assets/javascripts/notes.js
@@ -455,7 +455,7 @@ require('vendor/task_list');
var mergeRequestId = $form.data('noteable-iid');
if (ResolveService != null) {
- ResolveService.toggleResolveForDiscussion(projectPath, mergeRequestId, discussionId);
+ ResolveService.toggleResolveForDiscussion(mergeRequestId, discussionId);
}
}
diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss
index 9174976c4c6..1a53730bed5 100644
--- a/app/assets/stylesheets/pages/issuable.scss
+++ b/app/assets/stylesheets/pages/issuable.scss
@@ -461,8 +461,19 @@
.issuable-list {
li {
+
+ .issue-box {
+ display: -webkit-flex;
+ display: flex;
+ }
+
+ .issue-info-container {
+ -webkit-flex: 1;
+ flex: 1;
+ padding-right: $gl-padding;
+ }
+
.issue-check {
- float: left;
padding-right: $gl-padding;
margin-bottom: 10px;
min-width: 15px;
diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss
index 1e605337f09..80b0c9493d8 100644
--- a/app/assets/stylesheets/pages/issues.scss
+++ b/app/assets/stylesheets/pages/issues.scss
@@ -1,6 +1,6 @@
.issues-list {
.issue {
- padding: 10px $gl-padding;
+ padding: 10px 0 10px $gl-padding;
position: relative;
.title {
diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss
index 8541fe75e8d..692142c5887 100644
--- a/app/assets/stylesheets/pages/merge_requests.scss
+++ b/app/assets/stylesheets/pages/merge_requests.scss
@@ -272,8 +272,15 @@
.mr-list {
.merge-request {
- padding: 10px 15px;
+ padding: 10px 0 10px 15px;
position: relative;
+ display: -webkit-flex;
+ display: flex;
+
+ .issue-info-container {
+ -webkit-flex: 1;
+ flex: 1;
+ }
.merge-request-title {
margin-bottom: 2px;
diff --git a/app/models/project_services/jira_service.rb b/app/models/project_services/jira_service.rb
index 80d002f9c32..eef403dba92 100644
--- a/app/models/project_services/jira_service.rb
+++ b/app/models/project_services/jira_service.rb
@@ -250,21 +250,11 @@ class JiraService < IssueTrackerService
end
end
- # Build remote link on JIRA properties
- # Icons here must be available on WEB so JIRA can read the URL
- # We are using a open word graphics icon which have LGPL license
def build_remote_link_props(url:, title:, resolved: false)
status = {
resolved: resolved
}
- if resolved
- status[:icon] = {
- title: 'Closed',
- url16x16: 'http://www.openwebgraphics.com/resources/data/1768/16x16_apply.png'
- }
- end
-
{
GlobalID: 'GitLab',
object: {
diff --git a/app/views/discussions/_resolve_all.html.haml b/app/views/discussions/_resolve_all.html.haml
index f0b61e0f7de..e30ee1b0e05 100644
--- a/app/views/discussions/_resolve_all.html.haml
+++ b/app/views/discussions/_resolve_all.html.haml
@@ -1,6 +1,5 @@
- if discussion.for_merge_request?
- %resolve-discussion-btn{ ":project-path" => "'#{project_path(discussion.project)}'",
- ":discussion-id" => "'#{discussion.id}'",
+ %resolve-discussion-btn{ ":discussion-id" => "'#{discussion.id}'",
":merge-request-id" => discussion.noteable.iid,
":can-resolve" => discussion.can_resolve?(current_user),
"inline-template" => true }
diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml
index 085b2fc2814..5c9839cb330 100644
--- a/app/views/projects/issues/_issue.html.haml
+++ b/app/views/projects/issues/_issue.html.haml
@@ -1,60 +1,61 @@
%li{ id: dom_id(issue), class: issue_css_classes(issue), url: issue_path(issue), data: { labels: issue.label_ids, id: issue.id } }
- - if @bulk_edit
- .issue-check
- = check_box_tag dom_id(issue, "selected"), nil, false, 'data-id' => issue.id, class: "selected_issue"
+ .issue-box
+ - if @bulk_edit
+ .issue-check
+ = check_box_tag dom_id(issue, "selected"), nil, false, 'data-id' => issue.id, class: "selected_issue"
+ .issue-info-container
+ .issue-title.title
+ %span.issue-title-text
+ = confidential_icon(issue)
+ = link_to issue.title, issue_path(issue)
+ %ul.controls
+ - if issue.closed?
+ %li
+ CLOSED
- .issue-title.title
- %span.issue-title-text
- = confidential_icon(issue)
- = link_to issue.title, issue_path(issue)
- %ul.controls
- - if issue.closed?
- %li
- CLOSED
+ - if issue.assignee
+ %li
+ = link_to_member(@project, issue.assignee, name: false, title: "Assigned to :name")
- - if issue.assignee
- %li
- = link_to_member(@project, issue.assignee, name: false, title: "Assigned to :name")
+ - upvotes, downvotes = issue.upvotes, issue.downvotes
+ - if upvotes > 0
+ %li
+ = icon('thumbs-up')
+ = upvotes
- - upvotes, downvotes = issue.upvotes, issue.downvotes
- - if upvotes > 0
- %li
- = icon('thumbs-up')
- = upvotes
+ - if downvotes > 0
+ %li
+ = icon('thumbs-down')
+ = downvotes
- - if downvotes > 0
- %li
- = icon('thumbs-down')
- = downvotes
+ - note_count = issue.notes.user.count
+ %li
+ = link_to issue_path(issue, anchor: 'notes'), class: ('no-comments' if note_count.zero?) do
+ = icon('comments')
+ = note_count
- - note_count = issue.notes.user.count
- %li
- = link_to issue_path(issue, anchor: 'notes'), class: ('no-comments' if note_count.zero?) do
- = icon('comments')
- = note_count
+ .issue-info
+ #{issuable_reference(issue)} &middot;
+ opened #{time_ago_with_tooltip(issue.created_at, placement: 'bottom')}
+ by #{link_to_member(@project, issue.author, avatar: false)}
+ - if issue.milestone
+ &nbsp;
+ = link_to namespace_project_issues_path(issue.project.namespace, issue.project, milestone_title: issue.milestone.title) do
+ = icon('clock-o')
+ = issue.milestone.title
+ - if issue.due_date
+ %span{ class: "#{'cred' if issue.overdue?}" }
+ &nbsp;
+ = icon('calendar')
+ = issue.due_date.to_s(:medium)
+ - if issue.labels.any?
+ &nbsp;
+ - issue.labels.each do |label|
+ = link_to_label(label, subject: issue.project, css_class: 'label-link')
+ - if issue.tasks?
+ &nbsp;
+ %span.task-status
+ = issue.task_status
- .issue-info
- #{issuable_reference(issue)} &middot;
- opened #{time_ago_with_tooltip(issue.created_at, placement: 'bottom')}
- by #{link_to_member(@project, issue.author, avatar: false)}
- - if issue.milestone
- &nbsp;
- = link_to namespace_project_issues_path(issue.project.namespace, issue.project, milestone_title: issue.milestone.title) do
- = icon('clock-o')
- = issue.milestone.title
- - if issue.due_date
- %span{ class: "#{'cred' if issue.overdue?}" }
- &nbsp;
- = icon('calendar')
- = issue.due_date.to_s(:medium)
- - if issue.labels.any?
- &nbsp;
- - issue.labels.each do |label|
- = link_to_label(label, subject: issue.project, css_class: 'label-link')
- - if issue.tasks?
- &nbsp;
- %span.task-status
- = issue.task_status
-
- .pull-right.issue-updated-at
- %span updated #{time_ago_with_tooltip(issue.updated_at, placement: 'bottom', html_class: 'issue_update_ago')}
+ .pull-right.issue-updated-at
+ %span updated #{time_ago_with_tooltip(issue.updated_at, placement: 'bottom', html_class: 'issue_update_ago')}
diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml
index 4dbb97b3228..a5fbe9d6128 100644
--- a/app/views/projects/merge_requests/_merge_request.html.haml
+++ b/app/views/projects/merge_requests/_merge_request.html.haml
@@ -3,73 +3,74 @@
.issue-check
= check_box_tag dom_id(merge_request, "selected"), nil, false, 'data-id' => merge_request.id, class: "selected_issue"
- .merge-request-title.title
- %span.merge-request-title-text
- = link_to merge_request.title, merge_request_path(merge_request)
- %ul.controls
- - if merge_request.merged?
- %li
- MERGED
- - elsif merge_request.closed?
- %li
- = icon('ban')
- CLOSED
+ .issue-info-container
+ .merge-request-title.title
+ %span.merge-request-title-text
+ = link_to merge_request.title, merge_request_path(merge_request)
+ %ul.controls
+ - if merge_request.merged?
+ %li
+ MERGED
+ - elsif merge_request.closed?
+ %li
+ = icon('ban')
+ CLOSED
- - if merge_request.head_pipeline
- %li
- = render_pipeline_status(merge_request.head_pipeline)
+ - if merge_request.head_pipeline
+ %li
+ = render_pipeline_status(merge_request.head_pipeline)
- - if merge_request.open? && merge_request.broken?
- %li
- = link_to merge_request_path(merge_request), class: "has-tooltip", title: "Cannot be merged automatically", data: { container: 'body' } do
- = icon('exclamation-triangle')
+ - if merge_request.open? && merge_request.broken?
+ %li
+ = link_to merge_request_path(merge_request), class: "has-tooltip", title: "Cannot be merged automatically", data: { container: 'body' } do
+ = icon('exclamation-triangle')
- - if merge_request.assignee
- %li
- = link_to_member(merge_request.source_project, merge_request.assignee, name: false, title: "Assigned to :name")
+ - if merge_request.assignee
+ %li
+ = link_to_member(merge_request.source_project, merge_request.assignee, name: false, title: "Assigned to :name")
- - upvotes, downvotes = merge_request.upvotes, merge_request.downvotes
- - if upvotes > 0
- %li
- = icon('thumbs-up')
- = upvotes
+ - upvotes, downvotes = merge_request.upvotes, merge_request.downvotes
+ - if upvotes > 0
+ %li
+ = icon('thumbs-up')
+ = upvotes
- - if downvotes > 0
- %li
- = icon('thumbs-down')
- = downvotes
+ - if downvotes > 0
+ %li
+ = icon('thumbs-down')
+ = downvotes
- - note_count = merge_request.related_notes.user.count
- %li
- = link_to merge_request_path(merge_request, anchor: 'notes'), class: ('no-comments' if note_count.zero?) do
- = icon('comments')
- = note_count
+ - note_count = merge_request.related_notes.user.count
+ %li
+ = link_to merge_request_path(merge_request, anchor: 'notes'), class: ('no-comments' if note_count.zero?) do
+ = icon('comments')
+ = note_count
- .merge-request-info
- #{issuable_reference(merge_request)} &middot;
- opened #{time_ago_with_tooltip(merge_request.created_at, placement: 'bottom')}
- by #{link_to_member(@project, merge_request.author, avatar: false)}
- - if merge_request.target_project.default_branch != merge_request.target_branch
- &nbsp;
- = link_to namespace_project_commits_path(merge_request.project.namespace, merge_request.project, merge_request.target_branch) do
- = icon('code-fork')
- = merge_request.target_branch
+ .merge-request-info
+ #{issuable_reference(merge_request)} &middot;
+ opened #{time_ago_with_tooltip(merge_request.created_at, placement: 'bottom')}
+ by #{link_to_member(@project, merge_request.author, avatar: false)}
+ - if merge_request.target_project.default_branch != merge_request.target_branch
+ &nbsp;
+ = link_to namespace_project_commits_path(merge_request.project.namespace, merge_request.project, merge_request.target_branch) do
+ = icon('code-fork')
+ = merge_request.target_branch
- - if merge_request.milestone
- &nbsp;
- = link_to namespace_project_merge_requests_path(merge_request.project.namespace, merge_request.project, milestone_title: merge_request.milestone.title) do
- = icon('clock-o')
- = merge_request.milestone.title
+ - if merge_request.milestone
+ &nbsp;
+ = link_to namespace_project_merge_requests_path(merge_request.project.namespace, merge_request.project, milestone_title: merge_request.milestone.title) do
+ = icon('clock-o')
+ = merge_request.milestone.title
- - if merge_request.labels.any?
- &nbsp;
- - merge_request.labels.each do |label|
- = link_to_label(label, subject: merge_request.project, type: :merge_request, css_class: 'label-link')
+ - if merge_request.labels.any?
+ &nbsp;
+ - merge_request.labels.each do |label|
+ = link_to_label(label, subject: merge_request.project, type: :merge_request, css_class: 'label-link')
- - if merge_request.tasks?
- &nbsp;
- %span.task-status
- = merge_request.task_status
+ - if merge_request.tasks?
+ &nbsp;
+ %span.task-status
+ = merge_request.task_status
- .pull-right.hidden-xs
- %span updated #{time_ago_with_tooltip(merge_request.updated_at, placement: 'bottom', html_class: 'merge_request_updated_ago')}
+ .pull-right.hidden-xs
+ %span updated #{time_ago_with_tooltip(merge_request.updated_at, placement: 'bottom', html_class: 'merge_request_updated_ago')}
diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml
index 83250443bea..dd615d3036c 100644
--- a/app/views/projects/merge_requests/_show.html.haml
+++ b/app/views/projects/merge_requests/_show.html.haml
@@ -3,10 +3,9 @@
- page_description @merge_request.description
- page_card_attributes @merge_request.card_attributes
- content_for :page_specific_javascripts do
- = page_specific_javascript_bundle_tag('lib_vue')
= page_specific_javascript_bundle_tag('diff_notes')
-.merge-request{ 'data-url' => merge_request_path(@merge_request) }
+.merge-request{ 'data-url' => merge_request_path(@merge_request), 'data-project-path' => project_path(@merge_request.project) }
= render "projects/merge_requests/show/mr_title"
.merge-request-details.issuable-details{ data: { id: @merge_request.project.id } }
diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml
index 4b1da9c73e5..e58de9f0e18 100644
--- a/app/views/projects/notes/_note.html.haml
+++ b/app/views/projects/notes/_note.html.haml
@@ -30,8 +30,7 @@
- if note.resolvable?
- can_resolve = can?(current_user, :resolve_note, note)
- %resolve-btn{ "project-path" => "#{project_path(note.project)}",
- "discussion-id" => "#{note.discussion_id}",
+ %resolve-btn{ "discussion-id" => "#{note.discussion_id}",
":note-id" => note.id,
":resolved" => note.resolved?,
":can-resolve" => can_resolve,
diff --git a/changelogs/unreleased/27610-issue-number-alignment.yml b/changelogs/unreleased/27610-issue-number-alignment.yml
new file mode 100644
index 00000000000..19ab8872c62
--- /dev/null
+++ b/changelogs/unreleased/27610-issue-number-alignment.yml
@@ -0,0 +1,4 @@
+---
+title: fixes issue number alignment problem in MR and issue list
+merge_request: 9020
+author:
diff --git a/changelogs/unreleased/fixes-namespace-api-documentation.yml b/changelogs/unreleased/fixes-namespace-api-documentation.yml
new file mode 100644
index 00000000000..6b578bb1602
--- /dev/null
+++ b/changelogs/unreleased/fixes-namespace-api-documentation.yml
@@ -0,0 +1,4 @@
+---
+title: Update API docs for new namespace format
+merge_request: 9073
+author: Markus Koller
diff --git a/changelogs/unreleased/issue_26701.yml b/changelogs/unreleased/issue_26701.yml
new file mode 100644
index 00000000000..6834351bf43
--- /dev/null
+++ b/changelogs/unreleased/issue_26701.yml
@@ -0,0 +1,4 @@
+---
+title: Remove JIRA closed status icon
+merge_request:
+author:
diff --git a/changelogs/unreleased/upgrade-babel-v6.yml b/changelogs/unreleased/upgrade-babel-v6.yml
new file mode 100644
index 00000000000..55f9b3e407c
--- /dev/null
+++ b/changelogs/unreleased/upgrade-babel-v6.yml
@@ -0,0 +1,4 @@
+---
+title: upgrade babel 5.8.x to babel 6.22.x
+merge_request: 9072
+author:
diff --git a/config/dependency_decisions.yml b/config/dependency_decisions.yml
index aabe859730a..54389eeb9ef 100644
--- a/config/dependency_decisions.yml
+++ b/config/dependency_decisions.yml
@@ -302,3 +302,9 @@
:why: https://github.com/dchest/tweetnacl-js/blob/master/LICENSE
:versions: []
:when: 2017-01-14 20:10:57.812077000 Z
+- - :approve
+ - wordwrap
+ - :who: Mike Greiling
+ :why: https://github.com/substack/node-wordwrap/blob/0.0.3/LICENSE
+ :versions: []
+ :when: 2017-02-08 20:17:13.084968000 Z
diff --git a/config/webpack.config.js b/config/webpack.config.js
index 968c0076eaf..2d1a16a18dd 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -54,14 +54,12 @@ var config = {
exclude: /(node_modules|vendor\/assets)/,
loader: 'babel-loader',
query: {
- // 'use strict' was broken in sprockets-es6 due to sprockets concatination method.
- // many es5 strict errors which were never caught ended up in our es6 assets as a result.
- // this hack is necessary until they can be fixed.
- blacklist: ['useStrict']
+ presets: ['es2015', 'stage-2']
}
},
{
test: /\.(js|es6)$/,
+ exclude: /node_modules/,
loader: 'imports-loader',
query: 'this=>window'
},
diff --git a/doc/api/groups.md b/doc/api/groups.md
index 84ab01c292b..a3a43ca7f1c 100644
--- a/doc/api/groups.md
+++ b/doc/api/groups.md
@@ -106,15 +106,7 @@ Example response:
"id": 5,
"name": "Experimental",
"path": "h5bp",
- "owner_id": null,
- "created_at": "2016-04-05T21:40:49.152Z",
- "updated_at": "2016-04-07T08:07:48.466Z",
- "description": "foo",
- "avatar": {
- "url": null
- },
- "share_with_group_lock": false,
- "visibility_level": 10
+ "kind": "group"
},
"avatar_url": null,
"star_count": 1,
@@ -190,15 +182,7 @@ Example response:
"id": 4,
"name": "Twitter",
"path": "twitter",
- "owner_id": null,
- "created_at": "2016-06-17T07:47:24.216Z",
- "updated_at": "2016-06-17T07:47:24.216Z",
- "description": "Aliquid qui quis dignissimos distinctio ut commodi voluptas est.",
- "avatar": {
- "url": null
- },
- "share_with_group_lock": false,
- "visibility_level": 20
+ "kind": "group"
},
"avatar_url": null,
"star_count": 0,
@@ -237,15 +221,7 @@ Example response:
"id": 4,
"name": "Twitter",
"path": "twitter",
- "owner_id": null,
- "created_at": "2016-06-17T07:47:24.216Z",
- "updated_at": "2016-06-17T07:47:24.216Z",
- "description": "Aliquid qui quis dignissimos distinctio ut commodi voluptas est.",
- "avatar": {
- "url": null
- },
- "share_with_group_lock": false,
- "visibility_level": 20
+ "kind": "group"
},
"avatar_url": null,
"star_count": 0,
@@ -286,15 +262,7 @@ Example response:
"id": 5,
"name": "H5bp",
"path": "h5bp",
- "owner_id": null,
- "created_at": "2016-06-17T07:47:26.621Z",
- "updated_at": "2016-06-17T07:47:26.621Z",
- "description": "Id consequatur rem vel qui doloremque saepe.",
- "avatar": {
- "url": null
- },
- "share_with_group_lock": false,
- "visibility_level": 20
+ "kind": "group"
},
"avatar_url": null,
"star_count": 0,
@@ -416,15 +384,7 @@ Example response:
"id": 5,
"name": "Experimental",
"path": "h5bp",
- "owner_id": null,
- "created_at": "2016-04-05T21:40:49.152Z",
- "updated_at": "2016-04-07T08:07:48.466Z",
- "description": "foo",
- "avatar": {
- "url": null
- },
- "share_with_group_lock": false,
- "visibility_level": 10
+ "kind": "group"
},
"avatar_url": null,
"star_count": 1,
diff --git a/doc/api/oauth2.md b/doc/api/oauth2.md
index 5ef5e3f5744..eab532af594 100644
--- a/doc/api/oauth2.md
+++ b/doc/api/oauth2.md
@@ -57,7 +57,7 @@ Once you have the authorization code you can request an `access_token` using the
```
parameters = 'client_id=APP_ID&client_secret=APP_SECRET&code=RETURNED_CODE&grant_type=authorization_code&redirect_uri=REDIRECT_URI'
-RestClient.post 'http://localhost:3000/oauth/token', parameters
+RestClient.post 'http://gitlab.example.com/oauth/token', parameters
# The response will be
{
@@ -77,13 +77,13 @@ You can now make requests to the API with the access token returned.
The access token allows you to make requests to the API on a behalf of a user.
```
-GET https://localhost:3000/api/v3/user?access_token=OAUTH-TOKEN
+GET https://gitlab.example.com/api/v3/user?access_token=OAUTH-TOKEN
```
Or you can put the token to the Authorization header:
```
-curl --header "Authorization: Bearer OAUTH-TOKEN" https://localhost:3000/api/v3/user
+curl --header "Authorization: Bearer OAUTH-TOKEN" https://gitlab.example.com/api/v3/user
```
## Resource Owner Password Credentials
diff --git a/doc/api/projects.md b/doc/api/projects.md
index 040153ac880..bad238f57d7 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -72,13 +72,10 @@ Parameters:
"last_activity_at": "2013-09-30T13:46:02Z",
"creator_id": 3,
"namespace": {
- "created_at": "2013-09-30T13:46:02Z",
- "description": "",
"id": 3,
"name": "Diaspora",
- "owner_id": 1,
"path": "diaspora",
- "updated_at": "2013-09-30T13:46:02Z"
+ "kind": "group"
},
"archived": false,
"avatar_url": "http://example.com/uploads/project/avatar/4/uploads/avatar.png",
@@ -125,13 +122,10 @@ Parameters:
"last_activity_at": "2013-09-30T13:46:02Z",
"creator_id": 3,
"namespace": {
- "created_at": "2013-09-30T13:46:02Z",
- "description": "",
"id": 4,
"name": "Brightbox",
- "owner_id": 1,
"path": "brightbox",
- "updated_at": "2013-09-30T13:46:02Z"
+ "kind": "group"
},
"permissions": {
"project_access": {
@@ -210,13 +204,10 @@ Parameters:
"last_activity_at": "2013-09-30T13:46:02Z",
"creator_id": 3,
"namespace": {
- "created_at": "2013-09-30T13:46:02Z",
- "description": "",
"id": 3,
"name": "Diaspora",
- "owner_id": 1,
"path": "diaspora",
- "updated_at": "2013-09-30T13:46:02Z"
+ "kind": "group"
},
"archived": false,
"avatar_url": "http://example.com/uploads/project/avatar/4/uploads/avatar.png",
@@ -260,13 +251,10 @@ Parameters:
"last_activity_at": "2013-09-30T13:46:02Z",
"creator_id": 3,
"namespace": {
- "created_at": "2013-09-30T13:46:02Z",
- "description": "",
"id": 4,
"name": "Brightbox",
- "owner_id": 1,
"path": "brightbox",
- "updated_at": "2013-09-30T13:46:02Z"
+ "kind": "group"
},
"permissions": {
"project_access": {
@@ -398,13 +386,10 @@ Parameters:
"last_activity_at": "2013-09-30T13:46:02Z",
"creator_id": 3,
"namespace": {
- "created_at": "2013-09-30T13:46:02Z",
- "description": "",
"id": 3,
"name": "Diaspora",
- "owner_id": 1,
"path": "diaspora",
- "updated_at": "2013-09-30T13:46:02Z"
+ "kind": "group"
},
"permissions": {
"project_access": {
@@ -779,13 +764,10 @@ Example response:
"last_activity_at": "2013-09-30T13:46:02Z",
"creator_id": 3,
"namespace": {
- "created_at": "2013-09-30T13:46:02Z",
- "description": "",
"id": 3,
"name": "Diaspora",
- "owner_id": 1,
"path": "diaspora",
- "updated_at": "2013-09-30T13:46:02Z"
+ "kind": "group"
},
"archived": true,
"avatar_url": "http://example.com/uploads/project/avatar/3/uploads/avatar.png",
@@ -847,13 +829,10 @@ Example response:
"last_activity_at": "2013-09-30T13:46:02Z",
"creator_id": 3,
"namespace": {
- "created_at": "2013-09-30T13:46:02Z",
- "description": "",
"id": 3,
"name": "Diaspora",
- "owner_id": 1,
"path": "diaspora",
- "updated_at": "2013-09-30T13:46:02Z"
+ "kind": "group"
},
"archived": true,
"avatar_url": "http://example.com/uploads/project/avatar/3/uploads/avatar.png",
@@ -921,13 +900,10 @@ Example response:
"last_activity_at": "2013-09-30T13:46:02Z",
"creator_id": 3,
"namespace": {
- "created_at": "2013-09-30T13:46:02Z",
- "description": "",
"id": 3,
"name": "Diaspora",
- "owner_id": 1,
"path": "diaspora",
- "updated_at": "2013-09-30T13:46:02Z"
+ "kind": "group"
},
"permissions": {
"project_access": {
@@ -1006,13 +982,10 @@ Example response:
"last_activity_at": "2013-09-30T13:46:02Z",
"creator_id": 3,
"namespace": {
- "created_at": "2013-09-30T13:46:02Z",
- "description": "",
"id": 3,
"name": "Diaspora",
- "owner_id": 1,
"path": "diaspora",
- "updated_at": "2013-09-30T13:46:02Z"
+ "kind": "group"
},
"permissions": {
"project_access": {
diff --git a/doc/gitlab-basics/img/profile_settings.png b/doc/gitlab-basics/img/profile_settings.png
index 26df4c0a734..aaa1a39313d 100644
--- a/doc/gitlab-basics/img/profile_settings.png
+++ b/doc/gitlab-basics/img/profile_settings.png
Binary files differ
diff --git a/doc/gitlab-basics/img/profile_settings_ssh_keys_single_key.png b/doc/gitlab-basics/img/profile_settings_ssh_keys_single_key.png
index 6a1430d9663..7ebb8973ef0 100644
--- a/doc/gitlab-basics/img/profile_settings_ssh_keys_single_key.png
+++ b/doc/gitlab-basics/img/profile_settings_ssh_keys_single_key.png
Binary files differ
diff --git a/features/snippets/user.feature b/features/snippets/user.feature
deleted file mode 100644
index 5b5dadb7b39..00000000000
--- a/features/snippets/user.feature
+++ /dev/null
@@ -1,34 +0,0 @@
-@snippets
-Feature: Snippets User
- Background:
- Given I sign in as a user
- And I have public "Personal snippet one" snippet
- And I have private "Personal snippet private" snippet
- And I have internal "Personal snippet internal" snippet
-
- Scenario: I should see all my snippets
- Given I visit my snippets page
- Then I should see "Personal snippet one" in snippets
- And I should see "Personal snippet private" in snippets
- And I should see "Personal snippet internal" in snippets
-
- Scenario: I can see only my private snippets
- Given I visit my snippets page
- And I click "Private" filter
- Then I should not see "Personal snippet one" in snippets
- And I should not see "Personal snippet internal" in snippets
- And I should see "Personal snippet private" in snippets
-
- Scenario: I can see only my public snippets
- Given I visit my snippets page
- And I click "Public" filter
- Then I should see "Personal snippet one" in snippets
- And I should not see "Personal snippet private" in snippets
- And I should not see "Personal snippet internal" in snippets
-
- Scenario: I can see only my internal snippets
- Given I visit my snippets page
- And I click "Internal" filter
- Then I should see "Personal snippet internal" in snippets
- And I should not see "Personal snippet private" in snippets
- And I should not see "Personal snippet one" in snippets
diff --git a/features/steps/snippets/user.rb b/features/steps/snippets/user.rb
deleted file mode 100644
index 997c605bce2..00000000000
--- a/features/steps/snippets/user.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-class Spinach::Features::SnippetsUser < Spinach::FeatureSteps
- include SharedAuthentication
- include SharedPaths
- include SharedSnippet
-
- step 'I visit my snippets page' do
- visit dashboard_snippets_path
- end
-
- step 'I should see "Personal snippet one" in snippets' do
- expect(page).to have_content "Personal snippet one"
- end
-
- step 'I should see "Personal snippet private" in snippets' do
- expect(page).to have_content "Personal snippet private"
- end
-
- step 'I should see "Personal snippet internal" in snippets' do
- expect(page).to have_content "Personal snippet internal"
- end
-
- step 'I should not see "Personal snippet one" in snippets' do
- expect(page).not_to have_content "Personal snippet one"
- end
-
- step 'I should not see "Personal snippet private" in snippets' do
- expect(page).not_to have_content "Personal snippet private"
- end
-
- step 'I should not see "Personal snippet internal" in snippets' do
- expect(page).not_to have_content "Personal snippet internal"
- end
-
- step 'I click "Internal" filter' do
- page.within('.snippet-scope-menu') do
- click_link "Internal"
- end
- end
-
- step 'I click "Private" filter' do
- page.within('.snippet-scope-menu') do
- click_link "Private"
- end
- end
-
- step 'I click "Public" filter' do
- page.within('.snippet-scope-menu') do
- click_link "Public"
- end
- end
-
- def snippet
- @snippet ||= PersonalSnippet.find_by!(title: "Personal snippet one")
- end
-end
diff --git a/package.json b/package.json
index a25e09e4cf2..7f1c8dd6fff 100644
--- a/package.json
+++ b/package.json
@@ -11,9 +11,10 @@
"webpack-prod": "NODE_ENV=production npm run webpack"
},
"dependencies": {
- "babel": "^5.8.38",
- "babel-core": "^5.8.38",
- "babel-loader": "^5.4.2",
+ "babel-core": "^6.22.1",
+ "babel-loader": "^6.2.10",
+ "babel-preset-es2015": "^6.22.0",
+ "babel-preset-stage-2": "^6.22.0",
"bootstrap-sass": "3.3.6",
"compression-webpack-plugin": "^0.3.2",
"d3": "3.5.11",
diff --git a/spec/features/copy_as_gfm_spec.rb b/spec/features/copy_as_gfm_spec.rb
index f3a5b565122..fec86128d03 100644
--- a/spec/features/copy_as_gfm_spec.rb
+++ b/spec/features/copy_as_gfm_spec.rb
@@ -251,6 +251,8 @@ describe 'Copy as GFM', feature: true, js: true do
'SanitizationFilter',
<<-GFM.strip_heredoc
+ <a name="named-anchor"></a>
+
<sub>sub</sub>
<dl>
diff --git a/spec/features/snippets/user_snippets_spec.rb b/spec/features/snippets/user_snippets_spec.rb
new file mode 100644
index 00000000000..191c2fb9a22
--- /dev/null
+++ b/spec/features/snippets/user_snippets_spec.rb
@@ -0,0 +1,49 @@
+require 'rails_helper'
+
+feature 'User Snippets', feature: true do
+ let(:author) { create(:user) }
+ let!(:public_snippet) { create(:personal_snippet, :public, author: author, title: "This is a public snippet") }
+ let!(:internal_snippet) { create(:personal_snippet, :internal, author: author, title: "This is an internal snippet") }
+ let!(:private_snippet) { create(:personal_snippet, :private, author: author, title: "This is a private snippet") }
+
+ background do
+ login_as author
+ visit dashboard_snippets_path
+ end
+
+ scenario 'View all of my snippets' do
+ expect(page).to have_content(public_snippet.title)
+ expect(page).to have_content(internal_snippet.title)
+ expect(page).to have_content(private_snippet.title)
+ end
+
+ scenario 'View my public snippets' do
+ page.within('.snippet-scope-menu') do
+ click_link "Public"
+ end
+
+ expect(page).to have_content(public_snippet.title)
+ expect(page).not_to have_content(internal_snippet.title)
+ expect(page).not_to have_content(private_snippet.title)
+ end
+
+ scenario 'View my internal snippets' do
+ page.within('.snippet-scope-menu') do
+ click_link "Internal"
+ end
+
+ expect(page).not_to have_content(public_snippet.title)
+ expect(page).to have_content(internal_snippet.title)
+ expect(page).not_to have_content(private_snippet.title)
+ end
+
+ scenario 'View my private snippets' do
+ page.within('.snippet-scope-menu') do
+ click_link "Private"
+ end
+
+ expect(page).not_to have_content(public_snippet.title)
+ expect(page).not_to have_content(internal_snippet.title)
+ expect(page).to have_content(private_snippet.title)
+ end
+end
diff --git a/spec/javascripts/filtered_search/dropdown_user_spec.js.es6 b/spec/javascripts/filtered_search/dropdown_user_spec.js.es6
index f4b0d60db34..fa9d03c8a9a 100644
--- a/spec/javascripts/filtered_search/dropdown_user_spec.js.es6
+++ b/spec/javascripts/filtered_search/dropdown_user_spec.js.es6
@@ -9,7 +9,7 @@ require('~/filtered_search/dropdown_user');
let dropdownUser;
beforeEach(() => {
- spyOn(gl.FilteredSearchDropdown.prototype, 'constructor').and.callFake(() => {});
+ spyOn(gl.DropdownUser.prototype, 'bindEvents').and.callFake(() => {});
spyOn(gl.DropdownUser.prototype, 'getProjectId').and.callFake(() => {});
spyOn(gl.DropdownUtils, 'getSearchInput').and.callFake(() => {});
@@ -39,7 +39,7 @@ require('~/filtered_search/dropdown_user');
describe('config droplabAjaxFilter\'s endpoint', () => {
beforeEach(() => {
- spyOn(gl.FilteredSearchDropdown.prototype, 'constructor').and.callFake(() => {});
+ spyOn(gl.DropdownUser.prototype, 'bindEvents').and.callFake(() => {});
spyOn(gl.DropdownUser.prototype, 'getProjectId').and.callFake(() => {});
});
diff --git a/spec/models/project_services/jira_service_spec.rb b/spec/models/project_services/jira_service_spec.rb
index 2f6b159d76e..4bca0229e7a 100644
--- a/spec/models/project_services/jira_service_spec.rb
+++ b/spec/models/project_services/jira_service_spec.rb
@@ -135,7 +135,7 @@ describe JiraService, models: true do
url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/commit/#{merge_request.diff_head_sha}",
title: "GitLab: Solved by commit #{merge_request.diff_head_sha}.",
icon: { title: "GitLab", url16x16: "https://gitlab.com/favicon.ico" },
- status: { resolved: true, icon: { url16x16: "http://www.openwebgraphics.com/resources/data/1768/16x16_apply.png", title: "Closed" } }
+ status: { resolved: true }
}
)
).once