Commit 9ba0f83d authored by Kamil Trzcinski's avatar Kamil Trzcinski

Merge remote-tracking branch 'origin/master' into rename-ci-commit-phase-4

parents c43279a8 cfc99bbd
We’re closing our issue tracker on GitHub so we can focus on the GitLab.com project and respond to issues more quickly.
We encourage you to open an issue on the [GitLab.com issue tracker](https://gitlab.com/gitlab-org/gitlab-ce/issues). You can log into GitLab.com using your GitHub account.
Thank you for taking the time to contribute back to GitLab!
Please open a merge request [on GitLab.com](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests), we look forward to reviewing your contribution! You can log into GitLab.com using your GitHub account.
......@@ -13,7 +13,8 @@ AllCops:
# Exclude some GitLab files
Exclude:
- 'vendor/**/*'
- 'db/**/*'
- 'db/*'
- 'db/fixtures/**/*'
- 'tmp/**/*'
- 'bin/**/*'
- 'lib/backup/**/*'
......
......@@ -12,6 +12,7 @@ v 8.9.0 (unreleased)
- 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
- 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
......@@ -22,6 +23,7 @@ v 8.9.0 (unreleased)
- `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
......@@ -45,6 +47,7 @@ v 8.9.0 (unreleased)
- 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
......@@ -55,19 +58,21 @@ v 8.9.0 (unreleased)
- RepositoryCheck::SingleRepositoryWorker public and private methods are now instrumented
- 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
v 8.8.4 (unreleased)
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
- Markdown editor now correctly resets the input value on edit cancellation !4175
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
......@@ -179,6 +184,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) =>
event.preventDefault()
@toggleFilter($(event.currentTarget))
@reloadActivities()
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 g.bar
#= require Chart
#= require branch-graph
#= require ace/ace
#= require ace/ext-searchbox
......@@ -226,6 +225,10 @@ $ ->
form = btn.closest("form")
new ConfirmDangerModal(form, text)
$(document).on 'click', 'button', ->
$(this).blur()
$('input[type="search"]').each ->
$this = $(this)
$this.attr 'value', $this.val()
......@@ -268,5 +271,6 @@ $ ->
.on "resize", (e) ->
fitSidebarForSize()
gl.awardsHandler = new AwardsHandler()
checkInitialSidebarSize()
new Aside()
......@@ -65,7 +65,7 @@ class @AwardsHandler
$addBtn.removeClass 'is-loading'
$menu = $('.emoji-menu')
@positionMenu($menu, $addBtn)
@renderFrequentlyUsedBlock()
@renderFrequentlyUsedBlock() unless @frequentEmojiBlockRendered
setTimeout =>
$menu.addClass 'is-visible'
......@@ -100,7 +100,7 @@ class @AwardsHandler
$menu.css(css)
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()
......@@ -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: ''
......@@ -35,7 +36,7 @@ GitLab.GfmAutoComplete =
$.fn.atwho.default.callbacks.filter(query, data, searchKey)
beforeInsert: (value) ->
if value.indexOf('undefined')
if not GitLab.GfmAutoComplete.dataLoaded
@at
else
value
......@@ -182,6 +183,8 @@ GitLab.GfmAutoComplete =
$.getJSON(dataSource)
loadData: (data) ->
@dataLoaded = true
# load members
@input.atwho 'load', '@', data.members
# load issues
......
......@@ -4,4 +4,5 @@
# It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
# the compiled file.
#
#= require Chart
#= require_tree .
((w) ->
jQuery.timefor = (time, suffix, expiredLabel) ->
return '' unless time
suffix or= 'remaining'
expiredLabel or= 'Past due'
jQuery.timeago.settings.allowFuture = yes
{ suffixFromNow } = jQuery.timeago.settings.strings
jQuery.timeago.settings.strings.suffixFromNow = suffix
timefor = $.timeago time
if timefor.indexOf('ago') > -1
timefor = expiredLabel
jQuery.timeago.settings.strings.suffixFromNow = suffixFromNow
return timefor
) window
......@@ -12,6 +12,13 @@
$el.attr('title', gl.utils.formatDate($el.attr('datetime')))
)
$timeagoEls.timeago() if setTimeago
if setTimeago
$timeagoEls.timeago()
$timeagoEls.tooltip('destroy')
# Recreate with custom template
$timeagoEls.tooltip(
template: '<div class="tooltip local-timeago" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
)
) window
......@@ -24,11 +24,21 @@ class @MilestoneSelect
if issueUpdateURL
milestoneLinkTemplate = _.template(
'<a href="/<%= namespace %>/<%= path %>/milestones/<%= iid %>"><%= _.escape(title) %></a>'
'<a href="/<%= namespace %>/<%= path %>/milestones/<%= iid %>">
<span class="has-tooltip" data-container="body" title="<%= remaining %>">
<%= _.escape(title) %>
</span>
</a>'
)
milestoneLinkNoneTemplate = '<div class="light">None</div>'
collapsedSidebarLabelTemplate = _.template(
'<span class="has-tooltip" data-container="body" title="<%= remaining %>" data-placement="left">
<%= _.escape(title) %>
</span>'
)
$dropdown.glDropdown(
data: (term, callback) ->
$.ajax(
......@@ -122,8 +132,9 @@ class @MilestoneSelect
if data.milestone?
data.milestone.namespace = _this.currentProject.namespace
data.milestone.path = _this.currentProject.path
data.milestone.remaining = $.timefor data.milestone.due_date
$value.html(milestoneLinkTemplate(data.milestone))
$sidebarCollapsedValue.find('span').text(data.milestone.title)
$sidebarCollapsedValue.find('span').html(collapsedSidebarLabelTemplate(data.milestone))
else
$value.html(milestoneLinkNoneTemplate)
$sidebarCollapsedValue.find('span').text('No')
......
@Pager =
init: (@limit = 0, preload, @disable = false) ->
init: (@limit = 0, preload, @disable = false, @callback = $.noop) ->
@loading = $('.loading').first()
if preload
......@@ -19,6 +19,7 @@
@loading.hide()
success: (data) ->
Pager.append(data.count, data.html)
Pager.callback()
dataType: "json"
append: (count, html) ->
......
......@@ -19,3 +19,8 @@ class @Subscription
action = if status == 'subscribed' then 'Unsubscribe' else 'Subscribe'
btn.find('span').text(action)
@subscription_status.find('>div').toggleClass('hidden')
if btn.attr('data-original-title')
btn.tooltip('hide')
.attr('data-original-title', action)
.tooltip('fixTitle')
......@@ -122,6 +122,9 @@ class @UserTabs
@parentEl.find(tabSelector).html(data.html)
@loaded[action] = true
# Fix tooltips
gl.utils.localTimeAgo($('.js-timeago', tabSelector))
loadActivities: (source) ->
return if @loaded['activity'] is true
......
......@@ -79,6 +79,23 @@
@include btn-color($white-light, $border-color, $white-normal, $border-white-normal, $white-dark, $border-white-dark, $btn-white-active);
}
@mixin btn-with-margin {
margin-left: $btn-side-margin;
float: left;
&.inline {
float: none;
}
&.btn-sm {
margin-left: $btn-sm-side-margin;
}
&.btn-xs {
margin-left: $btn-xs-side-margin;
}
}
.btn {
@include btn-default;
@include btn-white;
......@@ -142,24 +159,7 @@
}
&.btn-grouped {
margin-right: $btn-side-margin;
float: left;
&.inline {
float: none;
}
&:last-child {
margin-right: 0;
}
&.btn-sm {
margin-right: $btn-sm-side-margin;
}
&.btn-xs {
margin-right: $btn-xs-side-margin;
}
@include btn-with-margin;
}
&.disabled {
......@@ -203,11 +203,7 @@
.btn-group {
&.btn-grouped {
margin-right: 7px;
float: left;
&:last-child {
margin-right: 0;
}
@include btn-with-margin;
}
}
......
......@@ -76,6 +76,7 @@ label {
.form-control {
@include box-shadow(none);
border-radius: 3px;
padding: $gl-vert-padding $gl-input-padding;
}
.select-wrapper {
......
......@@ -2,6 +2,7 @@
font-family: $regular_font;
font-size: $font-size-base;
&.ui-datepicker,
&.ui-datepicker-inline {
border: 1px solid #ddd;
padding: 10px;
......@@ -10,6 +11,25 @@
.ui-datepicker-header {
background: #fff;
border-color: #ddd;
.ui-datepicker-prev,
.ui-datepicker-next {
top: 4px;
}
.ui-datepicker-prev {
left: 2px;
}
.ui-datepicker-next {
right: 2px;
}
.ui-state-hover {
background: transparent;
border: 0;
cursor: pointer;
}
}
.ui-datepicker-calendar td a {
......@@ -36,21 +56,18 @@
}
.ui-state-highlight {
border: 1px solid #eee;
background: #eee;
border: 0;
background: transparent;
}
.ui-state-active {
border: 1px solid $gl-primary;
background: $gl-primary;
color: #fff;
}
.ui-state-hover,
.ui-state-focus {
border: 1px solid $row-hover;
background: $row-hover;
color: #333;
.ui-datepicker-calendar {
.ui-state-active,
.ui-state-hover,
.ui-state-focus {
border: 1px solid $gl-primary;
background: $gl-primary;
color: #fff;
}
}
}
......
......@@ -137,8 +137,16 @@ ul.content-list {
padding-top: 1px;
float: right;
.btn {
padding: 10px 14px;
> .btn,
> .btn-group {
margin-right: $gl-padding-top;
display: inline-block;
margin-top: 4px;
margin-bottom: 4px;
&:last-child {
margin-right: 0;
}
}
}
......
......@@ -171,6 +171,7 @@
> form {
display: inline-block;
margin-top: -1px;
margin-bottom: 12px;
}
.icon-label {
......@@ -207,7 +208,7 @@
@media (max-width: $screen-xs-max) {
padding-bottom: 0;
width: 100%;
.btn, form, .dropdown, .dropdown-menu-toggle, .form-control {
margin: 0 0 10px;
display: block;
......@@ -238,16 +239,6 @@
margin: 0;
}
}
/* Small devices (tablets, 768px and lower) */
@media (max-width: $screen-sm-max) {
width: 100%;
text-align: left;
input {
width: 300px;
}
}
}
}
......
......@@ -8,7 +8,7 @@
background: #fff;
border-color: $input-border;
height: 35px;
padding: $gl-vert-padding $gl-btn-padding;
padding: $gl-vert-padding $gl-input-padding;
font-size: $gl-font-size;
line-height: 1.42857143;
border-radius: $border-radius-base;
......
......@@ -192,3 +192,8 @@
.text-info:hover {
color: $brand-info;
}
// Prevent datetimes on tooltips to break into two lines
.local-timeago {
white-space: nowrap;
}
......@@ -57,6 +57,7 @@ $code_line_height: 1.5;
*/
$gl-padding: 16px;
$gl-btn-padding: 10px;
$gl-input-padding: 10px;
$gl-vert-padding: 6px;
$gl-padding-top: 10px;
......@@ -79,8 +80,8 @@ $provider-btn-not-active-color: #4688f1;
$link-underline-blue: #4a8bee;
$layout-link-gray: #7e7c7c;
$todo-alert-blue: #428bca;
$btn-side-margin: 7px;
$btn-sm-side-margin: 5px;
$btn-side-margin: 10px;
$btn-sm-side-margin: 7px;
$btn-xs-side-margin: 5px;
/*
......
......@@ -50,11 +50,26 @@
.label-row {
.label-name {
display: inline-block;
width: 170px;
display: block;
margin-bottom: 10px;
@media (max-width: $screen-xs-min) {
display: block;
@media (min-width: $screen-sm-min) {
display: inline-block;
width: 200px;
margin-bottom: 0;
}
}
.label-description {
display: block;
margin-bottom: 10px;
@media (min-width: $screen-sm-min) {
display: inline-block;
width: 40%;
margin-left: 10px;
margin-bottom: 0;
vertical-align: middle;
}
}
......@@ -68,10 +83,6 @@
padding: 3px 4px;
}
.label-subscription {
display: inline-block;
}
.dropdown-labels-error {
padding: 5px 10px;
margin-bottom: 10px;
......@@ -79,62 +90,27 @@
color: $white-light;
}
@mixin labels-mobile {
@media (max-width: $screen-xs-min) {
display: block;
width: 100%;
margin-left: 0;
padding: 10px 0;
}
}
.manage-labels-list {
.btn-action {
color: $gl-dark-link-color;
.prepend-left-10, .prepend-description-left {
display: inline-block;
width: 40%;
vertical-align: middle;
@include labels-mobile;
}
.prepend-description-left {
width: 57%;
@include labels-mobile;
}
.pull-info-right {
float: right;
@media (max-width: $screen-xs-min) {
float: none;
.fa {
font-size: 18px;
vertical-align: middle;
}
.action-buttons {
border-color: transparent;
padding: 6px;
color: $gl-text-color;
&:hover {
color: $gl-link-color;
&.label-subscribe-button {
padding-left: 0;
&.remove-row {
color: $gl-danger;
}
}
}
i {
color: $gl-text-color;
}
.append-right-20 {
a {
color: $gl-text-color;
}
@media (max-width: $screen-xs-min) {
display: block;
margin-bottom: 10px;
}
.dropdown {
@media (min-width: $screen-sm-min) {
float: right;
}
}
}
......@@ -186,3 +162,23 @@
color: inherit;
}
}
.label-options-toggle {
width: 100%;
}
.label-subscribe-button {
.label-subscribe-button-loading {
display: none;
}
&.disabled {
.label-subscribe-button-icon {
display: none;
}
.label-subscribe-button-loading {
display: block;
}
}
}
......@@ -108,6 +108,11 @@
font-size: 17px;
margin: 5px 0;
color: $gl-gray-dark;
&.has-conflicts .fa-exclamation-triangle {
color: $gl-warning;
}
}
p:last-child {
......
......@@ -129,17 +129,8 @@
display: none;
font-size: 15px;
.form-actions {
padding-left: 20px;
.btn-save {
float: left;
}
.note-form-option {
float: left;
padding: 2px 0 0 25px;
}
.md-area {
background-color: #fff;
}
}
......
......@@ -32,7 +32,7 @@ module LabelsHelper
# link_to_label(label) { "My Custom Label Text" }
#
# Returns a String
def link_to_label(label, project: nil, type: :issue, tooltip: true, &block)
def link_to_label(label, project: nil, type: :issue, tooltip: true, css_class: nil, &block)
project ||= @project || label.project
link = send("namespace_project_#{type.to_s.pluralize}_path",
project.namespace,
......@@ -40,9 +40,9 @@ module LabelsHelper
label_name: [label.name])
if block_given?
link_to link, &block
link_to link, class: css_class, &block
else
link_to render_colored_label(label, tooltip: tooltip), link
link_to render_colored_label(label, tooltip: tooltip), link, class: css_class
end
end
......
......@@ -56,7 +56,7 @@ module MilestonesHelper
def milestone_remaining_days(milestone)
if milestone.expired?
content_tag(:strong, 'expired')
content_tag(:strong, 'Past due')
elsif milestone.due_date
days = milestone.remaining_days
content = content_tag(:strong, days)
......
......@@ -20,7 +20,7 @@ class TodoService
# * mark all pending todos related to the issue for the current user as done
#
def update_issue(issue, current_user)
create_mention_todos(issue.project, issue, current_user)
update_issuable(issue, current_user)
end
# When close an issue we should:
......@@ -53,7 +53,7 @@ class TodoService
# * create a todo for each mentioned user on merge request
#
def update_merge_request(merge_request, current_user)
create_mention_todos(merge_request.project, merge_request, current_user)
update_issuable(merge_request, current_user)
end
# When close a merge request we should:
......@@ -153,6 +153,13 @@ class TodoService
create_mention_todos(issuable.project, issuable, author)
end
def update_issuable(issuable, author)
# Skip toggling a task list item in a description
return if issuable.tasks? && issuable.updated_tasks.any?
create_mention_todos(issuable.project, issuable, author)
end
def handle_note(note, author)
# Skip system notes, and notes on project snippet
return if note.system? || note.for_snippet?
......
......@@ -7,9 +7,6 @@
= awards.count
- if current_user
:javascript
gl.awardMenuUrl = "#{emojis_path}"
.award-menu-holder.js-award-holder
%button.btn.award-control.js-add-award{ type: "button" }
= icon('smile-o', class: "award-control-icon award-control-icon-normal")
......
......@@ -6,7 +6,8 @@
- if @user.two_factor_otp_enabled?
%h5 Authenticate via Two-Factor App
= form_for(resource, as: resource_name, url: session_path(resource_name), method: :post) do |f|
= f.hidden_field :remember_me, value: params[resource_name][:remember_me]
- resource_params = params[resource_name].presence || params
= f.hidden_field :remember_me, value: resource_params.fetch(:remember_me, 0)
= f.text_field :otp_attempt, class: 'form-control', placeholder: 'Two-Factor Authentication code', required: true, autofocus: true, autocomplete: 'off'
%p.help-block.hint Enter the code from the two-factor app on your mobile device. If you've lost your device, you may enter one of your recovery codes.
.prepend-top-20
......
......@@ -34,7 +34,7 @@
%strong.member-access-level= member.human_access
- if show_controls
- if can?(current_user, :update_group_member, member)
= button_tag class: "btn-xs btn js-toggle-button",
= button_tag class: "btn-xs btn btn-grouped inline js-toggle-button",
title: 'Edit access level', type: 'button' do
= icon('pencil')
......
......@@ -39,9 +39,8 @@
.col-md-6
.form-group
= f.label :due_date, "Due Date", class: "control-label"
.col-sm-10= f.hidden_field :due_date
.col-sm-10
.datepicker
= f.text_field :due_date, class: "datepicker form-control", placeholder: "Select due date"
.form-actions
= f.submit 'Create Milestone', class: "btn-create btn"
......
......@@ -3,31 +3,30 @@
= render "projects/commits/head"
%div{ class: (container_class) }
.row-content-block.second-block.content-component-block
.pull-right
- if can? current_user, :push_code, @project
.top-area
.nav-text
Protected branches can be managed in project settings
- if can? current_user, :push_code, @project
.nav-controls
= link_to new_namespace_project_branch_path(@project.namespace, @project), class: 'btn btn-create' do
= icon('plus')
New branch
&nbsp;
.dropdown.inline
%button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'}
%span.light
- if @sort.present?
= @sort.humanize
- else
Name
%b.caret
%ul.dropdown-menu.dropdown-menu-align-right
%li
= link_to namespace_project_branches_path(sort: nil) do
.dropdown.inline
%button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'}
%span.light
- if @sort.present?
= @sort.humanize
- else
Name
= link_to namespace_project_branches_path(sort: 'recently_updated') do
= sort_title_recently_updated
= link_to namespace_project_branches_path(sort: 'last_updated') do
= sort_title_oldest_updated
.oneline
Protected branches can be managed in project settings
%b.caret
%ul.dropdown-menu.dropdown-menu-align-right
%li
= link_to namespace_project_branches_path(sort: nil) do
Name
= link_to namespace_project_branches_path(sort: 'recently_updated') do
= sort_title_recently_updated
= link_to namespace_project_branches_path(sort: 'last_updated') do
= sort_title_oldest_updated
- unless @branches.empty?
%ul.content-list.all-branches
- @branches.each do |branch|
......
......@@ -34,7 +34,6 @@
= link_to 'Get started with Builds', help_page_path('ci/quick_start', 'README'), class: 'btn btn-info'
= link_to ci_lint_path, class: 'btn btn-default' do
= icon('wrench')
%span CI Lint
%ul.content-list
......
......@@ -12,7 +12,7 @@
= icon('rss')
%span.icon-label
Subscribe
= render 'shared/issuable/search_form', path: namespace_project_issues_path(@project.namespace, @project)
= render 'shared/issuable/search_form', path: namespace_project_issues_path(@project.namespace, @project)
- if can? current_user, :create_issue, @project
= link_to new_namespace_project_issue_path(@project.namespace, @project, issue: { assignee_id: @issuable_finder.assignee.try(:id), milestone_id: @issuable_finder.milestones.try(:first).try(:id) }), class: "btn btn-new", title: "New Issue", id: "new_issue_link" do
New Issue
......
- label_css_id = dom_id(label)
%li{id: label_css_id, data: { id: label.id } }
= render "shared/label_row", label: label
.pull-info-right
%span.append-right-20
= link_to_label(label, type: :merge_request) do
= pluralize label.open_merge_requests_count, 'merge request'
%span.append-right-20
= link_to_label(label) do
= pluralize label.open_issues_count(current_user), 'open issue'
.visible-xs.visible-sm-inline-block.visible-md-inline-block.dropdown
%button.btn.btn-default.label-options-toggle{ data: { toggle: "dropdown" } }
Options
%span.caret
.dropdown-menu.dropdown-menu-align-right
%ul
%li
= link_to_label(label, type: :merge_request) do
= pluralize label.open_merge_requests_count, 'merge request'
%li
= link_to_label(label) do
= pluralize label.open_issues_count(current_user), 'open issue'
- if current_user
%li.label-subscription{ data: { url: toggle_subscription_namespace_project_label_path(@project.namespace, @project, label) } }
%a.js-subscribe-button.label-subscribe-button.subscription-status{ role: "button", href: "#", data: { toggle: "tooltip", status: label_subscription_status(label) } }
%span= label_subscription_toggle_button_text(label)
- if can? current_user, :admin_label, @project
%li
= link_to "Edit", edit_namespace_project_label_path(@project.namespace, @project, label)
%li
= link_to "Delete", namespace_project_label_path(@project.namespace, @project, label), title: "Delete", method: :delete, remote: true, data: {confirm: "Remove this label? Are you sure?"}
- if current_user
.label-subscription{ data: { url: toggle_subscription_namespace_project_label_path(@project.namespace, @project, label) } }
.subscription-status{ data: { status: label_subscription_status(label) } }
.pull-right.hidden-xs.hidden-sm.hidden-md
= link_to_label(label, type: :merge_request, css_class: 'btn btn-transparent btn-action') do
= pluralize label.open_merge_requests_count, 'merge request'
= link_to_label(label, css_class: 'btn btn-transparent btn-action') do
= pluralize label.open_issues_count(current_user), 'open issue'
%button.js-subscribe-button.label-subscribe-button.btn.action-buttons{ type: "button", data: { toggle: "tooltip" } }
%span= label_subscription_toggle_button_text(label)
- if current_user
.label-subscription.inline{ data: { url: toggle_subscription_namespace_project_label_path(@project.namespace, @project, label) } }
%button.js-subscribe-button.label-subscribe-button.btn.btn-transparent.btn-action.subscription-status{ type: "button", title: label_subscription_toggle_button_text(label), data: { toggle: "tooltip", status: label_subscription_status(label) } }
%span.sr-only= label_subscription_toggle_button_text(label)
= icon('eye', class: 'label-subscribe-button-icon')
= icon('spinner spin', class: 'label-subscribe-button-loading')
- if can?(current_user, :admin_label, @project)
= link_to edit_namespace_project_label_path(@project.namespace, @project, label), title: "Edit", class: 'btn action-buttons', data: { toggle: 'tooltip' } do
%i.fa.fa-pencil-square-o
= link_to namespace_project_label_path(@project.namespace, @project, label), title: "Delete", class: 'btn action-buttons remove-row', method: :delete, remote: true, data: { confirm: 'Remove this label? Are you sure?', toggle: 'tooltip' } do
%i.fa.fa-trash-o
- if can? current_user, :admin_label, @project
= link_to edit_namespace_project_label_path(@project.namespace, @project, label), title: "Edit", class: 'btn btn-transparent btn-action', data: {toggle: "tooltip"} do
%span.sr-only Edit
= icon('pencil-square-o')
= link_to namespace_project_label_path(@project.namespace, @project, label), title: "Delete", class: 'btn btn-transparent btn-action remove-row', method: :delete, remote: true, data: {confirm: "Remove this label? Are you sure?", toggle: "tooltip"} do
%span.sr-only Delete
= icon('trash-o')
- if current_user
:javascript
new Subscription('##{label_css_id} .label-subscription');
- if current_user
:javascript
new Subscription('##{dom_id(label)} .label-subscription');
%h4
%h4.has-conflicts
= icon("exclamation-triangle")
This merge request contains merge conflicts
%p
Please resolve these conflicts or
Please resolve these conflicts or
- if @merge_request.can_be_merged_by?(current_user)
#{link_to "merge this request manually", "#modal_merge_info", class: "how_to_merge_link vlink", "data-toggle" => "modal"}.
- else
......
......@@ -17,9 +17,8 @@
.col-md-6
.form-group
= f.label :due_date, "Due Date", class: "control-label"
.col-sm-10= f.hidden_field :due_date
.col-sm-10
.datepicker
= f.text_field :due_date, class: "datepicker form-control", placeholder: "Select due date"
.form-actions
- if @milestone.new_record?
......
......@@ -6,7 +6,6 @@
.nav-controls
- if can?(current_user, :admin_milestone, @project)
= link_to new_namespace_project_milestone_path(@project.namespace, @project), class: "btn btn-new", title: "New Milestone" do
= icon('plus')
New Milestone
.milestones
......
......@@ -6,7 +6,7 @@
- if @milestone.closed?
Closed
- elsif @milestone.expired?
Expired
Past due
- else
Open
%span.identifier
......@@ -23,11 +23,9 @@
= link_to 'Reopen Milestone', namespace_project_milestone_path(@project.namespace, @project, @milestone, milestone: {state_event: :activate }), method: :put, class: "btn btn-reopen btn-nr btn-grouped"
= link_to edit_namespace_project_milestone_path(@project.namespace, @project, @milestone), class: "btn btn-grouped btn-nr" do
= icon('pencil-square-o')
Edit
= link_to namespace_project_milestone_path(@project.namespace, @project, @milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-grouped btn-danger" do
= icon('trash-o')
Delete
.detail-page-description.milestone-detail
......
......@@ -28,14 +28,12 @@
.nav-controls
- if can? current_user, :create_pipeline, @project
= link_to new_namespace_project_pipeline_path(@project.namespace, @project), class: 'btn btn-create' do
= icon('plus')
New pipeline
- unless @repository.gitlab_ci_yml
= link_to 'Get started with Pipelines', help_page_path('ci/quick_start', 'README'), class: 'btn btn-info'
= link_to ci_lint_path, class: 'btn btn-default' do
= icon('wrench')
%span CI Lint
%ul.content-list.pipelines
......
......@@ -32,7 +32,7 @@
.pull-right
%strong= member.human_access
- if can?(current_user, :update_project_member, member)
= button_tag class: "btn-xs btn js-toggle-button",
= button_tag class: "btn-xs btn-grouped inline btn js-toggle-button",
title: 'Edit access level', type: 'button' do
= icon('pencil')
......
%span.btn-group.btn-grouped
%span.btn-group
= link_to archive_namespace_project_repository_path(project.namespace, project, ref: ref, format: 'zip'), class: 'btn btn-default', rel: 'nofollow' do
%i.fa.fa-download
%span source code
%span Source code
%a.btn.btn-default.dropdown-toggle{ 'data-toggle' => 'dropdown' }
%span.caret
%span.sr-only
......@@ -9,9 +8,7 @@
%ul.dropdown-menu.dropdown-menu-align-right{ role: 'menu' }
%li
= link_to archive_namespace_project_repository_path(project.namespace, project, ref: ref, format: 'zip'), rel: 'nofollow' do
%i.fa.fa-download
%span Download zip
%li
= link_to archive_namespace_project_repository_path(project.namespace, project, ref: ref, format: 'tar.gz'), rel: 'nofollow' do
%i.fa.fa-download
%span Download tar.gz
......@@ -15,11 +15,11 @@
= render 'projects/tags/download', ref: tag.name, project: @project
- if can?(current_user, :push_code, @project)
= link_to edit_namespace_project_tag_release_path(@project.namespace, @project, tag.name), class: 'btn-grouped btn has-tooltip', title: "Edit release notes" do
= link_to edit_namespace_project_tag_release_path(@project.namespace, @project, tag.name), class: 'btn has-tooltip', title: "Edit release notes" do
= icon("pencil")
- if can?(current_user, :admin_project, @project)
= link_to namespace_project_tag_path(@project.namespace, @project, tag.name), class: 'btn btn-grouped btn-xs btn-remove remove-row has-tooltip', title: "Delete tag", method: :delete, data: { confirm: "Deleting the '#{tag.name}' tag cannot be undone. Are you sure?", container: 'body' }, remote: true do
= link_to namespace_project_tag_path(@project.namespace, @project, tag.name), class: 'btn btn-remove remove-row has-tooltip', title: "Delete tag", method: :delete, data: { confirm: "Deleting the '#{tag.name}' tag cannot be undone. Are you sure?", container: 'body' }, remote: true do
= icon("trash-o")
- if commit
......
......@@ -3,14 +3,14 @@
= render "projects/commits/head"
%div{ class: (container_class) }
.row-content-block.second-block.content-component-block
.top-area
.nav-text
Tags give the ability to mark specific points in history as being important
- if can? current_user, :push_code, @project
.pull-right
.nav-controls
= link_to new_namespace_project_tag_path(@project.namespace, @project), class: 'btn btn-create new-tag-btn' do
= icon('plus')
New tag
.oneline
Tags give the ability to mark specific points in history as being important
.tags
- unless @tags.empty?
......
- if (@page && @page.persisted?)
= link_to namespace_project_wiki_history_path(@project.namespace, @project, @page), class: "btn btn-grouped" do
= link_to namespace_project_wiki_history_path(@project.namespace, @project, @page), class: "btn" do
Page History
- if can?(current_user, :create_wiki, @project)
= link_to namespace_project_wiki_edit_path(@project.namespace, @project, @page), class: "btn btn-grouped" do
%i.fa.fa-pencil-square-o
= link_to namespace_project_wiki_edit_path(@project.namespace, @project, @page), class: "btn" do
Edit
- if can?(current_user, :admin_wiki, @project)
= link_to namespace_project_wiki_path(@project.namespace, @project, @page), data: { confirm: "Are you sure you want to delete this page?"}, method: :delete, class: "btn btn-remove" do
= icon('trash')
Delete
......@@ -13,7 +13,6 @@
.nav-controls
- if can?(current_user, :create_wiki, @project)
= link_to '#modal-new-wiki', class: "add-new-wiki btn btn-new", "data-toggle" => "modal" do
= icon('plus')
New Page
= render 'projects/wikis/new'
......@@ -8,5 +8,6 @@
= icon('star')
%span.label-name
= link_to_label(label, tooltip: false)
%span.prepend-left-10
= markdown(label.description, pipeline: :single_line)
- if label.description
%span.label-description
= markdown(label.description, pipeline: :single_line)
......@@ -6,10 +6,10 @@
- if group_member
.controls.hidden-xs
- if can?(current_user, :admin_group, group)
= link_to edit_group_path(group), class: "btn-sm btn btn-grouped" do
%i.fa.fa-cogs
= link_to edit_group_path(group), class: "btn" do
= icon('cogs')
= link_to leave_group_group_members_path(group), data: { confirm: leave_group_message(group.name) }, method: :delete, class: "btn-sm btn btn-grouped", title: 'Leave this group' do
= link_to leave_group_group_members_path(group), data: { confirm: leave_group_message(group.name) }, method: :delete, class: "btn", title: 'Leave this group' do
= icon('sign-out')
.stats
......
......@@ -88,9 +88,9 @@
.col-lg-6
.form-group
= f.label :due_date, "Due date", class: "control-label"
= f.hidden_field :due_date, id: "issuable-due-date"
.col-sm-10
.datepicker
.issuable-form-select-holder
= f.text_field :due_date, id: "issuable-due-date", class: "datepicker form-control", placeholder: "Select due date"
- if issuable.can_move?(current_user)
%hr
......
......@@ -41,7 +41,8 @@
= icon('clock-o')
%span
- if issuable.milestone
= issuable.milestone.title
%span.has-tooltip{title: milestone_remaining_days(issuable.milestone), data: {container: 'body', html: 1, placement: 'left'}}
= issuable.milestone.title
- else
None
.title.hide-collapsed
......@@ -52,7 +53,8 @@
.value.bold.hide-collapsed
- if issuable.milestone
= link_to namespace_project_milestone_path(@project.namespace, @project, issuable.milestone) do
= issuable.milestone.title
%span.has-tooltip{title: milestone_remaining_days(issuable.milestone), data: {container: 'body', html: 1}}
= issuable.milestone.title
- else
.light None
......
......@@ -35,11 +35,9 @@
.col-sm-6= render('shared/milestone_expired', milestone: milestone)
.col-sm-6
- if can?(current_user, :admin_milestone, milestone.project) and milestone.active?
= link_to edit_namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), class: "btn btn-xs" do
= icon('pencil-square-o')
= link_to edit_namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), class: "btn btn-xs btn-grouped" do
Edit
\
= link_to 'Close Milestone', namespace_project_milestone_path(@project.namespace, @project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-xs btn-close"
= link_to namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-xs btn-remove" do
= icon('trash-o')
= link_to 'Close Milestone', namespace_project_milestone_path(@project.namespace, @project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-xs btn-close btn-grouped"
= link_to namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-xs btn-remove btn-grouped" do
Delete
......@@ -79,10 +79,10 @@
%li.js-contributed-tab
= link_to user_contributed_projects_path, data: {target: 'div#contributed', action: 'contributed', toggle: 'tab'} do
Contributed projects
%li.projects-tab
%li.js-projects-tab
= link_to user_projects_path, data: {target: 'div#projects', action: 'projects', toggle: 'tab'} do
Personal projects
%li.snippets-tab
%li.js-snippets-tab
= link_to user_snippets_path, data: {target: 'div#snippets', action: 'snippets', toggle: 'tab'} do
Snippets
......
......@@ -442,22 +442,6 @@ Rails.application.routes.draw do
resources(:projects, constraints: { id: /[a-zA-Z.0-9_\-]+(?<!\.atom)/ }, except:
[:new, :create, :index], path: "/") do
# Allow /info/refs, /info/refs?service=git-upload-pack, and
# /info/refs?service=git-receive-pack, but nothing else.
#
git_http_handshake = lambda do |request|
request.query_string.blank? ||
request.query_string.match(/\Aservice=git-(upload|receive)-pack\z/)
end
ref_redirect = redirect do |params, request|
path = "#{params[:namespace_id]}/#{params[:project_id]}.git/info/refs"
path << "?#{request.query_string}" unless request.query_string.blank?
path
end
get '/info/refs', constraints: git_http_handshake, to: ref_redirect
member do
put :transfer
delete :remove_fork
......@@ -472,12 +456,28 @@ Rails.application.routes.draw do
scope module: :projects do
# Git HTTP clients ('git clone' etc.)
scope constraints: { format: /(git|wiki\.git)/ } do
scope constraints: { id: /.+\.git/, format: nil } do
get '/info/refs', to: 'git_http#info_refs'
post '/git-upload-pack', to: 'git_http#git_upload_pack'
post '/git-receive-pack', to: 'git_http#git_receive_pack'
end
# Allow /info/refs, /info/refs?service=git-upload-pack, and
# /info/refs?service=git-receive-pack, but nothing else.
#
git_http_handshake = lambda do |request|
request.query_string.blank? ||
request.query_string.match(/\Aservice=git-(upload|receive)-pack\z/)
end
ref_redirect = redirect do |params, request|
path = "#{params[:namespace_id]}/#{params[:project_id]}.git/info/refs"
path << "?#{request.query_string}" unless request.query_string.blank?
path
end
get '/info/refs', constraints: git_http_handshake, to: ref_redirect
# Blob routes:
get '/new/*id', to: 'blob#new', constraints: { id: /.+/ }, as: 'new_blob'
post '/create/*id', to: 'blob#create', constraints: { id: /.+/ }, as: 'create_blob'
......
# rubocop:disable all
class InitSchema < ActiveRecord::Migration
def up
......
# rubocop:disable all
class RenameOwnerToCreatorForProject < ActiveRecord::Migration
def change
rename_column :projects, :owner_id, :creator_id
......
# rubocop:disable all
class AddPublicToProject < ActiveRecord::Migration
def change
add_column :projects, :public, :boolean, default: false, null: false
......
# rubocop:disable all
class AddIssuesTrackerToProject < ActiveRecord::Migration
def change
add_column :projects, :issues_tracker, :string, default: :gitlab, null: false
......
# rubocop:disable all
class AddUserPermissions < ActiveRecord::Migration
def up
add_column :users, :can_create_group, :boolean, default: true, null: false
......
# rubocop:disable all
class RemovePrivateFlagFromProject < ActiveRecord::Migration
def up
remove_column :projects, :private_flag
......
# rubocop:disable all
class AddDescriptionToNamsespace < ActiveRecord::Migration
def change
add_column :namespaces, :description, :string, default: '', null: false
......
# rubocop:disable all
class AddDescriptionToTeams < ActiveRecord::Migration
def change
add_column :user_teams, :description, :string, default: '', null: false
......
# rubocop:disable all
class AddIssuesTrackerIdToProject < ActiveRecord::Migration
def change
add_column :projects, :issues_tracker_id, :string
......
# rubocop:disable all
class RenameStateToMergeStatusInMilestone < ActiveRecord::Migration
def change
rename_column :merge_requests, :state, :merge_status
......
# rubocop:disable all
class AddStateToIssue < ActiveRecord::Migration
def change
add_column :issues, :state, :string
......
# rubocop:disable all
class AddStateToMergeRequest < ActiveRecord::Migration
def change
add_column :merge_requests, :state, :string
......
# rubocop:disable all
class AddStateToMilestone < ActiveRecord::Migration
def change
add_column :milestones, :state, :string
......
# rubocop:disable all
class ConvertClosedToStateInIssue < ActiveRecord::Migration
include Gitlab::Database
......
# rubocop:disable all
class ConvertClosedToStateInMergeRequest < ActiveRecord::Migration
include Gitlab::Database
......
# rubocop:disable all
class ConvertClosedToStateInMilestone < ActiveRecord::Migration
include Gitlab::Database
......
# rubocop:disable all
class RemoveMergedFromMergeRequest < ActiveRecord::Migration
def up
remove_column :merge_requests, :merged
......
# rubocop:disable all
class RemoveClosedFromIssue < ActiveRecord::Migration
def up
remove_column :issues, :closed
......
# rubocop:disable all
class RemoveClosedFromMergeRequest < ActiveRecord::Migration
def up
remove_column :merge_requests, :closed
......
# rubocop:disable all
class RemoveClosedFromMilestone < ActiveRecord::Migration
def up
remove_column :milestones, :closed
......
# rubocop:disable all
class AddNewMergeStatusToMergeRequest < ActiveRecord::Migration
def change
add_column :merge_requests, :new_merge_status, :string
......
# rubocop:disable all
class ConvertMergeStatusInMergeRequest < ActiveRecord::Migration
def up
execute "UPDATE #{table_name} SET new_merge_status = 'unchecked' WHERE merge_status = 1"
......
# rubocop:disable all
class RemoveMergeStatusFromMergeRequest < ActiveRecord::Migration
def up
remove_column :merge_requests, :merge_status
......
# rubocop:disable all
class RenameNewMergeStatusToMergeStatusInMilestone < ActiveRecord::Migration
def change
rename_column :merge_requests, :new_merge_status, :merge_status
......
# rubocop:disable all
class AddStateToUser < ActiveRecord::Migration
def change
add_column :users, :state, :string
......
# rubocop:disable all
class ConvertBlockedToState < ActiveRecord::Migration
def up
User.transaction do
......
# rubocop:disable all
class RemoveBlockedFromUser < ActiveRecord::Migration
def up
remove_column :users, :blocked
......
# rubocop:disable all
class UserColorScheme < ActiveRecord::Migration
include Gitlab::Database
......
# rubocop:disable all
class AddSnippetsToFeatures < ActiveRecord::Migration
def change
add_column :projects, :snippets_enabled, :boolean, null: false, default: true
......
# rubocop:disable all
class CreateForkedProjectLinks < ActiveRecord::Migration
def change
create_table :forked_project_links do |t|
......
# rubocop:disable all
class AddPrivateToSnippets < ActiveRecord::Migration
def change
add_column :snippets, :private, :boolean, null: false, default: true
......
# rubocop:disable all
class AddTypeToSnippets < ActiveRecord::Migration
def change
add_column :snippets, :type, :string
......
# rubocop:disable all
class ChangeProjectIdToNullInSnipepts < ActiveRecord::Migration
def up
change_column :snippets, :project_id, :integer, :null => true
......
# rubocop:disable all
class AddTypeValueForSnippets < ActiveRecord::Migration
def up
Snippet.where("project_id IS NOT NULL").update_all(type: 'ProjectSnippet')
......
# rubocop:disable all
class AddNotificationLevelToUser < ActiveRecord::Migration
def change
add_column :users, :notification_level, :integer, null: false, default: 1
......
# rubocop:disable all
class AddIndexToUsersAuthenticationToken < ActiveRecord::Migration
def change
add_index :users, :authentication_token, unique: true
......
# rubocop:disable all
class AddLastActivityColumnIntoProject < ActiveRecord::Migration
def up
add_column :projects, :last_activity_at, :datetime
......
# rubocop:disable all
class AddNotificationLevelToUserProject < ActiveRecord::Migration
def change
add_column :users_projects, :notification_level, :integer, null: false, default: 3
......
# rubocop:disable all
class RemoveWikiTable < ActiveRecord::Migration
def up
drop_table :wikis
......
# rubocop:disable all
class AllowMergesForForks < ActiveRecord::Migration
def self.up
add_column :merge_requests, :target_project_id, :integer, :null => true
......
# rubocop:disable all
class AddTypeToKey < ActiveRecord::Migration
def change
add_column :keys, :type, :string
......
# rubocop:disable all
class CreateDeployKeysProjects < ActiveRecord::Migration
def change
create_table :deploy_keys_projects do |t|
......
# rubocop:disable all
class RemoveProjectIdFromKey < ActiveRecord::Migration
def up
puts 'Migrate deploy keys: '
......
# rubocop:disable all
class AddMoreFieldsToService < ActiveRecord::Migration
def change
add_column :services, :subdomain, :string
......
# rubocop:disable all
class AddSystemToNotes < ActiveRecord::Migration
class Note < ActiveRecord::Base
end
......
# rubocop:disable all
class IncreaseSnippetTextColumnSize < ActiveRecord::Migration
def up
# MYSQL LARGETEXT for snippet
......
# rubocop:disable all
class AddPasswordExpiresAtToUsers < ActiveRecord::Migration
def change
add_column :users, :password_expires_at, :datetime
......
# rubocop:disable all
class AddCreatedByIdToUser < ActiveRecord::Migration
def change
add_column :users, :created_by_id, :integer
......
# rubocop:disable all
class AddImprotedToProject < ActiveRecord::Migration
def change
add_column :projects, :imported, :boolean, default: false, null: false
......
# rubocop:disable all
class CreateUsersGroups < ActiveRecord::Migration
def change
create_table :users_groups do |t|
......
# rubocop:disable all
class AddNotificationLevelToUserGroup < ActiveRecord::Migration
def change
add_column :users_groups, :notification_level, :integer, null: false, default: 3
......
# rubocop:disable all
class AddMoreDbIndex < ActiveRecord::Migration
def change
add_index :deploy_keys_projects, :project_id
......
# rubocop:disable all
class AddFingerprintToKey < ActiveRecord::Migration
def change
add_column :keys, :fingerprint, :string
......
# rubocop:disable all
class CreateProjectGroupLinks < ActiveRecord::Migration
def change
create_table :project_group_links do |t|
......
# rubocop:disable all
class AddStDiffToNote < ActiveRecord::Migration
def change
add_column :notes, :st_diff, :text, :null => true
......
# rubocop:disable all
class AddPermissionCheckToUser < ActiveRecord::Migration
def change
add_column :users, :last_credential_check_at, :datetime
......
# rubocop:disable all
class AddImportUrlToProject < ActiveRecord::Migration
def change
add_column :projects, :import_url, :string
......
# rubocop:disable all
class AddInternalIdsToIssuesAndMr < ActiveRecord::Migration
def change
add_column :issues, :iid, :integer
......
# rubocop:disable all
class AddAccessToProjectGroupLink < ActiveRecord::Migration
def change
add_column :project_group_links, :group_access, :integer, null: false, default: ProjectGroupLink.default_access
......
# rubocop:disable all
class RemoveDeprecatedTables < ActiveRecord::Migration
def up
drop_table :user_teams
......
# rubocop:disable all
class AddInternalIdsToMilestones < ActiveRecord::Migration
def change
add_column :milestones, :iid, :integer
......
# rubocop:disable all
class AddDescriptionToMergeRequest < ActiveRecord::Migration
def change
add_column :merge_requests, :description, :text, null: true
......
# rubocop:disable all
class ChangeOwnerIdForGroup < ActiveRecord::Migration
def up
change_column :namespaces, :owner_id, :integer, null: true
......
# rubocop:disable all
class AddAvatarToUsers < ActiveRecord::Migration
def change
add_column :users, :avatar, :string
......
# rubocop:disable all
class AddConfirmableToUsers < ActiveRecord::Migration
def self.up
add_column :users, :confirmation_token, :string
......
# rubocop:disable all
class RemoveDefaultBranch < ActiveRecord::Migration
def up
remove_column :projects, :default_branch
......
# rubocop:disable all
class CreateBroadcastMessages < ActiveRecord::Migration
def change
create_table :broadcast_messages do |t|
......
# rubocop:disable all
class AddVisibilityLevelToProjects < ActiveRecord::Migration
include Gitlab::Database
......
# rubocop:disable all
class AddArchivedToProjects < ActiveRecord::Migration
def change
add_column :projects, :archived, :boolean, default: false, null: false
......
# rubocop:disable all
class AddColorAndFontToBroadcastMessages < ActiveRecord::Migration
def change
add_column :broadcast_messages, :color, :string
......
# rubocop:disable all
class AddEventFieldsForWebHook < ActiveRecord::Migration
def change
add_column :web_hooks, :push_events, :boolean, default: true, null: false
......
# rubocop:disable all
class AddHideNoSshKeyToUsers < ActiveRecord::Migration
def change
add_column :users, :hide_no_ssh_key, :boolean, :default => false
......
# rubocop:disable all
class AddRecipientsToService < ActiveRecord::Migration
def change
add_column :services, :recipients, :text
......
# rubocop:disable all
class AddWebsiteUrlToUsers < ActiveRecord::Migration
def change
add_column :users, :website_url, :string, {:null => false, :default => ''}
......
# rubocop:disable all
class CreateMergeRequestDiffs < ActiveRecord::Migration
def up
create_table :merge_request_diffs do |t|
......
# rubocop:disable all
class MigrateMrDiffs < ActiveRecord::Migration
def self.up
execute "INSERT INTO merge_request_diffs ( merge_request_id, st_commits, st_diffs ) SELECT id, st_commits, st_diffs FROM merge_requests"
......
# rubocop:disable all
class RemoveMRdiffFields < ActiveRecord::Migration
def up
remove_column :merge_requests, :st_commits
......
# rubocop:disable all
class AddAvatarToProjects < ActiveRecord::Migration
def change
add_column :projects, :avatar, :string
......
# rubocop:disable all
class AddGroupAvatars < ActiveRecord::Migration
def change
add_column :namespaces, :avatar, :string
......
# rubocop:disable all
class CreateEmails < ActiveRecord::Migration
def change
create_table :emails do |t|
......
# rubocop:disable all
class AddApiKeyToServices < ActiveRecord::Migration
def change
add_column :services, :api_key, :string
......
# rubocop:disable all
class AddIndexMergeRequestDiffsOnMergeRequestId < ActiveRecord::Migration
def change
add_index :merge_request_diffs, :merge_request_id, unique: true
......
# rubocop:disable all
class AddTagPushHooksToProjectHook < ActiveRecord::Migration
def change
add_column :web_hooks, :tag_push_events, :boolean, default: false
......
# rubocop:disable all
class AddImportStatusToProject < ActiveRecord::Migration
def change
add_column :projects, :import_status, :string
......
# rubocop:disable all
class MigrateAlreadyImportedProjects < ActiveRecord::Migration
include Gitlab::Database
......
# rubocop:disable all
class FixNamespaces < ActiveRecord::Migration
def up
Namespace.where('name <> path and type is null').each do |namespace|
......
# rubocop:disable all
class ChangeStateToAllowEmptyMergeRequestDiffs < ActiveRecord::Migration
def up
change_column :merge_request_diffs, :state, :string, null: true,
......
# rubocop:disable all
require_relative 'limits_to_mysql'
# rubocop:disable all
class AddIndexOnIid < ActiveRecord::Migration
def change
RemoveDuplicateIid.clean(Issue)
......
# rubocop:disable all
class IndexOnCurrentSignInAt < ActiveRecord::Migration
def change
add_index :users, :current_sign_in_at
......
# rubocop:disable all
class AddNotesIndexUpdatedAt < ActiveRecord::Migration
def change
add_index :notes, :updated_at
......
# rubocop:disable all
class AddRepoSizeToDb < ActiveRecord::Migration
def change
add_column :projects, :repository_size, :float, default: 0
......
# rubocop:disable all
class MigrateRepoSize < ActiveRecord::Migration
def up
project_data = execute('SELECT projects.id, namespaces.path AS namespace_path, projects.path AS project_path FROM projects LEFT JOIN namespaces ON projects.namespace_id = namespaces.id')
......
# rubocop:disable all
class AddPositionToMergeRequest < ActiveRecord::Migration
def change
add_column :merge_requests, :position, :integer, default: 0
......
# rubocop:disable all
class CreateUsersStarProjects < ActiveRecord::Migration
def change
create_table :users_star_projects do |t|
......
# rubocop:disable all
class CreateLabels < ActiveRecord::Migration
def change
create_table :labels do |t|
......
# rubocop:disable all
class CreateLabelLinks < ActiveRecord::Migration
def change
create_table :label_links do |t|
......
# rubocop:disable all
class MigrateProjectTags < ActiveRecord::Migration
def up
ActsAsTaggableOn::Tagging.where(taggable_type: 'Project', context: 'labels').update_all(context: 'tags')
......
# rubocop:disable all
class MigrateTaggableLabels < ActiveRecord::Migration
def up
taggings = ActsAsTaggableOn::Tagging.where(taggable_type: ['Issue', 'MergeRequest'], context: 'labels')
......
# rubocop:disable all
class AddIndexToLabels < ActiveRecord::Migration
def change
add_index "labels", :project_id
......
# rubocop:disable all
class MigrateToNewShell < ActiveRecord::Migration
def change
return if Rails.env.test?
......
# rubocop:disable all
class SerializeServiceProperties < ActiveRecord::Migration
def change
unless column_exists?(:services, :properties)
......
# rubocop:disable all
class AddMembersTable < ActiveRecord::Migration
def change
create_table :members do |t|
......
# rubocop:disable all
class MigrateToNewMembersModel < ActiveRecord::Migration
def up
execute "INSERT INTO members ( user_id, source_id, source_type, access_level, notification_level, type ) SELECT user_id, group_id, 'Namespace', group_access, notification_level, 'GroupMember' FROM users_groups"
......
# rubocop:disable all
class RemoveOldMemberTables < ActiveRecord::Migration
def up
drop_table :users_groups
......
# rubocop:disable all
class MoveSlackServiceToWebhook < ActiveRecord::Migration
def change
SlackService.all.each do |slack_service|
......
# rubocop:disable all
class AddVisibilityLevelToSnippet < ActiveRecord::Migration
include Gitlab::Database
......
# rubocop:disable all
class AddAuditEvent < ActiveRecord::Migration
def change
create_table :audit_events do |t|
......
# rubocop:disable all
# In 20140914145549_migrate_to_new_members_model.rb we forgot to set the
# created_at and updated_at times for new records in the 'members' table. This
# became a problem after commit c8e78d972a5a628870eefca0f2ccea0199c55bda which
......
# rubocop:disable all
class AddIdentityTable < ActiveRecord::Migration
def up
create_table :identities do |t|
......
# rubocop:disable all
class AddLockedAtToMergeRequest < ActiveRecord::Migration
def change
add_column :merge_requests, :locked_at, :datetime
......
# rubocop:disable all
class CreateDoorkeeperTables < ActiveRecord::Migration
def change
create_table :oauth_applications do |t|
......
# rubocop:disable all
class AddOwnerToApplication < ActiveRecord::Migration
def change
add_column :oauth_applications, :owner_id, :integer, null: true
......
# rubocop:disable all
class AddImportDataToProjectTable < ActiveRecord::Migration
def change
add_column :projects, :import_type, :string
......
# rubocop:disable all
class AddDevelopersCanPushToProtectedBranches < ActiveRecord::Migration
def change
add_column :protected_branches, :developers_can_push, :boolean, default: false, null: false
......
# rubocop:disable all
class CreateApplicationSettings < ActiveRecord::Migration
def change
create_table :application_settings do |t|
......
# rubocop:disable all
class AddHomePageUrlForApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :home_page_url, :string
......
# rubocop:disable all
class AddGitlabAccessTokenToUser < ActiveRecord::Migration
def change
add_column :users, :gitlab_access_token, :string
......
# rubocop:disable all
class AddDefaultBranchProtectionSetting < ActiveRecord::Migration
def change
add_column :application_settings, :default_branch_protection, :integer, :default => 2
......
# rubocop:disable all
class AddTimestampsToIdentities < ActiveRecord::Migration
def change
add_timestamps(:identities)
......
# rubocop:disable all
class AddIndexToCreatedAt < ActiveRecord::Migration
def change
add_index "users", [:created_at, :id]
......
# rubocop:disable all
class AddNotificationEmailToUser < ActiveRecord::Migration
def up
add_column :users, :notification_email, :string
......
# rubocop:disable all
class AddMissingIndex < ActiveRecord::Migration
def change
add_index "services", [:created_at, :id]
......
# rubocop:disable all
class AddTemplateToService < ActiveRecord::Migration
def change
add_column :services, :template, :boolean, default: false
......
# rubocop:disable all
class AllowNullInServicesProjectId < ActiveRecord::Migration
def change
change_column :services, :project_id, :integer, null: true
......
# rubocop:disable all
class AddTwitterSharingEnabledToApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :twitter_sharing_enabled, :boolean, default: true
......
# rubocop:disable all
class AddHideNoPasswordToUser < ActiveRecord::Migration
def change
add_column :users, :hide_no_password, :boolean, default: false
......
# rubocop:disable all
class AddPasswordAutomaticallySetToUser < ActiveRecord::Migration
def change
add_column :users, :password_automatically_set, :boolean, default: false
......
# rubocop:disable all
class AddBitbucketAccessTokenAndSecretToUser < ActiveRecord::Migration
def change
add_column :users, :bitbucket_access_token, :string
......
# rubocop:disable all
class AddEventsToServices < ActiveRecord::Migration
def change
add_column :services, :push_events, :boolean, :default => true
......
# rubocop:disable all
class SetMissingLastActivityAt < ActiveRecord::Migration
def up
execute "UPDATE projects SET last_activity_at = updated_at WHERE last_activity_at IS NULL"
......
# rubocop:disable all
class AddNoteEventsToServices < ActiveRecord::Migration
def change
add_column :services, :note_events, :boolean, default: true, null: false
......
# rubocop:disable all
class AddRestrictedVisibilityLevelsToApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :restricted_visibility_levels, :text
......
# rubocop:disable all
class FixNamespaceDuplication < ActiveRecord::Migration
def up
#fixes path duplication
......
# rubocop:disable all
class AddUniqueIndexToNamespace < ActiveRecord::Migration
def change
remove_index :namespaces, column: :name if index_exists?(:namespaces, :name)
......
# rubocop:disable all
class AddVersionCheckToApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :version_check_enabled, :boolean, default: true
......
# rubocop:disable all
class CreateSubscriptionsTable < ActiveRecord::Migration
def change
create_table :subscriptions do |t|
......
# rubocop:disable all
class AddLocationToUser < ActiveRecord::Migration
def change
add_column :users, :location, :string
......
# rubocop:disable all
class SetIncorrectAssigneeIdToNull < ActiveRecord::Migration
def up
execute "UPDATE issues SET assignee_id = NULL WHERE assignee_id = -1"
......
# rubocop:disable all
class AddPublicToKey < ActiveRecord::Migration
def change
add_column :keys, :public, :boolean, default: false, null: false
......
# rubocop:disable all
class AddImportDataToProject < ActiveRecord::Migration
def change
add_column :projects, :import_data, :text
......
# rubocop:disable all
class AddDeviseTwoFactorToUsers < ActiveRecord::Migration
def change
add_column :users, :encrypted_otp_secret, :string
......
# rubocop:disable all
class AddMaxAttachmentSizeToApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :max_attachment_size, :integer, default: 10, null: false
......
# rubocop:disable all
class AddDeviseTwoFactorBackupableToUsers < ActiveRecord::Migration
def change
add_column :users, :otp_backup_codes, :text
......
# rubocop:disable all
class AddInviteDataToMember < ActiveRecord::Migration
def up
add_column :members, :created_by_id, :integer
......
# rubocop:disable all
class FixIdentities < ActiveRecord::Migration
def up
# Up until now, legacy 'ldap' references in the database were charitably
......
# rubocop:disable all
class RenameBuildboxService < ActiveRecord::Migration
def up
execute "UPDATE services SET type = 'BuildkiteService' WHERE type = 'BuildboxService';"
......
# rubocop:disable all
class AddPublicEmailToUsers < ActiveRecord::Migration
def change
add_column :users, :public_email, :string, default: "", null: false
......
# rubocop:disable all
class CreateProjectImportData < ActiveRecord::Migration
def change
create_table :project_import_data do |t|
......
# rubocop:disable all
class RemoveImportDataFromProject < ActiveRecord::Migration
def up
remove_column :projects, :import_data
......
# rubocop:disable all
class RemovePeriodsAtEndsOfUsernames < ActiveRecord::Migration
include Gitlab::ShellAdapter
......
# rubocop:disable all
class AddDefaultProjectVisibililtyToApplicationSettings < ActiveRecord::Migration
def up
add_column :application_settings, :default_project_visibility, :integer
......
# rubocop:disable all
# This migration is a duplicate of 20150425164651_change_collation_for_tag_names.acts_as_taggable_on_engine.rb
# It shold be applied before the index additions to ensure that `name` is case sensitive.
......
# rubocop:disable all
class RemoveDuplicateTags < ActiveRecord::Migration
def up
select_all("SELECT name, COUNT(id) as cnt FROM tags GROUP BY name HAVING COUNT(id) > 1").each do |tag|
......
# rubocop:disable all
# This migration comes from acts_as_taggable_on_engine (originally 2)
class AddMissingUniqueIndices < ActiveRecord::Migration
def self.up
......
# rubocop:disable all
# This migration comes from acts_as_taggable_on_engine (originally 3)
class AddTaggingsCounterCacheToTags < ActiveRecord::Migration
def self.up
......
# rubocop:disable all
# This migration comes from acts_as_taggable_on_engine (originally 4)
class AddMissingTaggableIndex < ActiveRecord::Migration
def self.up
......
# rubocop:disable all
# This migration comes from acts_as_taggable_on_engine (originally 5)
# This migration is added to circumvent issue #623 and have special characters
# work properly
......
# rubocop:disable all
class AddDefaultSnippetVisibilityToAppSettings < ActiveRecord::Migration
def up
add_column :application_settings, :default_snippet_visibility, :integer
......
# rubocop:disable all
class RemoveAbandonedGroupMembersRecords < ActiveRecord::Migration
def up
execute("DELETE FROM members WHERE type = 'GroupMember' AND source_id NOT IN(\
......
# rubocop:disable all
class AddRestrictedSignupDomainsToApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :restricted_signup_domains, :text
......
# rubocop:disable all
# Convert legacy Markdown-emphasized notes to the current, non-emphasized format
#
# _mentioned in 54f7727c850972f0401c1312a7c4a6a380de5666_
......
# rubocop:disable all
class AddNoteEventsToWebHooks < ActiveRecord::Migration
def up
add_column :web_hooks, :note_events, :boolean, default: false, null: false
......
# rubocop:disable all
class AddUserOauthApplicationsToApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :user_oauth_applications, :bool, default: true
......
# rubocop:disable all
class AddAfterSignOutPathForApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :after_sign_out_path, :string
......
# rubocop:disable all
class AddSessionExpireDelayForApplicationSettings < ActiveRecord::Migration
def change
unless column_exists?(:application_settings, :session_expire_delay)
......
# rubocop:disable all
class AddDashboardToUsers < ActiveRecord::Migration
def up
add_column :users, :dashboard, :integer, default: 0
......
# rubocop:disable all
class AddDefaultOtpRequiredForLoginValue < ActiveRecord::Migration
def up
execute %q{UPDATE users SET otp_required_for_login = FALSE WHERE otp_required_for_login IS NULL}
......
# rubocop:disable all
class AddProjectViewToUsers < ActiveRecord::Migration
def change
add_column :users, :project_view, :integer, default: 0
......
# rubocop:disable all
class AddCommitsCountToProject < ActiveRecord::Migration
def change
add_column :projects, :commit_count, :integer, default: 0
......
# rubocop:disable all
class AddUpdatedByToIssuablesAndNotes < ActiveRecord::Migration
def change
add_column :notes, :updated_by_id, :integer
......
# rubocop:disable all
class CreateAbuseReports < ActiveRecord::Migration
def change
create_table :abuse_reports do |t|
......
# rubocop:disable all
require 'yaml'
class AddSettingsImportSources < ActiveRecord::Migration
......
# rubocop:disable all
class RemoveOauthTokensFromUsers < ActiveRecord::Migration
def change
remove_column :users, :github_access_token, :string
......
# rubocop:disable all
class DeduplicateUserIdentities < ActiveRecord::Migration
def change
execute 'DROP TABLE IF EXISTS tt_migration_DeduplicateUserIdentities;'
......
# rubocop:disable all
class AddSentNotifications < ActiveRecord::Migration
def change
create_table :sent_notifications do |t|
......
# rubocop:disable all
class AddEnableSslVerification < ActiveRecord::Migration
def change
add_column :web_hooks, :enable_ssl_verification, :boolean, default: false
......
# rubocop:disable all
class AddCiTables < ActiveRecord::Migration
def change
create_table "ci_application_settings", force: true do |t|
......
# rubocop:disable all
class AddTemplateToLabel < ActiveRecord::Migration
def change
add_column :labels, :template, :boolean, default: false
......
# rubocop:disable all
class AddCiTags < ActiveRecord::Migration
def change
create_table "ci_taggings", force: true do |t|
......
# rubocop:disable all
class EnableSslVerificationByDefault < ActiveRecord::Migration
def change
change_column :web_hooks, :enable_ssl_verification, :boolean, default: true
......
# rubocop:disable all
class EnableSslVerificationForWebHooks < ActiveRecord::Migration
def up
execute("UPDATE web_hooks SET enable_ssl_verification = true")
......
# rubocop:disable all
class AddHelpPageTextToApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :help_page_text, :text
......
# rubocop:disable all
class AddIndexForCommittedAtAndId < ActiveRecord::Migration
def change
add_index :ci_commits, [:project_id, :committed_at, :id]
......
# rubocop:disable all
class AddCiEnabledToApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :ci_enabled, :boolean, null: false, default: true
......
# rubocop:disable all
class RemoveInvalidMilestonesFromMergeRequests < ActiveRecord::Migration
def up
execute("UPDATE merge_requests SET milestone_id = NULL where milestone_id NOT IN (SELECT id FROM milestones)")
......
# rubocop:disable all
class AddConsumedTimestepToUsers < ActiveRecord::Migration
def change
add_column :users, :consumed_timestep, :integer
......
# rubocop:disable all
class AddLineCodeToSentNotification < ActiveRecord::Migration
def change
add_column :sent_notifications, :line_code, :string
......
# rubocop:disable all
class AddProjectIdToCiCommit < ActiveRecord::Migration
def up
add_column :ci_commits, :gl_project_id, :integer
......
# rubocop:disable all
class MigrateProjectIdForCiCommits < ActiveRecord::Migration
def up
subquery = 'SELECT gitlab_id FROM ci_projects WHERE ci_projects.id = ci_commits.project_id'
......
# rubocop:disable all
class MergeRequestErrorField < ActiveRecord::Migration
def up
add_column :merge_requests, :merge_error, :string
......
# rubocop:disable all
class AddNullToNameForCiProjects < ActiveRecord::Migration
def up
change_column_null :ci_projects, :name, true
......
# rubocop:disable all
class AddGroupShareLock < ActiveRecord::Migration
def change
add_column :namespaces, :share_with_group_lock, :boolean, default: false
......
# rubocop:disable all
class AddStageIdxToBuilds < ActiveRecord::Migration
def change
add_column :ci_builds, :stage_idx, :integer
......
# rubocop:disable all
class AddIndexForBuilds < ActiveRecord::Migration
def up
add_index :ci_builds, [:commit_id, :stage_idx, :created_at]
......
# rubocop:disable all
class AddRefAndTagToBuilds < ActiveRecord::Migration
def change
add_column :ci_builds, :tag, :boolean
......
# rubocop:disable all
class MigrateRefAndTagToBuild < ActiveRecord::Migration
def change
execute('UPDATE ci_builds SET ref=(SELECT ref FROM ci_commits WHERE ci_commits.id = ci_builds.commit_id) WHERE ref IS NULL')
......
# rubocop:disable all
class AddUserIdToBuild < ActiveRecord::Migration
def change
add_column :ci_builds, :user_id, :integer
......
# rubocop:disable all
class AddLayoutOptionForUsers < ActiveRecord::Migration
def change
add_column :users, :layout, :integer, default: 0
......
# rubocop:disable all
class RemoveCiEnabledFromApplicationSettings < ActiveRecord::Migration
def change
remove_column :application_settings, :ci_enabled, :boolean, null: false, default: true
......
# rubocop:disable all
class NamespacesProjectsPathLowerIndexes < ActiveRecord::Migration
disable_ddl_transaction!
......
# rubocop:disable all
class AddUsersLowerUsernameEmailIndexes < ActiveRecord::Migration
disable_ddl_transaction!
......
# rubocop:disable all
class AddTypeAndDescriptionToBuilds < ActiveRecord::Migration
def change
add_column :ci_builds, :type, :string
......
# rubocop:disable all
class MigrateNameToDescriptionForBuilds < ActiveRecord::Migration
def change
execute("UPDATE ci_builds SET type='Ci::Build' WHERE type IS NULL")
......
# rubocop:disable all
class AddAdminNotificationEmailSetting < ActiveRecord::Migration
def change
add_column :application_settings, :admin_notification_email, :string
......
# rubocop:disable all
class SetJiraServiceApiUrl < ActiveRecord::Migration
# This migration can be performed online without errors, but some Jira API calls may be missed
# when doing so because api_url is not yet available.
......
# rubocop:disable all
class AddArtifactsFileToBuilds < ActiveRecord::Migration
def change
add_column :ci_builds, :artifacts_file, :text
......
# rubocop:disable all
class AddCiProjectsGlProjectIdIndex < ActiveRecord::Migration
def change
add_index :ci_commits, :gl_project_id
......
# rubocop:disable all
class AddCiBuildsAndProjectsIndexes < ActiveRecord::Migration
def change
add_index :ci_projects, :gitlab_id
......
# rubocop:disable all
class AddNotesLineCodeIndex < ActiveRecord::Migration
def change
add_index :notes, :line_code
......
# rubocop:disable all
class FixBuildTags < ActiveRecord::Migration
def up
execute("UPDATE taggings SET taggable_type='CommitStatus' WHERE taggable_type='Ci::Build'")
......
# rubocop:disable all
class FailBuildWithoutNames < ActiveRecord::Migration
def up
execute("UPDATE ci_builds SET status='failed' WHERE name IS NULL AND status='pending'")
......
# rubocop:disable all
class AddServicesTemplateIndex < ActiveRecord::Migration
def change
add_index :services, :template
......
# rubocop:disable all
class CiLimitsToMysql < ActiveRecord::Migration
def change
return unless ActiveRecord::Base.configurations[Rails.env]['adapter'] =~ /^mysql/
......
# rubocop:disable all
class AddCiBuildsIndexForStatus < ActiveRecord::Migration
def change
add_index :ci_builds, [:commit_id, :status, :type]
......
# rubocop:disable all
class FailBuildWithEmptyName < ActiveRecord::Migration
def up
execute("UPDATE ci_builds SET status='failed' WHERE (name IS NULL OR name='') AND status='pending'")
......
# rubocop:disable all
require 'fileutils'
class RemoveSatellites < ActiveRecord::Migration
......
# rubocop:disable all
class AddProjectPathIndex < ActiveRecord::Migration
def up
add_index :projects, :path
......
# rubocop:disable all
class AddMergeWhenBuildSucceedsToMergeRequest < ActiveRecord::Migration
def change
add_column :merge_requests, :merge_params, :text
......
# rubocop:disable all
class AddPublicToGroup < ActiveRecord::Migration
def change
add_column :namespaces, :public, :boolean, default: false
......
# rubocop:disable all
class AddSharedRunnersSetting < ActiveRecord::Migration
def up
add_column :application_settings, :shared_runners_enabled, :boolean, default: true, null: false
......
# rubocop:disable all
class CreateLfsObjects < ActiveRecord::Migration
def change
create_table :lfs_objects do |t|
......
# rubocop:disable all
class CreateLfsObjectsProjects < ActiveRecord::Migration
def change
create_table :lfs_objects_projects do |t|
......
# rubocop:disable all
class AddFileToLfsObjects < ActiveRecord::Migration
def change
add_column :lfs_objects, :file, :string
......
# rubocop:disable all
class CreateReleases < ActiveRecord::Migration
def change
create_table :releases do |t|
......
# rubocop:disable all
class AddIsAwardToNotes < ActiveRecord::Migration
def change
add_column :notes, :is_award, :boolean, default: false, null: false
......
# rubocop:disable all
class AddMaxArtifactsSizeToApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :max_artifacts_size, :integer, default: 100, null: false
......
# rubocop:disable all
class AddIssuesStateIndex < ActiveRecord::Migration
def change
add_index :issues, :state
......
# rubocop:disable all
class AddProjectsVisibilityLevelIndex < ActiveRecord::Migration
def change
add_index :projects, :visibility_level
......
# rubocop:disable all
class AddImportErrorToProject < ActiveRecord::Migration
def change
add_column :projects, :import_error, :text
......
# rubocop:disable all
class AddIndexForLfsOidAndSize < ActiveRecord::Migration
def change
add_index :lfs_objects, :oid
......
# rubocop:disable all
class AddUniqueForLfsOidIndex < ActiveRecord::Migration
def change
remove_index :lfs_objects, :oid
......
# rubocop:disable all
class AddProjectsPublicIndex < ActiveRecord::Migration
def change
add_index :namespaces, :public
......
# rubocop:disable all
class RaiseHookUrlLimit < ActiveRecord::Migration
def change
change_column :web_hooks, :url, :string, limit: 2000
......
# rubocop:disable all
class AddHideProjectLimitToUsers < ActiveRecord::Migration
def change
add_column :users, :hide_project_limit, :boolean, default: false
......
# rubocop:disable all
class AddBuildEventsToServices < ActiveRecord::Migration
def change
add_column :services, :build_events, :boolean, default: false, null: false
......
# rubocop:disable all
class MigrateCiWebHooks < ActiveRecord::Migration
include Gitlab::Database
......
# rubocop:disable all
class MigrateCiEmails < ActiveRecord::Migration
include Gitlab::Database
......
# rubocop:disable all
class AddUnlockTokenToUser < ActiveRecord::Migration
def change
add_column :users, :unlock_token, :string
......
# rubocop:disable all
class AddRunnersRegistrationTokenToApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :runners_registration_token, :string
......
# rubocop:disable all
class MigrateCiSlackService < ActiveRecord::Migration
include Gitlab::Database
......
# rubocop:disable all
class MigrateCiHipChatService < ActiveRecord::Migration
include Gitlab::Database
......
# rubocop:disable all
class AddCiToProject < ActiveRecord::Migration
def change
add_column :projects, :ci_id, :integer
......
# rubocop:disable all
class AddProjectIdToCi < ActiveRecord::Migration
def change
add_column :ci_builds, :gl_project_id, :integer
......
# rubocop:disable all
class MigrateCiToProject < ActiveRecord::Migration
def up
migrate_project_id_for_table('ci_runner_projects')
......
# rubocop:disable all
class AddIndexToCiTables < ActiveRecord::Migration
def change
add_index :ci_builds, :gl_project_id
......
# rubocop:disable all
class DropNullForCiTables < ActiveRecord::Migration
def change
remove_index :ci_variables, :project_id
......
# rubocop:disable all
class AddTfaToApplicationSettings < ActiveRecord::Migration
def change
change_table :application_settings do |t|
......
# rubocop:disable all
class AddTfaAdditionalFields < ActiveRecord::Migration
def change
change_table :users do |t|
......
# rubocop:disable all
# Migration type: online without errors (works on previous version and new one)
class RenameEmojis < ActiveRecord::Migration
def up
......
# rubocop:disable all
# Migration type: online
class RemovePublicFromNamespace < ActiveRecord::Migration
def change
......
# rubocop:disable all
class InfluxdbSettings < ActiveRecord::Migration
def change
add_column :application_settings, :metrics_enabled, :boolean, default: false
......
# rubocop:disable all
class AddRecaptchaToApplicationSettings < ActiveRecord::Migration
def change
change_table :application_settings do |t|
......
# rubocop:disable all
class InfluxdbUdpPortSetting < ActiveRecord::Migration
def change
add_column :application_settings, :metrics_port, :integer, default: 8089
......
# rubocop:disable all
class InfluxdbRemoteDatabaseSetting < ActiveRecord::Migration
def change
remove_column :application_settings, :metrics_database
......
# rubocop:disable all
class AddArtifactsMetadataToCiBuild < ActiveRecord::Migration
def change
add_column :ci_builds, :artifacts_metadata, :text
......
# rubocop:disable all
class AddAkismetToApplicationSettings < ActiveRecord::Migration
def change
change_table :application_settings do |t|
......
# rubocop:disable all
class RemoveAlertTypeFromBroadcastMessages < ActiveRecord::Migration
def change
remove_column :broadcast_messages, :alert_type, :integer
......
# rubocop:disable all
class AddIndexMilestonesTitle < ActiveRecord::Migration
def change
add_index :milestones, :title
......
# rubocop:disable all
class RemoveInfluxdbCredentials < ActiveRecord::Migration
def change
remove_column :application_settings, :metrics_username, :string
......
# rubocop:disable all
class CreateSpamLogs < ActiveRecord::Migration
def change
create_table :spam_logs do |t|
......
# rubocop:disable all
class AddMetricsSampleInterval < ActiveRecord::Migration
def change
add_column :application_settings, :metrics_sample_interval, :integer,
......
# rubocop:disable all
class AddSentryToApplicationSettings < ActiveRecord::Migration
def change
change_table :application_settings do |t|
......
# rubocop:disable all
class AddIpBlockingSettingsToApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :ip_blocking_enabled, :boolean, default: false
......
# rubocop:disable all
class AddServicesCategory < ActiveRecord::Migration
def up
add_column :services, :category, :string, default: 'common', null: false
......
# rubocop:disable all
class AddServicesDefault < ActiveRecord::Migration
def up
add_column :services, :default, :boolean, default: false
......
# rubocop:disable all
class AddLdapEmailToUsers < ActiveRecord::Migration
def up
add_column :users, :ldap_email, :boolean, default: false, null: false
......
# rubocop:disable all
class AddBaseCommitShaToMergeRequestDiffs < ActiveRecord::Migration
def change
add_column :merge_request_diffs, :base_commit_sha, :string
......
# rubocop:disable all
class AddEmailAuthorInBodyToApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :email_author_in_body, :boolean, default: false
......
# rubocop:disable all
class AddPendingDeleteToProject < ActiveRecord::Migration
def change
add_column :projects, :pending_delete, :boolean, default: false
......
# rubocop:disable all
class RemoveIpBlockingSettingsFromApplicationSettings < ActiveRecord::Migration
def change
remove_column :application_settings, :ip_blocking_enabled, :boolean, default: false
......
# rubocop:disable all
class ChangeLfsObjectsSizeColumn < ActiveRecord::Migration
def change
change_column :lfs_objects, :size, :integer, limit: 8
......
# rubocop:disable all
class RemoveDotAtomPathEndingOfProjects < ActiveRecord::Migration
include Gitlab::ShellAdapter
......
# rubocop:disable all
class AddMergeCommitShaToMergeRequests < ActiveRecord::Migration
def change
add_column :merge_requests, :merge_commit_sha, :string
......
# rubocop:disable all
class AddErasableToCiBuild < ActiveRecord::Migration
def change
add_reference :ci_builds, :erased_by, references: :users, index: true
......
# rubocop:disable all
class AddAllowGuestToAccessBuildsProject < ActiveRecord::Migration
def change
add_column :projects, :public_builds, :boolean, default: true, null: false
......
# rubocop:disable all
class AddRealSizeToMergeRequestDiffs < ActiveRecord::Migration
def change
add_column :merge_request_diffs, :real_size, :string
......
# rubocop:disable all
class AddIndexToSnippet < ActiveRecord::Migration
def change
add_index :snippets, :updated_at
......
# rubocop:disable all
class CreateTasks < ActiveRecord::Migration
def change
create_table :tasks do |t|
......
# rubocop:disable all
class AddDescriptionToLabel < ActiveRecord::Migration
def change
add_column :labels, :description, :string
......
# rubocop:disable all
class AddNoteToTasks < ActiveRecord::Migration
def change
add_reference :tasks, :note, index: true
......
# rubocop:disable all
class RenameTasksToTodos < ActiveRecord::Migration
def change
rename_table :tasks, :todos
......
# rubocop:disable all
class CreateAppearancesCe < ActiveRecord::Migration
def change
unless table_exists?(:appearances)
......
# rubocop:disable all
class AddConfidentialToIssues < ActiveRecord::Migration
def change
add_column :issues, :confidential, :boolean, default: false
......
# rubocop:disable all
class AddDeleteAtToIssues < ActiveRecord::Migration
def change
add_column :issues, :deleted_at, :datetime
......
# rubocop:disable all
class AddDeleteAtToMergeRequests < ActiveRecord::Migration
def change
add_column :merge_requests, :deleted_at, :datetime
......
# rubocop:disable all
class AddTrigramIndexesForSearching < ActiveRecord::Migration
disable_ddl_transaction!
......
# rubocop:disable all
class AddEventFieldForWebHook < ActiveRecord::Migration
def change
add_column :web_hooks, :wiki_page_events, :boolean, default: false, null: false
......
# rubocop:disable all
class AddEventToServices < ActiveRecord::Migration
def change
add_column :services, :wiki_page_events, :boolean, default: true
......
# rubocop:disable all
class AddMainLanguageToRepository < ActiveRecord::Migration
def change
add_column :projects, :main_language, :string
......
# rubocop:disable all
class AddVisibilityLevelToGroups < ActiveRecord::Migration
def up
add_column :namespaces, :visibility_level, :integer, null: false, default: Gitlab::VisibilityLevel::PUBLIC
......
# rubocop:disable all
class AddImportCredentialsToProjectImportData < ActiveRecord::Migration
def change
add_column :project_import_data, :encrypted_credentials, :text
......
# rubocop:disable all
# Loops through old importer projects that kept a token/password in the import URL
# and encrypts the credentials into a separate field in project#import_data
# #down method not supported
......
# rubocop:disable all
class RemoveExpiresAtFromSnippets < ActiveRecord::Migration
def change
remove_column :snippets, :expires_at, :datetime
......
# rubocop:disable all
class DisallowBlankLineCodeOnNote < ActiveRecord::Migration
def up
execute("UPDATE notes SET line_code = NULL WHERE line_code = ''")
......
# rubocop:disable all
# Create visibility level field on DB
# Sets default_visibility_level to value on settings if not restricted
# If value is restricted takes higher visibility level allowed
......
# rubocop:disable all
class FixTodos < ActiveRecord::Migration
def up
execute <<-SQL
......
# rubocop:disable all
class AddDueDateToIssues < ActiveRecord::Migration
def change
add_column :issues, :due_date, :date
......
# rubocop:disable all
class AddExternalFlagToUsers < ActiveRecord::Migration
def change
add_column :users, :external, :boolean, default: false
......
# rubocop:disable all
class AddPriorityToLabel < ActiveRecord::Migration
def change
add_column :labels, :priority, :integer
......
# rubocop:disable all
class ProjectsAddPushesSinceGc < ActiveRecord::Migration
def change
add_column :projects, :pushes_since_gc, :integer, default: 0
......
# rubocop:disable all
class ProjectAddRepositoryCheck < ActiveRecord::Migration
def change
add_column :projects, :last_repository_check_failed, :boolean
......
# rubocop:disable all
class CiRunnersTokenIndex < ActiveRecord::Migration
disable_ddl_transaction!
......
# rubocop:disable all
class ChangeTargetIdToNullOnTodos < ActiveRecord::Migration
def change
change_column_null :todos, :target_id, true
......
# rubocop:disable all
class AddCommitIdToTodos < ActiveRecord::Migration
def change
add_column :todos, :commit_id, :string
......
# rubocop:disable all
class AddMovedToToIssue < ActiveRecord::Migration
def change
add_reference :issues, :moved_to, references: :issues
......
# rubocop:disable all
class IndexNamespacesOnVisibilityLevel < ActiveRecord::Migration
def change
unless index_exists?(:namespaces, :visibility_level)
......
# rubocop:disable all
class RemoveTodosForDeletedIssues < ActiveRecord::Migration
def up
execute <<-SQL
......
# rubocop:disable all
class CreateNotificationSettings < ActiveRecord::Migration
def change
create_table :notification_settings do |t|
......
# rubocop:disable all
# This migration will create one row of NotificationSetting for each Member row
# It can take long time on big instances.
#
......
# rubocop:disable all
class AddNotificationSettingIndex < ActiveRecord::Migration
def change
add_index :notification_settings, :user_id
......
# rubocop:disable all
class AddIndexOnPendingDeleteProjects < ActiveRecord::Migration
def change
add_index :projects, :pending_delete
......
# rubocop:disable all
class RemoveTodosForDeletedMergeRequests < ActiveRecord::Migration
def up
execute <<-SQL
......
# rubocop:disable all
class RemoveTwitterSharingEnabledFromApplicationSettings < ActiveRecord::Migration
def change
remove_column :application_settings, :twitter_sharing_enabled, :boolean
......
# rubocop:disable all
class AddImagesEnabledForProject < ActiveRecord::Migration
def change
add_column :projects, :container_registry_enabled, :boolean
......
# rubocop:disable all
class AddRepositoryChecksEnabledSetting < ActiveRecord::Migration
def change
add_column :application_settings, :repository_checks_enabled, :boolean, default: true
......
# rubocop:disable all
class AddFieldsToCiCommit < ActiveRecord::Migration
def change
add_column :ci_commits, :status, :string
......
# rubocop:disable all
class UpdateCiCommit < ActiveRecord::Migration
# This migration can be run online, but needs to be executed for the second time after restarting Unicorn workers
# Otherwise Offline migration should be used.
......
# rubocop:disable all
class AddCiCommitIndexes < ActiveRecord::Migration
disable_ddl_transaction!
......
# rubocop:disable all
class AddTokenToWebHooks < ActiveRecord::Migration
def change
add_column :web_hooks, :token, :string
......
# rubocop:disable all
class AddSharedRunnersTextToApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :shared_runners_text, :text
......
# rubocop:disable all
class AddAwardEmoji < ActiveRecord::Migration
def change
create_table :award_emoji do |t|
......
# rubocop:disable all
class ConvertAwardNoteToEmojiAward < ActiveRecord::Migration
def change
def up
......
# rubocop:disable all
class RemoveNoteIsAward < ActiveRecord::Migration
def change
remove_column :notes, :is_award, :boolean
......
# rubocop:disable all
class AddMetricsPacketSize < ActiveRecord::Migration
def change
add_column :application_settings, :metrics_packet_size, :integer, default: 1
......
# rubocop:disable all
class DisableRepositoryChecks < ActiveRecord::Migration
def up
change_column_default :application_settings, :repository_checks_enabled, false
......
# rubocop:disable all
class CreateU2fRegistrations < ActiveRecord::Migration
def change
create_table :u2f_registrations do |t|
......
# rubocop:disable all
class AddDisabledOauthSignInSourcesToApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :disabled_oauth_sign_in_sources, :text
......
# rubocop:disable all
class AddRunUntaggedToCiRunner < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
disable_ddl_transaction!
......
# rubocop:disable all
class RemoveWallEnabledFromProjects < ActiveRecord::Migration
def change
remove_column :projects, :wall_enabled, :boolean, default: true, null: false
......
# rubocop:disable all
class AddTypeToNotes < ActiveRecord::Migration
def change
add_column :notes, :type, :string
......
# rubocop:disable all
class SetTypeOnLegacyDiffNotes < ActiveRecord::Migration
def change
execute "UPDATE notes SET type = 'LegacyDiffNote' WHERE line_code IS NOT NULL"
......
# rubocop:disable all
class AddHealthCheckAccessTokenToApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :health_check_access_token, :string
......
# rubocop:disable all
class AddSendUserConfirmationEmailToApplicationSettings < ActiveRecord::Migration
def up
add_column :application_settings, :send_user_confirmation_email, :boolean, default: false
......
# rubocop:disable all
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
......
# rubocop:disable all
class RemoveNotificationSettingsForDeletedProjects < ActiveRecord::Migration
def up
execute <<-SQL
......
# rubocop:disable all
class AddUsersStateIndex < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
......
# rubocop:disable all
# This is ONLINE migration
class AddContainerRegistryTokenExpireDelayToApplicationSettings < ActiveRecord::Migration
......
# rubocop:disable all
class RemoveDuplicatedNotificationSettings < ActiveRecord::Migration
def up
duplicates = exec_query(%Q{
......
# rubocop:disable all
class AddIndexToNotificationSettings < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
......
# rubocop:disable all
class AddAfterSignUpTextToApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :after_sign_up_text, :text
......
# rubocop:disable all
class LimitsToMysql < ActiveRecord::Migration
def up
return unless ActiveRecord::Base.configurations[Rails.env]['adapter'] =~ /^mysql/
......
......@@ -9,7 +9,7 @@ class Spinach::Features::ProjectIssuesLabels < Spinach::FeatureSteps
step 'I remove label \'bug\'' do
page.within "#label_#{bug_label.id}" do
click_link 'Delete'
first(:link, 'Delete').click
end
end
......
......@@ -29,6 +29,6 @@ class Spinach::Features::Labels < Spinach::FeatureSteps
private
def subscribe_button
first('.label-subscribe-button span')
first('.js-subscribe-button', visible: true)
end
end
module Gitlab
module GithubImport
class Client
GITHUB_SAFE_REMAINING_REQUESTS = 100
GITHUB_SAFE_SLEEP_TIME = 500
attr_reader :client, :api
def initialize(access_token)
......@@ -11,7 +14,7 @@ module Gitlab
)
if access_token
::Octokit.auto_paginate = true
::Octokit.auto_paginate = false
@api = ::Octokit::Client.new(
access_token: access_token,
......@@ -36,7 +39,7 @@ module Gitlab
def method_missing(method, *args, &block)
if api.respond_to?(method)
api.send(method, *args, &block)
request { api.send(method, *args, &block) }
else
super(method, *args, &block)
end
......@@ -55,6 +58,34 @@ module Gitlab
def github_options
config["args"]["client_options"].deep_symbolize_keys
end
def rate_limit
api.rate_limit!
end
def rate_limit_exceed?
rate_limit.remaining <= GITHUB_SAFE_REMAINING_REQUESTS
end
def rate_limit_sleep_time
rate_limit.resets_in + GITHUB_SAFE_SLEEP_TIME
end
def request
sleep rate_limit_sleep_time if rate_limit_exceed?
data = yield
last_response = api.last_response
while last_response.rels[:next]
sleep rate_limit_sleep_time if rate_limit_exceed?
last_response = last_response.rels[:next].get
data.concat(last_response.data) if last_response.data.is_a?(Array)
end
data
end
end
end
end
......@@ -3,9 +3,6 @@ module Gitlab
class Importer
include Gitlab::ShellAdapter
GITHUB_SAFE_REMAINING_REQUESTS = 100
GITHUB_SAFE_SLEEP_TIME = 500
attr_reader :client, :project, :repo, :repo_url
def initialize(project)
......@@ -28,52 +25,12 @@ module Gitlab
private
def turn_auto_pagination_off!
client.auto_paginate = false
end
def turn_auto_pagination_on!
client.auto_paginate = true
end
def rate_limit
client.rate_limit!
end
def rate_limit_exceed?
rate_limit.remaining <= GITHUB_SAFE_REMAINING_REQUESTS
end
def rate_limit_sleep_time
rate_limit.resets_in + GITHUB_SAFE_SLEEP_TIME
end
def paginate
turn_auto_pagination_off!
sleep rate_limit_sleep_time if rate_limit_exceed?
data = yield
last_response = client.last_response
while last_response.rels[:next]
sleep rate_limit_sleep_time if rate_limit_exceed?
last_response = last_response.rels[:next].get
data.concat(last_response.data) if last_response.data.is_a?(Array)
end
turn_auto_pagination_on!
data
end
def credentials
@credentials ||= project.import_data.credentials if project.import_data
end
def import_labels
labels = paginate { client.labels(repo, per_page: 100) }
labels = client.labels(repo, per_page: 100)
labels.each { |raw| LabelFormatter.new(project, raw).create! }
true
......@@ -82,7 +39,7 @@ module Gitlab
end
def import_milestones
milestones = paginate { client.milestones(repo, state: :all, per_page: 100) }
milestones = client.milestones(repo, state: :all, per_page: 100)
milestones.each { |raw| MilestoneFormatter.new(project, raw).create! }
true
......@@ -91,9 +48,9 @@ module Gitlab
end
def import_issues
data = paginate { client.issues(repo, state: :all, sort: :created, direction: :asc, per_page: 100) }
issues = client.issues(repo, state: :all, sort: :created, direction: :asc, per_page: 100)
data.each do |raw|
issues.each do |raw|
gh_issue = IssueFormatter.new(project, raw)
if gh_issue.valid?
......@@ -112,7 +69,7 @@ module Gitlab
hooks = client.hooks(repo).map { |raw| HookFormatter.new(raw) }.select(&:valid?)
disable_webhooks(hooks)
pull_requests = paginate { client.pull_requests(repo, state: :all, sort: :created, direction: :asc, per_page: 100) }
pull_requests = client.pull_requests(repo, state: :all, sort: :created, direction: :asc, per_page: 100)
pull_requests = pull_requests.map { |raw| PullRequestFormatter.new(project, raw) }.select(&:valid?)
source_branches_removed = pull_requests.reject(&:source_branch_exists?).map { |pr| [pr.source_branch_name, pr.source_branch_sha] }
......@@ -146,14 +103,12 @@ module Gitlab
def update_webhooks(hooks, options)
hooks.each do |hook|
sleep rate_limit_sleep_time if rate_limit_exceed?
client.edit_hook(repo, hook.id, hook.name, hook.config, options)
end
end
def restore_branches(branches)
branches.each do |name, sha|
sleep rate_limit_sleep_time if rate_limit_exceed?
client.create_ref(repo, "refs/heads/#{name}", sha)
end
......@@ -162,15 +117,12 @@ module Gitlab
def clean_up_restored_branches(branches)
branches.each do |name, _|
sleep rate_limit_sleep_time if rate_limit_exceed?
client.delete_ref(repo, "heads/#{name}")
project.repository.rm_branch(project.creator, name)
end
end
def apply_labels(issuable)
sleep rate_limit_sleep_time if rate_limit_exceed?
issue = client.issue(repo, issuable.iid)
if issue.labels.count > 0
......@@ -183,12 +135,12 @@ module Gitlab
end
def import_comments(issuable)
comments = paginate { client.issue_comments(repo, issuable.iid, per_page: 100) }
comments = client.issue_comments(repo, issuable.iid, per_page: 100)
create_comments(issuable, comments)
end
def import_comments_on_diff(merge_request)
comments = paginate { client.pull_request_comments(repo, merge_request.iid, per_page: 100) }
comments = client.pull_request_comments(repo, merge_request.iid, per_page: 100)
create_comments(merge_request, comments)
end
......
......@@ -8,6 +8,7 @@ module Gitlab
gon.relative_url_root = Gitlab.config.gitlab.relative_url_root
gon.shortcuts_path = help_shortcuts_path
gon.user_color_scheme = Gitlab::ColorSchemes.for_user(current_user).css_class
gon.award_menu_url = emojis_path
if current_user
gon.current_user_id = current_user.id
......
......@@ -34,7 +34,7 @@ namespace :gitlab do
# PG: http://www.postgresql.org/docs/current/static/ddl-depend.html
# MySQL: http://dev.mysql.com/doc/refman/5.7/en/drop-table.html
# Add `IF EXISTS` because cascade could have already deleted a table.
tables.each { |t| connection.execute("DROP TABLE IF EXISTS #{t} CASCADE") }
tables.each { |t| connection.execute("DROP TABLE IF EXISTS #{connection.quote_table_name(t)} CASCADE") }
end
desc 'Configures the database by running migrate, or by loading the schema and seeding if needed'
......
require 'spec_helper'
feature 'Tooltips on .timeago dates', feature: true, js: true do
include WaitForAjax
let(:user) { create(:user) }
let(:project) { create(:project, name: 'test', namespace: user.namespace) }
let(:created_date) { Date.yesterday.to_time }
let(:expected_format) { created_date.strftime('%b %-d, %Y %l:%M%P UTC') }
context 'on the activity tab' do
before do
project.team << [user, :master]
Event.create( project: project, author_id: user.id, action: Event::JOINED,
updated_at: created_date, created_at: created_date)
login_as user
visit user_path(user)
wait_for_ajax()
page.find('.js-timeago').hover
end
it 'has the datetime formated correctly' do
expect(page).to have_selector('.local-timeago', text: expected_format)
end
end
context 'on the snippets tab' do
before do
project.team << [user, :master]
create(:snippet, author: user, updated_at: created_date, created_at: created_date)
login_as user
visit user_snippets_path(user)
wait_for_ajax()
page.find('.js-timeago').hover
end
it 'has the datetime formated correctly' do
expect(page).to have_selector('.local-timeago', text: expected_format)
end
end
end
......@@ -75,12 +75,13 @@ describe 'Issues', feature: true do
fill_in 'issue_title', with: 'bug 345'
fill_in 'issue_description', with: 'bug description'
find('#issuable-due-date').click
page.within '.datepicker' do
page.within '.ui-datepicker' do
click_link date.day
end
expect(find('#issuable-due-date', visible: false).value).to eq date.to_s
expect(find('#issuable-due-date').value).to eq date.to_s
click_button 'Submit issue'
......@@ -100,18 +101,19 @@ describe 'Issues', feature: true do
it 'should save with due date' do
date = Date.today.at_beginning_of_month
expect(find('#issuable-due-date', visible: false).value).to eq date.to_s
expect(find('#issuable-due-date').value).to eq date.to_s
date = date.tomorrow
fill_in 'issue_title', with: 'bug 345'
fill_in 'issue_description', with: 'bug description'
find('#issuable-due-date').click
page.within '.datepicker' do
page.within '.ui-datepicker' do
click_link date.day
end
expect(find('#issuable-due-date', visible: false).value).to eq date.to_s
expect(find('#issuable-due-date').value).to eq date.to_s
click_button 'Save changes'
......
......@@ -3,10 +3,11 @@
#= require jquery.cookie
#= require ./fixtures/emoji_menu
awardsHandler = null
window.gl or= {}
gl.emojiAliases = -> return { '+1': 'thumbsup', '-1': 'thumbsdown' }
gl.awardMenuUrl = '/emojis'
awardsHandler = null
window.gl or= {}
window.gon or= {}
gl.emojiAliases = -> return { '+1': 'thumbsup', '-1': 'thumbsdown' }
gon.award_menu_url = '/emojis'
lazyAssert = (done, assertFn) ->
......@@ -25,9 +26,7 @@ describe 'AwardsHandler', ->
fixture.load 'awards_handler.html'
awardsHandler = new AwardsHandler
spyOn(awardsHandler, 'postEmoji').and.callFake (url, emoji, cb) => cb()
spyOn(jQuery, 'get').and.callFake (req, cb) ->
expect(req).toBe '/emojis'
cb window.emojiMenu
spyOn(jQuery, 'get').and.callFake (req, cb) -> cb window.emojiMenu
describe '::showEmojiMenu', ->
......
......@@ -2,7 +2,7 @@ require 'spec_helper'
describe DisableEmailInterceptor, lib: true do
before do
ActionMailer::Base.register_interceptor(DisableEmailInterceptor)
Mail.register_interceptor(DisableEmailInterceptor)
end
it 'should not send emails' do
......@@ -14,7 +14,7 @@ describe DisableEmailInterceptor, lib: true do
# Removing interceptor from the list because unregister_interceptor is
# implemented in later version of mail gem
# See: https://github.com/mikel/mail/pull/705
Mail.class_variable_set(:@@delivery_interceptors, [])
Mail.unregister_interceptor(DisableEmailInterceptor)
end
def deliver_mail
......
......@@ -2,7 +2,7 @@ require "spec_helper"
describe 'Git HTTP requests', lib: true do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:project) { create(:project, path: 'project.git-project') }
it "gives WWW-Authenticate hints" do
clone_get('doesnt/exist.git')
......@@ -268,6 +268,87 @@ describe 'Git HTTP requests', lib: true do
end
end
context "when the project path doesn't end in .git" do
context "GET info/refs" do
let(:path) { "/#{project.path_with_namespace}/info/refs" }
context "when no params are added" do
before { get path }
it "redirects to the .git suffix version" do
expect(response).to redirect_to("/#{project.path_with_namespace}.git/info/refs")
end
end
context "when the upload-pack service is requested" do
let(:params) { { service: 'git-upload-pack' } }
before { get path, params }
it "redirects to the .git suffix version" do
expect(response).to redirect_to("/#{project.path_with_namespace}.git/info/refs?service=#{params[:service]}")
end
end
context "when the receive-pack service is requested" do
let(:params) { { service: 'git-receive-pack' } }
before { get path, params }
it "redirects to the .git suffix version" do
expect(response).to redirect_to("/#{project.path_with_namespace}.git/info/refs?service=#{params[:service]}")
end
end
context "when the params are anything else" do
let(:params) { { service: 'git-implode-pack' } }
before { get path, params }
it "redirects to the sign-in page" do
expect(response).to redirect_to(new_user_session_path)
end
end
end
context "POST git-upload-pack" do
it "fails to find a route" do
expect { clone_post(project.path_with_namespace) }.to raise_error(ActionController::RoutingError)
end
end
context "POST git-receive-pack" do
it "failes to find a route" do
expect { push_post(project.path_with_namespace) }.to raise_error(ActionController::RoutingError)
end
end
end
context "retrieving an info/refs file" do
before { project.update_attribute(:visibility_level, Project::PUBLIC) }
context "when the file exists" do
before do
# Provide a dummy file in its place
allow_any_instance_of(Repository).to receive(:blob_at).and_call_original
allow_any_instance_of(Repository).to receive(:blob_at).with('5937ac0a7beb003549fc5fd26fc247adbce4a52e', 'info/refs') do
Gitlab::Git::Blob.find(project.repository, 'master', '.gitignore')
end
get "/#{project.path_with_namespace}/blob/master/info/refs"
end
it "returns the file" do
expect(response.status).to eq(200)
end
end
context "when the file exists" do
before { get "/#{project.path_with_namespace}/blob/master/info/refs" }
it "returns not found" do
expect(response.status).to eq(404)
end
end
end
def clone_get(project, options={})
get "/#{project}/info/refs", { service: 'git-upload-pack' }, auth_env(*options.values_at(:user, :password))
end
......
......@@ -18,7 +18,7 @@ describe TodoService, services: true do
end
describe 'Issues' do
let(:issue) { create(:issue, project: project, assignee: john_doe, author: author, description: mentions) }
let(:issue) { create(:issue, project: project, assignee: john_doe, author: author, description: "- [ ] Task 1\n- [ ] Task 2 #{mentions}") }
let(:unassigned_issue) { create(:issue, project: project, assignee: nil) }
let(:confidential_issue) { create(:issue, :confidential, project: project, author: author, assignee: assignee, description: mentions) }
......@@ -101,6 +101,19 @@ describe TodoService, services: true do
should_create_todo(user: admin, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
should_not_create_todo(user: john_doe, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
end
it 'does not create todo when when tasks are marked as completed' do
issue.update(description: "- [x] Task 1\n- [X] Task 2 #{mentions}")
service.update_issue(issue, author)
should_not_create_todo(user: admin, target: issue, action: Todo::MENTIONED)
should_not_create_todo(user: assignee, target: issue, action: Todo::MENTIONED)
should_not_create_todo(user: author, target: issue, action: Todo::MENTIONED)
should_not_create_todo(user: john_doe, target: issue, action: Todo::MENTIONED)
should_not_create_todo(user: member, target: issue, action: Todo::MENTIONED)
should_not_create_todo(user: non_member, target: issue, action: Todo::MENTIONED)
end
end
describe '#close_issue' do
......@@ -210,7 +223,7 @@ describe TodoService, services: true do
end
describe 'Merge Requests' do
let(:mr_assigned) { create(:merge_request, source_project: project, author: author, assignee: john_doe, description: mentions) }
let(:mr_assigned) { create(:merge_request, source_project: project, author: author, assignee: john_doe, description: "- [ ] Task 1\n- [ ] Task 2 #{mentions}") }
let(:mr_unassigned) { create(:merge_request, source_project: project, author: author, assignee: nil) }
describe '#new_merge_request' do
......@@ -253,6 +266,19 @@ describe TodoService, services: true do
expect { service.update_merge_request(mr_assigned, author) }.not_to change(member.todos, :count)
end
it 'does not create todo when when tasks are marked as completed' do
mr_assigned.update(description: "- [x] Task 1\n- [X] Task 2 #{mentions}")
service.update_merge_request(mr_assigned, author)
should_not_create_todo(user: admin, target: mr_assigned, action: Todo::MENTIONED)
should_not_create_todo(user: assignee, target: mr_assigned, action: Todo::MENTIONED)
should_not_create_todo(user: author, target: mr_assigned, action: Todo::MENTIONED)
should_not_create_todo(user: john_doe, target: mr_assigned, action: Todo::MENTIONED)
should_not_create_todo(user: member, target: mr_assigned, action: Todo::MENTIONED)
should_not_create_todo(user: non_member, target: mr_assigned, action: Todo::MENTIONED)
end
end
describe '#close_merge_request' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment