Commit 0fab7b11 authored by Kamil Trzcinski's avatar Kamil Trzcinski

Merge remote-tracking branch 'origin/master' into artifacts-when

parents bb3fc8c7 57ebd399
We’re closing our issue tracker on GitHub so we can focus on the project and respond to issues more quickly.
We encourage you to open an issue on the [ issue tracker]( You can log into using your GitHub account.
Thank you for taking the time to contribute back to GitLab!
Please open a merge request [on](, we look forward to reviewing your contribution! You can log into using your GitHub account.
......@@ -7,7 +7,8 @@ services:
key: "ruby21"
- vendor
- vendor/apt
- vendor/ruby
......@@ -61,6 +62,8 @@ update-knapsack:
- scripts/merge-reports knapsack/rspec_report.json knapsack/rspec_node_*.json
- scripts/merge-reports knapsack/spinach_report.json knapsack/spinach_node_*.json
- rm -f knapsack/*_node_*.json
- master
# Execute all testing suites
......@@ -13,7 +13,8 @@ AllCops:
# Exclude some GitLab files
- 'vendor/**/*'
- 'db/**/*'
- 'db/*'
- 'db/fixtures/**/*'
- 'tmp/**/*'
- 'bin/**/*'
- 'lib/backup/**/*'
......@@ -1088,6 +1089,9 @@ Rails/TimeZone:
Enabled: false
Enabled: false
##################### RSpec ##################################
# Check that instances are not being stubbed globally.
Please view this file on the master branch, on stable branches it's out of date.
v 8.9.0 (unreleased)
- Fix Error 500 when using closes_issues API with an external issue tracker
- Bulk assign/unassign labels to issues.
- Ability to prioritize labels !4009 / !3205 (Thijs Wouters)
- Fix endless redirections when accessing user OAuth applications when they are disabled
- Allow enabling wiki page events from Webhook management UI
- Bump rouge to 1.11.0
- Fix issue with arrow keys not working in search autocomplete dropdown
- Make EmailsOnPushWorker use Sidekiq mailers queue
- Fix wiki page events' webhook to point to the wiki repository
- Don't show tags for revert and cherry-pick operations
- Fix issue todo not remove when leave project !4150 (Long Nguyen)
- Allow customisable text on the 'nearly there' page after a user signs up
- Bump recaptcha gem to 3.0.0 to remove deprecated stoken support
- Fix SVG sanitizer to allow more elements
- Allow forking projects with restricted visibility level
- Added descriptions to notification settings dropdown
- Improve note validation to prevent errors when creating invalid note via API
- Reduce number of fog gem dependencies
- Remove project notification settings associated with deleted projects
......@@ -18,14 +24,18 @@ v 8.9.0 (unreleased)
- Redesign navigation for project pages
- Fix groups API to list only user's accessible projects
- Redesign account and email confirmation emails
- `git clone https://host/namespace/project` now works, in addition to using the `.git` suffix
- Bump nokogiri to 1.6.8
- Use gitlab-shell v3.0.0
- Upgrade to jQuery 2
- Use Knapsack to evenly distribute tests across multiple nodes
- Add `sha` parameter to MR merge API, to ensure only reviewed changes are merged
- Don't allow MRs to be merged when commits were added since the last review / page load
- Add DB index on users.state
- Add rake task 'gitlab:db:configure' for conditionally seeding or migrating the database
- Changed the Slack build message to use the singular duration if necessary (Aran Koning)
- Links from a wiki page to other wiki pages should be rewritten as expected
- Add option to project to only allow merge requests to be merged if the build succeeds (Rui Santos)
- Fix issues filter when ordering by milestone
- Added artifacts:when to .gitlab-ci.yml - this requires GitLab Runner 1.3
- Todos will display target state if issuable target is 'Closed' or 'Merged'
......@@ -37,31 +47,43 @@ v 8.9.0 (unreleased)
- Use downcased path to container repository as this is expected path by Docker
- Projects pending deletion will render a 404 page
- Measure queue duration between gitlab-workhorse and Rails
- Make Omniauth providers specs to not modify global configuration
- Make authentication service for Container Registry to be compatible with < Docker 1.11
- Add Application Setting to configure Container Registry token expire delay (default 5min)
- Cache assigned issue and merge request counts in sidebar nav
- Use Knapsack only in CI environment
- Cache project build count in sidebar nav
- Add milestone expire date to the right sidebar
- Fix markdown_spec to use before instead of before(:all) to properly cleanup database after testing
- Reduce number of queries needed to render issue labels in the sidebar
- Improve error handling importing projects
- Remove duplicated notification settings
- Put project Files and Commits tabs under Code tab
- Decouple global notification level from user model
- Replace Colorize with Rainbow for coloring console output in Rake tasks.
- Add workhorse controller and API helpers
- An indicator is now displayed at the top of the comment field for confidential issues.
- RepositoryCheck::SingleRepositoryWorker public and private methods are now instrumented
v 8.8.4 (unreleased)
- Improve issuables APIs performance when accessing notes !4471
- External links now open in a new tab
- Markdown editor now correctly resets the input value on edit cancellation !4175
- Toggling a task list item in a issue/mr description does not creates a Todo for mentions
- Improved UX of date pickers on issue & milestone forms
- Cache on the database if a project has an active external issue tracker.
- Put project Labels and Milestones pages links under Issues and Merge Requests tabs as subnav
- All classes in the Banzai::ReferenceParser namespace are now instrumented
v 8.8.5 (unreleased)
- Ensure branch cleanup regardless of whether the GitHub import process succeeds
- Fix issue with arrow keys not working in search autocomplete dropdown
- Fix todos page throwing errors when you have a project pending deletion
- Reduce number of SQL queries when rendering user references
- Upgrade to jQuery 2
- Remove prev/next buttons on issues and merge requests
- Import GitHub repositories respecting the API rate limit
- Fix importer for GitHub comments on diff
- Disable Webhooks before proceeding with the GitHub import
- Added descriptions to notification settings dropdown
- Fix incremental trace upload API when using multi-byte UTF-8 chars in trace
v 8.8.4
- Fix LDAP-based login for users with 2FA enabled. !4493
v 8.8.3
- Fix 404 page when viewing TODOs that contain milestones or labels in different projects. !4312
......@@ -173,6 +195,7 @@ v 8.8.0
- Fixed advice on invalid permissions on upload path !2948 (Ludovic Perrine)
- Allows MR authors to have the source branch removed when merging the MR. !2801 (Jeroen Jacobs)
- When creating a .gitignore file a dropdown with templates will be provided
- Shows the issue/MR list search/filter form and corrects the mobile styling for guest users. #17562
v 8.7.7
- Fix import by `Any Git URL` broken if the URL contains a space
class @Activities
constructor: ->
Pager.init 20, true
Pager.init 20, true, false, @updateTooltips
$(".event-filter-link").on "click", (event) =>
updateTooltips: ->
gl.utils.localTimeAgo($('.js-timeago', '#activity'))
reloadActivities: ->
$(".content_list").html ''
Pager.init 20, true
......@@ -35,7 +35,6 @@
#= require raphael
#= require g.raphael
#= require
#= require Chart
#= require branch-graph
#= require ace/ace
#= require ace/ext-searchbox
......@@ -163,19 +162,6 @@ $ ->
$'placement') || 'bottom'
$('.header-logo .home').tooltip(
placement: (_, el) ->
$el = $(el)
if $('.page-with-sidebar').hasClass('page-sidebar-collapsed') then 'right' else 'bottom'
container: 'body'
selector: '.sidebar-collapsed .nav-sidebar a, .sidebar-collapsed a.sidebar-user'
placement: 'right'
container: 'body'
# Form submitter
$('.trigger-submit').on 'change', ->
......@@ -208,6 +194,7 @@ $ ->
$('.navbar-toggle').on 'click', ->
$('.header-content .title').toggle()
$('.header-content .header-logo').toggle()
$('.header-content .navbar-collapse').toggle()
$('.navbar-toggle i').toggleClass("fa-angle-right fa-angle-left")
......@@ -226,6 +213,10 @@ $ ->
form = btn.closest("form")
new ConfirmDangerModal(form, text)
$(document).on 'click', 'button', ->
$('input[type="search"]').each ->
$this = $(this)
$this.attr 'value', $this.val()
......@@ -238,7 +229,6 @@ $ ->
$this.attr 'value', $this.val()
$sidebarGutterToggle = $('.js-sidebar-toggle')
$navIconToggle = $('.toggle-nav-collapse')
.off 'breakpoint:change'
......@@ -248,10 +238,6 @@ $ ->
if $gutterIcon.hasClass('fa-angle-double-right')
$navIcon = $navIconToggle.find('.fa')
if $navIcon.hasClass('fa-angle-left')
fitSidebarForSize = ->
oldBootstrapBreakpoint = bootstrapBreakpoint
bootstrapBreakpoint = bp.getBreakpointSize()
......@@ -264,9 +250,10 @@ $ ->
$(document).trigger('breakpoint:change', [bootstrapBreakpoint])
.off "resize"
.on "resize", (e) ->
.off ""
.on "", (e) ->
gl.awardsHandler = new AwardsHandler()
new Aside()
......@@ -65,7 +65,7 @@ class @AwardsHandler
$addBtn.removeClass 'is-loading'
$menu = $('.emoji-menu')
@positionMenu($menu, $addBtn)
@renderFrequentlyUsedBlock() unless @frequentEmojiBlockRendered
setTimeout =>
$menu.addClass 'is-visible'
......@@ -100,7 +100,7 @@ class @AwardsHandler
addAward: (votesBlock, awardUrl, emoji, checkMutuality = yes, callback) ->
addAward: (votesBlock, awardUrl, emoji, checkMutuality = true, callback) ->
emoji = @normilizeEmojiName emoji
......@@ -111,7 +111,7 @@ class @AwardsHandler
$('.emoji-menu').removeClass 'is-visible'
addAwardToEmojiBar: (votesBlock, emoji, checkForMutuality = yes) ->
addAwardToEmojiBar: (votesBlock, emoji, checkForMutuality = true) ->
@checkMutuality votesBlock, emoji if checkForMutuality
@addEmojiToFrequentlyUsedList emoji
......@@ -153,7 +153,7 @@ class @AwardsHandler
if isAlreadyVoted
@showEmojiLoader $emojiButton
@addAward votesBlock, awardUrl, mutualVote, no, ->
@addAward votesBlock, awardUrl, mutualVote, false, ->
$emojiButton.removeClass 'is-loading'
......@@ -282,7 +282,7 @@ class @AwardsHandler
@createEmojiMenu @getAwardMenuUrl(), => @createEmoji_ votesBlock, emoji
getAwardMenuUrl: -> return gl.awardMenuUrl
getAwardMenuUrl: -> return gon.award_menu_url
resolveNameToCssClass: (emoji) ->
......@@ -336,13 +336,15 @@ class @AwardsHandler
if $.cookie 'frequently_used_emojis'
frequentlyUsedEmojis = @getFrequentlyUsedEmojis()
ul = $("<ul class='clearfix emoji-menu-list'>")
ul = $("<ul class='clearfix emoji-menu-list frequent-emojis'>")
for emoji in frequentlyUsedEmojis
$(".emoji-menu-content [data-emoji='#{emoji}']").closest('li').clone().appendTo(ul)
$('input.emoji-search').after(ul).after($('<h5>').text('Frequently used'))
@frequentEmojiBlockRendered = true
setupSearch: ->
......@@ -365,4 +367,4 @@ class @AwardsHandler
searchEmojis: (term) ->
$(".emoji-menu-content [data-emoji*='#{term}']").closest('li').clone()
$(".emoji-menu-list:not(.frequent-emojis) [data-emoji*='#{term}']").closest('li').clone()
class CiBuild
class @CiBuild
@interval: null
@state: null
constructor: (build_url, build_status, build_state) ->
constructor: (@build_url, @build_status, @state) ->
@state = build_state
# Init breakpoint checker
@bp = Breakpoints.get()
.off 'click', '.js-sidebar-build-toggle'
.on 'click', '.js-sidebar-build-toggle', @toggleSidebar
.off ''
.on '', @hideSidebar
if build_status == "running" || build_status == "pending"
if $('#build-trace').length
if @build_status is "running" or @build_status is "pending"
# Bind autoscroll button to follow build output
$("#autoscroll-button").bind "click", ->
$('#autoscroll-button').on 'click', ->
state = $(this).data("state")
if "enabled" is state
$(this).data "state", "disabled"
......@@ -27,26 +39,37 @@ class CiBuild
# Only valid for runnig build when output changes during time
CiBuild.interval = setInterval =>
if window.location.href.split("#").first() is build_url
last_state = @state
url: build_url + "/trace.json?state=" + encodeURIComponent(@state)
dataType: "json"
success: (log) =>
return unless last_state is @state
if log.state and log.status is "running"
@state = log.state
if log.append
$('.fa-refresh').before log.html
$('#build-trace code').html log.html
$('#build-trace code').append '<i class="fa fa-refresh fa-spin"/>'
else if log.status isnt build_status
Turbolinks.visit build_url
if window.location.href.split("#").first() is @build_url
, 4000
getInitialBuildTrace: ->
url: @build_url
dataType: 'json'
success: (build_data) ->
$('.js-build-output').html build_data.trace_html
if build_data.status is 'success' or build_data.status is 'failed'
getBuildTrace: ->
url: "#{@build_url}/trace.json?state=#{encodeURIComponent(@state)}"
dataType: "json"
success: (log) =>
if log.state
@state = log.state
if log.status is "running"
if log.append
$('.js-build-output').append log.html
$('.js-build-output').html log.html
else if log.status isnt @build_status
Turbolinks.visit @build_url
checkAutoscroll: ->
$("html,body").scrollTop $("#build-trace").height() if "enabled" is $("#autoscroll-button").data("state")
......@@ -61,4 +84,22 @@ class CiBuild
$body.outerHeight() - ($buildTrace.outerHeight() + $buildTrace.offset().top)
@CiBuild = CiBuild
shouldHideSidebar: ->
bootstrapBreakpoint = @bp.getBreakpointSize()
bootstrapBreakpoint is 'xs' or bootstrapBreakpoint is 'sm'
toggleSidebar: =>
if @shouldHideSidebar()
.toggleClass 'right-sidebar-expanded right-sidebar-collapsed'
hideSidebar: =>
if @shouldHideSidebar()
.removeClass 'right-sidebar-expanded'
.addClass 'right-sidebar-collapsed'
.removeClass 'right-sidebar-collapsed'
.addClass 'right-sidebar-expanded'
......@@ -23,7 +23,6 @@ class Dispatcher
new Issue()
shortcut_handler = new ShortcutsIssuable()
new ZenMode()
gl.awardsHandler = new AwardsHandler()
when 'projects:milestones:show', 'groups:milestones:show', 'dashboard:milestones:show'
new Milestone()
when 'dashboard:todos:index'
......@@ -54,7 +53,6 @@ class Dispatcher
new Diff()
shortcut_handler = new ShortcutsIssuable(true)
new ZenMode()
gl.awardsHandler = new AwardsHandler()
when "projects:merge_requests:diffs"
new Diff()
new ZenMode()
......@@ -3,6 +3,7 @@
window.GitLab ?= {}
GitLab.GfmAutoComplete =
dataLoading: false
dataLoaded: false
dataSource: ''
......@@ -22,6 +23,24 @@ GitLab.GfmAutoComplete =
template: '<li>${title}</li>'
template: '<li><i class="fa fa-refresh fa-spin"></i> Loading...</li>'
sorter: (query, items, searchKey) ->
return items if items[0].name? and items[0].name is 'loading'
$.fn.atwho.default.callbacks.sorter(query, items, searchKey)
filter: (query, data, searchKey) ->
return data if data[0] is 'loading'
$.fn.atwho.default.callbacks.filter(query, data, searchKey)
beforeInsert: (value) ->
if not GitLab.GfmAutoComplete.dataLoaded
# Add GFM auto-completion to all input fields, that accept GFM input.
setup: (wrap) ->
@input = $('.js-gfm-input')
......@@ -53,18 +72,37 @@ GitLab.GfmAutoComplete =
# Emoji
at: ':'
displayTpl: @Emoji.template
displayTpl: (value) =>
if value.path?
insertTpl: ':${name}:'
data: ['loading']
sorter: @DefaultOptions.sorter
filter: @DefaultOptions.filter
beforeInsert: @DefaultOptions.beforeInsert
# Team Members
at: '@'
displayTpl: @Members.template
displayTpl: (value) =>
if value.username?
insertTpl: '${atwho-at}${username}'
searchKey: 'search'
data: ['loading']
sorter: @DefaultOptions.sorter
filter: @DefaultOptions.filter
beforeInsert: @DefaultOptions.beforeInsert
beforeSave: (members) ->
$.map members, (m) ->
return m if not m.username?
title =
title += " (#{m.count})" if m.count
......@@ -76,11 +114,21 @@ GitLab.GfmAutoComplete =
at: '#'
alias: 'issues'
searchKey: 'search'
displayTpl: @Issues.template
displayTpl: (value) =>
if value.title?
data: ['loading']
insertTpl: '${atwho-at}${id}'
sorter: @DefaultOptions.sorter
filter: @DefaultOptions.filter
beforeInsert: @DefaultOptions.beforeInsert
beforeSave: (issues) ->
$.map issues, (i) ->
return i if not i.title?
id: i.iid
title: sanitize(i.title)
search: "#{i.iid} #{i.title}"
......@@ -89,11 +137,18 @@ GitLab.GfmAutoComplete =
at: '%'
alias: 'milestones'
searchKey: 'search'
displayTpl: @Milestones.template
displayTpl: (value) =>
if value.title?
insertTpl: '${atwho-at}"${title}"'
data: ['loading']
beforeSave: (milestones) ->
$.map milestones, (m) ->
return m if not m.title?
id: m.iid
title: sanitize(m.title)
search: "#{m.title}"
......@@ -102,11 +157,21 @@ GitLab.GfmAutoComplete =
at: '!'
alias: 'mergerequests'
searchKey: 'search'
displayTpl: @Issues.template
displayTpl: (value) =>
if value.title?
data: ['loading']
insertTpl: '${atwho-at}${id}'
sorter: @DefaultOptions.sorter
filter: @DefaultOptions.filter
beforeInsert: @DefaultOptions.beforeInsert
beforeSave: (merges) ->
$.map merges, (m) ->
return m if not m.title?
id: m.iid
title: sanitize(m.title)
search: "#{m.iid} #{m.title}"
......@@ -118,6 +183,8 @@ GitLab.GfmAutoComplete =
loadData: (data) ->
@dataLoaded = true
# load members
@input.atwho 'load', '@', data.members
# load issues
......@@ -128,3 +195,7 @@ GitLab.GfmAutoComplete =
@input.atwho 'load', 'mergerequests', data.mergerequests
# load emojis
@input.atwho 'load', ':', data.emojis
# This trigger at.js again
# otherwise we would be stuck with loading until the user types