Commit 490ae8a6 authored by Lin Jen-Shin's avatar Lin Jen-Shin

Merge remote-tracking branch 'ee/master' into ce-to-ee-2017-07-28

* ee/master:
  And end
  Squashed commit of the following:
  Trailing Spaces removed
  Moves the Performance Bar to the top instead of being at the bottom
  Fix remote mirror last_update_at nil error in view
  Adds restrict group owners to admins option to admin application settings dashboard
  Working File Locks
  Update CHANGELOG.md for 9.4.2
  Update CHANGELOG-EE.md for 9.4.2-ee
  Converting it to true string if :file_locks available
  Merge issuable "reopened" state into "opened"
  Remove :remove_default_access_levels and use
  Replace autodeploy guide image to use blank namespace
  Latest Changes from CE applied
  Removed Path Locks from _tree_content.html.haml
  removed similar code
  fixed form submitting
  EE port of ph-inline-js
  Applied Patch of inline-js-removal-projects-other from CE Also removed Additional EE Inline Script on _tree_content.html.haml
parents 2b84e500 d8aec0b7
Please view this file on the master branch, on stable branches it's out of date. Please view this file on the master branch, on stable branches it's out of date.
## 9.4.2 (2017-07-28)
- Adds lower bound to pull mirror scheduling feature. !2366
- Add warning and option toggle when rebuilding authorized_keys. !2508
- Fix CSS for mini graph with downstream pipeline.
- Renamed board to boards in new project sidebar.
- Fix Rebasing not working with Merge Requests.
- Fixed issue boards focus mode when new navigation is turned on.
## 9.4.1 (2017-07-25) ## 9.4.1 (2017-07-25)
- Cleans up mirror capacity in project destroy service if project is a scheduled mirror. !2445 - Cleans up mirror capacity in project destroy service if project is a scheduled mirror. !2445
......
...@@ -2,6 +2,21 @@ ...@@ -2,6 +2,21 @@
documentation](doc/development/changelog.md) for instructions on adding your own documentation](doc/development/changelog.md) for instructions on adding your own
entry. entry.
## 9.4.2 (2017-07-28)
- Fix job merge request link to a forked source project. !12965
- Improve redirect route query performance. !13062
- Allow admin to read_users_list even if it's restricted. !13066
- Fixes 500 error caused by pending delete projects in admin dashboard. !13067
- Add instrumentation to MarkupHelper#link_to_gfm. !13069
- Pending delete projects should not show in deploy keys. !13088
- Fix sizing of custom header logo in new navigation.
- Fix crash on /help/ui.
- Fix creating merge request diffs when diff contains bytes that are invalid in UTF-8.
- fix vertical alignment of New Project button.
- Add LDAP SSL certificate verification option.
- Fix vertical alignment in firefox and safari for pipeline mini graph.
## 9.4.1 (2017-07-25) ## 9.4.1 (2017-07-25)
- Fix pipeline_schedules pages throwing error 500 (when ref is empty). !12983 - Fix pipeline_schedules pages throwing error 500 (when ref is empty). !12983
......
...@@ -24,11 +24,6 @@ class AuditLogs { ...@@ -24,11 +24,6 @@ class AuditLogs {
$('.project-item-select').on('click', () => { $('.project-item-select').on('click', () => {
$('form.filter-form').submit(); $('form.filter-form').submit();
}); });
$('form.filter-form').on('submit', function applyFilters(event) {
event.preventDefault();
gl.utils.visitUrl(`${this.action}?${$(this).serialize()}`);
});
} }
initFilterDropdown($dropdown, fieldName, searchFields, cb) { initFilterDropdown($dropdown, fieldName, searchFields, cb) {
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
/* global LabelsSelect */ /* global LabelsSelect */
/* global MilestoneSelect */ /* global MilestoneSelect */
/* global Commit */ /* global Commit */
/* global NewBranchForm */
/* global NotificationsForm */ /* global NotificationsForm */
/* global NotificationsDropdown */ /* global NotificationsDropdown */
/* global GroupAvatar */ /* global GroupAvatar */
...@@ -23,6 +24,7 @@ ...@@ -23,6 +24,7 @@
/* global MergeRequest */ /* global MergeRequest */
/* global Compare */ /* global Compare */
/* global CompareAutocomplete */ /* global CompareAutocomplete */
/* global PathLocks */
/* global ProjectNew */ /* global ProjectNew */
/* global ProjectShow */ /* global ProjectShow */
/* global Labels */ /* global Labels */
...@@ -68,6 +70,9 @@ import initExperimentalFlags from './experimental_flags'; ...@@ -68,6 +70,9 @@ import initExperimentalFlags from './experimental_flags';
import OAuthRememberMe from './oauth_remember_me'; import OAuthRememberMe from './oauth_remember_me';
import PerformanceBar from './performance_bar'; import PerformanceBar from './performance_bar';
import GpgBadges from './gpg_badges'; import GpgBadges from './gpg_badges';
import initNotes from './init_notes';
import initLegacyFilters from './init_legacy_filters';
import initIssuableSidebar from './init_issuable_sidebar';
// EE-only // EE-only
import ApproversSelect from './approvers_select'; import ApproversSelect from './approvers_select';
...@@ -166,6 +171,8 @@ import AuditLogs from './audit_logs'; ...@@ -166,6 +171,8 @@ import AuditLogs from './audit_logs';
new Issue(); new Issue();
shortcut_handler = new ShortcutsIssuable(); shortcut_handler = new ShortcutsIssuable();
new ZenMode(); new ZenMode();
initIssuableSidebar();
initNotes();
break; break;
case 'dashboard:milestones:index': case 'dashboard:milestones:index':
new ProjectSelect(); new ProjectSelect();
...@@ -176,10 +183,12 @@ import AuditLogs from './audit_logs'; ...@@ -176,10 +183,12 @@ import AuditLogs from './audit_logs';
new Milestone(); new Milestone();
new Sidebar(); new Sidebar();
break; break;
case 'dashboard:issues':
case 'dashboard:merge_requests':
case 'groups:issues': case 'groups:issues':
case 'groups:merge_requests': case 'groups:merge_requests':
new UsersSelect();
new ProjectSelect(); new ProjectSelect();
initLegacyFilters();
break; break;
case 'dashboard:todos:index': case 'dashboard:todos:index':
new Todos(); new Todos();
...@@ -259,7 +268,10 @@ import AuditLogs from './audit_logs'; ...@@ -259,7 +268,10 @@ import AuditLogs from './audit_logs';
case 'projects:tags:new': case 'projects:tags:new':
new ZenMode(); new ZenMode();
new gl.GLForm($('.tag-form'), true); new gl.GLForm($('.tag-form'), true);
new RefSelectDropdown($('.js-branch-select'), window.gl.availableRefs); new RefSelectDropdown($('.js-branch-select'));
break;
case 'projects:snippets:show':
initNotes();
break; break;
case 'projects:snippets:new': case 'projects:snippets:new':
case 'projects:snippets:edit': case 'projects:snippets:edit':
...@@ -285,15 +297,12 @@ import AuditLogs from './audit_logs'; ...@@ -285,15 +297,12 @@ import AuditLogs from './audit_logs';
window.mergeRequest = new MergeRequest({ window.mergeRequest = new MergeRequest({
action: mrShowNode.dataset.mrAction, action: mrShowNode.dataset.mrAction,
}); });
initIssuableSidebar();
initNotes();
break; break;
case 'dashboard:activity': case 'dashboard:activity':
new gl.Activities(); new gl.Activities();
break; break;
case 'dashboard:issues':
case 'dashboard:merge_requests':
new ProjectSelect();
new UsersSelect();
break;
case 'projects:commit:show': case 'projects:commit:show':
new Commit(); new Commit();
new gl.Diff(); new gl.Diff();
...@@ -302,6 +311,7 @@ import AuditLogs from './audit_logs'; ...@@ -302,6 +311,7 @@ import AuditLogs from './audit_logs';
new MiniPipelineGraph({ new MiniPipelineGraph({
container: '.js-commit-pipeline-graph', container: '.js-commit-pipeline-graph',
}).bindEvents(); }).bindEvents();
initNotes();
break; break;
case 'projects:commit:pipelines': case 'projects:commit:pipelines':
new MiniPipelineGraph({ new MiniPipelineGraph({
...@@ -331,6 +341,9 @@ import AuditLogs from './audit_logs'; ...@@ -331,6 +341,9 @@ import AuditLogs from './audit_logs';
case 'projects:edit': case 'projects:edit':
setupProjectEdit(); setupProjectEdit();
break; break;
case 'projects:pipelines:new':
new NewBranchForm($('.js-new-pipeline-form'));
break;
case 'projects:pipelines:builds': case 'projects:pipelines:builds':
case 'projects:pipelines:failures': case 'projects:pipelines:failures':
case 'projects:pipelines:show': case 'projects:pipelines:show':
...@@ -384,6 +397,17 @@ import AuditLogs from './audit_logs'; ...@@ -384,6 +397,17 @@ import AuditLogs from './audit_logs';
shortcut_handler = new ShortcutsNavigation(); shortcut_handler = new ShortcutsNavigation();
new TreeView(); new TreeView();
new BlobViewer(); new BlobViewer();
if (document.querySelector('.js-tree-content').dataset.pathLocksAvailable === 'true') {
PathLocks.init(
document.querySelector('.js-tree-content').dataset.pathLocksToggle,
document.querySelector('.js-tree-content').dataset.pathLocksPath,
);
}
$('#tree-slider').waitForImages(function() {
gl.utils.ajaxGet(document.querySelector('.js-tree-content').dataset.logsPath);
});
break; break;
case 'projects:find_file:show': case 'projects:find_file:show':
shortcut_handler = true; shortcut_handler = true;
...@@ -401,10 +425,20 @@ import AuditLogs from './audit_logs'; ...@@ -401,10 +425,20 @@ import AuditLogs from './audit_logs';
case 'projects:labels:edit': case 'projects:labels:edit':
new Labels(); new Labels();
break; break;
case 'groups:labels:index':
case 'projects:labels:index': case 'projects:labels:index':
if ($('.prioritized-labels').length) { if ($('.prioritized-labels').length) {
new gl.LabelManager(); new gl.LabelManager();
} }
$('.label-subscription').each((i, el) => {
const $el = $(el);
if ($el.find('.dropdown-group-label').length) {
new gl.GroupLabelSubscription($el);
} else {
new gl.ProjectLabelSubscription($el);
}
});
break; break;
case 'projects:network:show': case 'projects:network:show':
// Ensure we don't create a particular shortcut handler here. This is // Ensure we don't create a particular shortcut handler here. This is
...@@ -460,10 +494,15 @@ import AuditLogs from './audit_logs'; ...@@ -460,10 +494,15 @@ import AuditLogs from './audit_logs';
case 'snippets:show': case 'snippets:show':
new LineHighlighter(); new LineHighlighter();
new BlobViewer(); new BlobViewer();
initNotes();
break; break;
case 'import:fogbugz:new_user_map': case 'import:fogbugz:new_user_map':
new UsersSelect(); new UsersSelect();
break; break;
case 'profiles:personal_access_tokens:index':
case 'admin:impersonation_tokens:index':
new gl.DueDateSelectors();
break;
} }
switch (path.first()) { switch (path.first()) {
case 'sessions': case 'sessions':
...@@ -541,6 +580,7 @@ import AuditLogs from './audit_logs'; ...@@ -541,6 +580,7 @@ import AuditLogs from './audit_logs';
shortcut_handler = new ShortcutsWiki(); shortcut_handler = new ShortcutsWiki();
new ZenMode(); new ZenMode();
new gl.GLForm($('.wiki-form'), true); new gl.GLForm($('.wiki-form'), true);
new Sidebar();
break; break;
case 'snippets': case 'snippets':
shortcut_handler = new ShortcutsNavigation(); shortcut_handler = new ShortcutsNavigation();
......
/* eslint-disable no-new */
/* global MilestoneSelect */
/* global LabelsSelect */
/* global WeightSelect */
/* global IssuableContext */
/* global Sidebar */
export default () => {
const sidebarOptions = JSON.parse(document.querySelector('.js-sidebar-options').innerHTML);
new MilestoneSelect({
full_path: sidebarOptions.fullPath,
});
new LabelsSelect();
new WeightSelect();
new IssuableContext(sidebarOptions.currentUser);
gl.Subscription.bindAll('.subscription');
new gl.DueDateSelectors();
window.sidebar = new Sidebar();
};
/* eslint-disable no-new */
/* global LabelsSelect */
/* global MilestoneSelect */
/* global IssueStatusSelect */
/* global SubscriptionSelect */
/* global WeightSelect */
import UsersSelect from './users_select';
export default () => {
new UsersSelect();
new LabelsSelect();
new MilestoneSelect();
new IssueStatusSelect();
new SubscriptionSelect();
new WeightSelect();
};
/* global Notes */
export default () => {
const dataEl = document.querySelector('.js-notes-data');
const {
notesUrl,
notesIds,
now,
diffView,
autocomplete,
} = JSON.parse(dataEl.innerHTML);
window.notes = new Notes(notesUrl, notesIds, now, diffView, autocomplete);
};
...@@ -53,7 +53,7 @@ export default { ...@@ -53,7 +53,7 @@ export default {
return this.state && this.state.length > 0; return this.state && this.state.length > 0;
}, },
isOpen() { isOpen() {
return this.state === 'opened' || this.state === 'reopened'; return this.state === 'opened';
}, },
isClosed() { isClosed() {
return this.state === 'closed'; return this.state === 'closed';
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
import UsersSelect from './users_select'; import UsersSelect from './users_select';
const PARTICIPANTS_ROW_COUNT = 7;
(function() { (function() {
this.IssuableContext = (function() { this.IssuableContext = (function() {
function IssuableContext(currentUser) { function IssuableContext(currentUser) {
...@@ -50,11 +52,9 @@ import UsersSelect from './users_select'; ...@@ -50,11 +52,9 @@ import UsersSelect from './users_select';
} }
IssuableContext.prototype.initParticipants = function() { IssuableContext.prototype.initParticipants = function() {
var _this;
_this = this;
$(document).on("click", ".js-participants-more", this.toggleHiddenParticipants); $(document).on("click", ".js-participants-more", this.toggleHiddenParticipants);
return $(".js-participants-author").each(function(i) { return $(".js-participants-author").each(function(i) {
if (i >= _this.PARTICIPANTS_ROW_COUNT) { if (i >= PARTICIPANTS_ROW_COUNT) {
return $(this).addClass("js-participants-hidden").hide(); return $(this).addClass("js-participants-hidden").hide();
} }
}); });
......
...@@ -145,7 +145,6 @@ import './right_sidebar'; ...@@ -145,7 +145,6 @@ import './right_sidebar';
import './search'; import './search';
import './search_autocomplete'; import './search_autocomplete';
import './smart_interval'; import './smart_interval';
import './snippets_list';
import './star'; import './star';
import './subscription'; import './subscription';
import './subscription_select'; import './subscription_select';
...@@ -365,4 +364,14 @@ $(function () { ...@@ -365,4 +364,14 @@ $(function () {
gl.utils.renderTimeago(); gl.utils.renderTimeago();
$(document).trigger('init.scrolling-tabs'); $(document).trigger('init.scrolling-tabs');
$('form.filter-form').on('submit', function (event) {
const link = document.createElement('a');
link.href = this.action;
const action = `${this.action}${link.search === '' ? '?' : '&'}`;
event.preventDefault();
gl.utils.visitUrl(`${action}${$(this).serialize()}`);
});
}); });
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
/* global Flash */ /* global Flash */
import Vue from 'vue'; import Vue from 'vue';
import initIssuableSidebar from '../init_issuable_sidebar';
import './merge_conflict_store'; import './merge_conflict_store';
import './merge_conflict_service'; import './merge_conflict_service';
import './mixins/line_conflict_utils'; import './mixins/line_conflict_utils';
...@@ -19,6 +20,8 @@ $(() => { ...@@ -19,6 +20,8 @@ $(() => {
resolveConflictsPath: conflictsEl.dataset.resolveConflictsPath resolveConflictsPath: conflictsEl.dataset.resolveConflictsPath
}); });
initIssuableSidebar();
gl.MergeConflictsResolverApp = new Vue({ gl.MergeConflictsResolverApp = new Vue({
el: '#conflicts', el: '#conflicts',
data: mergeConflictsStore.state, data: mergeConflictsStore.state,
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
var _this, $els; var _this, $els;
if (currentProject != null) { if (currentProject != null) {
_this = this; _this = this;
this.currentProject = JSON.parse(currentProject); this.currentProject = typeof currentProject === 'string' ? JSON.parse(currentProject) : currentProject;
} }
$els = $(els); $els = $(els);
......
import Chart from 'vendor/Chart';
document.addEventListener('DOMContentLoaded', () => {
const chartData = JSON.parse(document.getElementById('pipelinesChartsData').innerHTML);
const buildChart = (chartScope) => {
const data = {
labels: chartScope.labels,
datasets: [{
fillColor: '#7f8fa4',
strokeColor: '#7f8fa4',
pointColor: '#7f8fa4',
pointStrokeColor: '#EEE',
data: chartScope.totalValues,
},
{
fillColor: '#44aa22',
strokeColor: '#44aa22',
pointColor: '#44aa22',
pointStrokeColor: '#fff',
data: chartScope.successValues,
},
],
};
const ctx = $(`#${chartScope.scope}Chart`).get(0).getContext('2d');
const options = {
scaleOverlay: true,
responsive: true,
maintainAspectRatio: false,
};
if (window.innerWidth < 768) {
// Scale fonts if window width lower than 768px (iPad portrait)
options.scaleFontSize = 8;
}
new Chart(ctx).Line(data, options);
};
chartData.forEach(scope => buildChart(scope));
});
import Chart from 'vendor/Chart';
document.addEventListener('DOMContentLoaded', () => {
const chartData = JSON.parse(document.getElementById('pipelinesTimesChartsData').innerHTML);
const data = {
labels: chartData.labels,
datasets: [{
fillColor: 'rgba(220,220,220,0.5)',
strokeColor: 'rgba(220,220,220,1)',
barStrokeWidth: 1,
barValueSpacing: 1,
barDatasetSpacing: 1,
data: chartData.values,
}],
};
const ctx = $('#build_timesChart').get(0).getContext('2d');
const options = {
scaleOverlay: true,
responsive: true,
maintainAspectRatio: false,
};
if (window.innerWidth < 768) {
// Scale fonts if window width lower than 768px (iPad portrait)
options.scaleFontSize = 8;
}
new Chart(ctx).Bar(data, options);
});
...@@ -6,21 +6,27 @@ import Cookies from 'js-cookie'; ...@@ -6,21 +6,27 @@ import Cookies from 'js-cookie';
(function() { (function() {
this.Project = (function() { this.Project = (function() {
function Project() { function Project() {
$('ul.clone-options-dropdown a').click(function() { const $cloneOptions = $('ul.clone-options-dropdown');
var url; const $projectCloneField = $('#project_clone');
if ($(this).hasClass('active')) { const $cloneBtnText = $('a.clone-dropdown-btn span');
return;
} $('a', $cloneOptions).on('click', (e) => {
$('.active').not($(this)).removeClass('active'); const $this = $(e.currentTarget);
$(this).toggleClass('active'); const url = $this.attr('href');
url = $("#project_clone").val();
$('#project_clone').val(url); e.preventDefault();
$('.active', $cloneOptions).not($this).removeClass('active');
$this.toggleClass('active');
$projectCloneField.val(url);
$cloneBtnText.text($this.text());
$('#modal-geo-info').data({
cloneUrlSecondary: $this.attr('href'),
cloneUrlPrimary: $this.data('primaryUrl') || ''
});
return $('.clone').text(url); return $('.clone').text(url);
// Git protocol switcher
// Remove the active class for all buttons (ssh, http, kerberos if shown)
// Add the active class for the clicked button
// Update the input field
// Update the command line instructions
}); });
// Ref switcher // Ref switcher
this.initRefSwitcher(); this.initRefSwitcher();
......
document.addEventListener('DOMContentLoaded', () => {
const importBtnTooltip = 'Please enter a valid project name.';
const $importBtnWrapper = $('.import_gitlab_project');
$('.how_to_import_link').on('click', (e) => {
e.preventDefault();
$('.how_to_import_link').next('.modal').show();
});
$('.modal-header .close').on('click', () => {
$('.modal').hide();
});
$('.btn_import_gitlab_project').on('click', () => {
const importHref = $('a.btn_import_gitlab_project').attr('href');
$('.btn_import_gitlab_project').attr('href', `${importHref}?namespace_id=${$('#project_namespace_id').val()}&path=${$('#project_path').val()}`);
});
$('.btn_import_gitlab_project').attr('disabled', !$('#project_path').val().trim().length);
$importBtnWrapper.attr('title', importBtnTooltip);
$('#new_project').on('submit', () => {
const $path = $('#project_path');
$path.val($path.val().trim());
});
$('#project_path').on('keyup', () => {
if ($('#project_path').val().trim().length) {
$('.btn_import_gitlab_project').attr('disabled', false);
$importBtnWrapper.attr('title', '');
$importBtnWrapper.removeClass('has-tooltip');
} else {
$('.btn_import_gitlab_project').attr('disabled', true);
$importBtnWrapper.addClass('has-tooltip');
}
});
$('#project_import_url').disable();
$('.import_git').on('click', () => {
const $projectImportUrl = $('#project_import_url');
$projectImportUrl.attr('disabled', !$projectImportUrl.attr('disabled'));
});
});
class RefSelectDropdown { class RefSelectDropdown {
constructor($dropdownButton, availableRefs) { constructor($dropdownButton, availableRefs) {
const availableRefsValue = availableRefs || JSON.parse(document.getElementById('availableRefs').innerHTML);
$dropdownButton.glDropdown({ $dropdownButton.glDropdown({
data: availableRefs, data: availableRefsValue,
filterable: true, filterable: true,
filterByText: true, filterByText: true,
remote: false, remote: false,
......
...@@ -5,7 +5,8 @@ import sidebarAssignees from './components/assignees/sidebar_assignees'; ...@@ -5,7 +5,8 @@ import sidebarAssignees from './components/assignees/sidebar_assignees';
import Mediator from './sidebar_mediator'; import Mediator from './sidebar_mediator';
function domContentLoaded() { function domContentLoaded() {
const mediator = new Mediator(gl.sidebarOptions); const sidebarOptions = JSON.parse(document.querySelector('.js-sidebar-options').innerHTML);
const mediator = new Mediator(sidebarOptions);
mediator.fetch(); mediator.fetch();
const sidebarAssigneesEl = document.querySelector('#js-vue-sidebar-assignees'); const sidebarAssigneesEl = document.querySelector('#js-vue-sidebar-assignees');
......
function SnippetsList() {
const $holder = $('.snippets-list-holder');
$holder.find('.pagination').on('ajax:success', (e, data) => {
$holder.replaceWith(data.html);
});
}
window.gl.SnippetsList = SnippetsList;
...@@ -37,10 +37,6 @@ export default class Todos { ...@@ -37,10 +37,6 @@ export default class Todos {
this.initFilterDropdown($('.js-type-search'), 'type'); this.initFilterDropdown($('.js-type-search'), 'type');
this.initFilterDropdown($('.js-action-search'), 'action_id'); this.initFilterDropdown($('.js-action-search'), 'action_id');
$('form.filter-form').on('submit', function applyFilters(event) {
event.preventDefault();
gl.utils.visitUrl(`${this.action}&${$(this).serialize()}`);
});
return new UsersSelect(); return new UsersSelect();
} }
......
...@@ -67,7 +67,7 @@ export default class MergeRequestStore { ...@@ -67,7 +67,7 @@ export default class MergeRequestStore {
this.mergeCheckPath = data.merge_check_path; this.mergeCheckPath = data.merge_check_path;
this.mergeActionsContentPath = data.commit_change_content_path; this.mergeActionsContentPath = data.commit_change_content_path;
this.isRemovingSourceBranch = this.isRemovingSourceBranch || false; this.isRemovingSourceBranch = this.isRemovingSourceBranch || false;
this.isOpen = data.state === 'opened' || data.state === 'reopened' || false; this.isOpen = data.state === 'opened';
this.hasMergeableDiscussionsState = data.mergeable_discussions_state === false; this.hasMergeableDiscussionsState = data.mergeable_discussions_state === false;
this.canRemoveSourceBranch = currentUser.can_remove_source_branch || false; this.canRemoveSourceBranch = currentUser.can_remove_source_branch || false;
this.canMerge = !!data.merge_path; this.canMerge = !!data.merge_path;
......
...@@ -315,6 +315,10 @@ header { ...@@ -315,6 +315,10 @@ header {
} }
} }
.with-performance-bar header.navbar-gitlab {
top: $performance-bar-height;
}
.navbar-nav { .navbar-nav {
li { li {
.badge { .badge {
......
...@@ -120,3 +120,7 @@ of the body element here, we negate cascading side effects but allow momentum sc ...@@ -120,3 +120,7 @@ of the body element here, we negate cascading side effects but allow momentum sc
.page-with-sidebar { .page-with-sidebar {
-webkit-overflow-scrolling: auto; -webkit-overflow-scrolling: auto;
} }
.with-performance-bar .page-with-sidebar {
margin-top: $header-height + $performance-bar-height;
}
...@@ -374,6 +374,10 @@ ...@@ -374,6 +374,10 @@
} }
} }
.with-performance-bar .layout-nav {
margin-top: $header-height + $performance-bar-height;
}
.scrolling-tabs-container { .scrolling-tabs-container {
position: relative; position: relative;
...@@ -468,6 +472,22 @@ ...@@ -468,6 +472,22 @@
} }
} }
.with-performance-bar .page-with-layout-nav {
.right-sidebar {
top: ($header-height + 1) * 2 + $performance-bar-height;
}
&.page-with-sub-nav {
.right-sidebar {
top: ($header-height + 1) * 3 + $performance-bar-height;
&.affix {
top: $header-height + $performance-bar-height;
}
}
}
}
.nav-block { .nav-block {
&.activities { &.activities {
border-bottom: 1px solid $border-color; border-bottom: 1px solid $border-color;
......
...@@ -89,6 +89,10 @@ ...@@ -89,6 +89,10 @@
} }
} }
.with-performance-bar .right-sidebar.affix {
top: $header-height + $performance-bar-height;
}
@mixin maintain-sidebar-dimensions { @mixin maintain-sidebar-dimensions {
display: block; display: block;
width: $gutter-width; width: $gutter-width;
......
...@@ -205,6 +205,8 @@ $divergence-graph-separator-bg: #ccc; ...@@ -205,6 +205,8 @@ $divergence-graph-separator-bg: #ccc;
$general-hover-transition-duration: 100ms; $general-hover-transition-duration: 100ms;
$general-hover-transition-curve: linear; $general-hover-transition-curve: linear;
$highlight-changes-color: rgb(235, 255, 232); $highlight-changes-color: rgb(235, 255, 232);
$performance-bar-height: 35px;
$issue-box-upcoming-bg: #8f8f8f; $issue-box-upcoming-bg: #8f8f8f;
$pages-group-name-color: #4c4e54; $pages-group-name-color: #4c4e54;
$ldap-members-override-bg: $orange-50; $ldap-members-override-bg: $orange-50;
......
...@@ -118,7 +118,7 @@ $new-sidebar-width: 220px; ...@@ -118,7 +118,7 @@ $new-sidebar-width: 220px;
z-index: 400; z-index: 400;
width: $new-sidebar-width; width: $new-sidebar-width;
transition: left $sidebar-transition-duration; transition: left $sidebar-transition-duration;
top: 50px; top: $header-height;
bottom: 0; bottom: 0;
left: 0; left: 0;
overflow: auto; overflow: auto;
...@@ -163,6 +163,10 @@ $new-sidebar-width: 220px; ...@@ -163,6 +163,10 @@ $new-sidebar-width: 220px;
} }
} }
.with-performance-bar .nav-sidebar {
top: $header-height + $performance-bar-height;
}
.sidebar-sub-level-items { .sidebar-sub-level-items {
display: none; display: none;
padding-bottom: 8px; padding-bottom: 8px;
...@@ -260,7 +264,7 @@ $new-sidebar-width: 220px; ...@@ -260,7 +264,7 @@ $new-sidebar-width: 220px;
// Make issue boards full-height now that sub-nav is gone // Make issue boards full-height now that sub-nav is gone
.boards-list { .boards-list {
height: calc(100vh - 50px); height: calc(100vh - #{$header-height});
@media (min-width: $screen-sm-min) { @media (min-width: $screen-sm-min) {
height: 475px; // Needed for PhantomJS height: 475px; // Needed for PhantomJS
...@@ -270,6 +274,10 @@ $new-sidebar-width: 220px; ...@@ -270,6 +274,10 @@ $new-sidebar-width: 220px;
} }
} }
.with-performance-bar .boards-list {
height: calc(100vh - #{$header-height} - #{$performance-bar-height});
}
// Change color of all horizontal tabs to match the new indigo color // Change color of all horizontal tabs to match the new indigo color
.nav-links li.active a { .nav-links li.active a {
......
...@@ -64,10 +64,10 @@ ...@@ -64,10 +64,10 @@
color: $gl-text-color; color: $gl-text-color;
position: sticky; position: sticky;
position: -webkit-sticky; position: -webkit-sticky;
top: 50px; top: $header-height;
&.affix { &.affix {
top: 50px; top: $header-height;
} }
// with sidebar // with sidebar
...@@ -171,6 +171,16 @@ ...@@ -171,6 +171,16 @@
} }
} }
.with-performance-bar .build-page {
.top-bar {
top: $header-height + $performance-bar-height;
&.affix {
top: $header-height + $performance-bar-height;
}
}
}
.build-header { .build-header {
.ci-header-container, .ci-header-container,
.header-action-buttons { .header-action-buttons {
......
...@@ -445,6 +445,14 @@ ...@@ -445,6 +445,14 @@
} }
} }
.with-performance-bar .right-sidebar {
top: $header-height + $performance-bar-height;
.issuable-sidebar {
height: calc(100% - #{$header-height} - #{$performance-bar-height});
}
}
.detail-page-description { .detail-page-description {
padding: 16px 0; padding: 16px 0;
......
...@@ -759,6 +759,10 @@ ...@@ -759,6 +759,10 @@
} }
} }
.with-performance-bar .merge-request-tabs-holder {
top: $header-height + $performance-bar-height;
}
.merge-request-tabs { .merge-request-tabs {
display: flex; display: flex;
margin-bottom: 0; margin-bottom: 0;
......
...@@ -3,9 +3,16 @@ ...@@ -3,9 +3,16 @@
@import "peek/views/rblineprof"; @import "peek/views/rblineprof";
#peek { #peek {
height: 35px; position: fixed;
left: 0;
top: 0;
width: 100%;
z-index: 2000;
overflow-x: hidden;
height: $performance-bar-height;
background: $black; background: $black;
line-height: 35px; line-height: $performance-bar-height;
color: $perf-bar-text; color: $perf-bar-text;
&.disabled { &.disabled {
...@@ -25,7 +32,8 @@ ...@@ -25,7 +32,8 @@
} }
.wrapper { .wrapper {
width: 1000px; width: 80%;
height: $performance-bar-height;
margin: 0 auto; margin: 0 auto;
} }
......
...@@ -2,6 +2,7 @@ class Groups::LdapGroupLinksController < Groups::ApplicationController ...@@ -2,6 +2,7 @@ class Groups::LdapGroupLinksController < Groups::ApplicationController
before_action :group before_action :group
before_action :require_ldap_enabled before_action :require_ldap_enabled
before_action :authorize_admin_group! before_action :authorize_admin_group!
before_action :authorize_manage_ldap_group_links!
layout 'group_settings' layout 'group_settings'
...@@ -31,6 +32,12 @@ class Groups::LdapGroupLinksController < Groups::ApplicationController ...@@ -31,6 +32,12 @@ class Groups::LdapGroupLinksController < Groups::ApplicationController
private private
def authorize_manage_ldap_group_links!
unless can?(current_user, :admin_ldap_group_links, group)
return render_404
end
end
def require_ldap_enabled def require_ldap_enabled
render_404 unless Gitlab.config.ldap.enabled render_404 unless Gitlab.config.ldap.enabled
end end
......
...@@ -86,7 +86,6 @@ class IssuableFinder ...@@ -86,7 +86,6 @@ class IssuableFinder
end end
counts[:all] = counts.values.sum counts[:all] = counts.values.sum
counts[:opened] += counts[:reopened]
counts.with_indifferent_access counts.with_indifferent_access
end end
......
...@@ -268,7 +268,11 @@ module ApplicationHelper ...@@ -268,7 +268,11 @@ module ApplicationHelper
end end
def page_class def page_class
"issue-boards-page" if current_controller?(:boards) class_names = []
class_names << 'issue-boards-page' if current_controller?(:boards)
class_names << 'with-performance-bar' if performance_bar_enabled?
class_names
end end
# Returns active css class when condition returns true # Returns active css class when condition returns true
......
...@@ -21,7 +21,8 @@ module EE ...@@ -21,7 +21,8 @@ module EE
:slack_app_enabled, :slack_app_enabled,
:slack_app_id, :slack_app_id,
:slack_app_secret, :slack_app_secret,
:slack_app_verification_token :slack_app_verification_token,
:allow_group_owners_to_manage_ldap
] ]
end end
......
...@@ -362,4 +362,14 @@ module IssuablesHelper ...@@ -362,4 +362,14 @@ module IssuablesHelper
params[:format] = :json if issuable.is_a?(Issue) params[:format] = :json if issuable.is_a?(Issue)
end end
end end
def issuable_sidebar_options(issuable, can_edit_issuable)
{
endpoint: "#{issuable_json_path(issuable)}?basic=true",
editable: can_edit_issuable,
currentUser: current_user.as_json(only: [:username, :id, :name], methods: :avatar_url),
rootPath: root_path,
fullPath: @project.full_path
}
end
end end
module MembersHelper module MembersHelper
# Returns a `<action>_<source>_member` association, e.g.: # Returns a `<action>_<source>_member` association, e.g.:
# - admin_project_member, update_project_member, destroy_project_member # - admin_project_member, update_project_member, destroy_project_member
# - admin_group_member, update_group_member, destroy_group_member # - admin_group_member, update_group_member, destroy_group_member, override_group_member
def action_member_permission(action, member) def action_member_permission(action, member)
"#{action}_#{member.type.underscore}".to_sym "#{action}_#{member.type.underscore}".to_sym
end end
......
module NavHelper module NavHelper
def page_with_sidebar_class
class_name = page_gutter_class
class_name << 'page-with-new-sidebar' if defined?(@new_sidebar) && @new_sidebar
class_name
end
def page_gutter_class def page_gutter_class
if current_path?('merge_requests#show') || if current_path?('merge_requests#show') ||
current_path?('projects/merge_requests/conflicts#show') || current_path?('projects/merge_requests/conflicts#show') ||
current_path?('issues#show') || current_path?('issues#show') ||
current_path?('milestones#show') current_path?('milestones#show')
if cookies[:collapsed_gutter] == 'true' if cookies[:collapsed_gutter] == 'true'
"page-gutter right-sidebar-collapsed" %w[page-gutter right-sidebar-collapsed]
else else
"page-gutter right-sidebar-expanded" %w[page-gutter right-sidebar-expanded]
end end
elsif current_path?('jobs#show') elsif current_path?('jobs#show')
"page-gutter build-sidebar right-sidebar-expanded" %w[page-gutter build-sidebar right-sidebar-expanded]
elsif current_path?('wikis#show') || elsif current_path?('wikis#show') ||
current_path?('wikis#edit') || current_path?('wikis#edit') ||
current_path?('wikis#update') || current_path?('wikis#update') ||
current_path?('wikis#history') || current_path?('wikis#history') ||
current_path?('wikis#git_access') current_path?('wikis#git_access')
"page-gutter wiki-sidebar right-sidebar-expanded" %w[page-gutter wiki-sidebar right-sidebar-expanded]
else
[]
end end
end end
def nav_header_class def nav_header_class
class_name = '' class_names = []
class_name << " with-horizontal-nav" if defined?(nav) && nav class_names << 'with-horizontal-nav' if defined?(nav) && nav
class_name class_names
end end
def layout_nav_class def layout_nav_class
class_name = '' return [] if show_new_nav?
class_name << " page-with-layout-nav" if defined?(nav) && nav
class_name << " page-with-sub-nav" if content_for?(:sub_nav)
class_name class_names = []
class_names << 'page-with-layout-nav' if defined?(nav) && nav
class_names << 'page-with-sub-nav' if content_for?(:sub_nav)
class_names
end end
def nav_control_class def nav_control_class
......
...@@ -130,4 +130,14 @@ module NotesHelper ...@@ -130,4 +130,14 @@ module NotesHelper
can?(current_user, :create_note, @project) can?(current_user, :create_note, @project)
end end
end end
def initial_notes_data(autocomplete)
{
notesUrl: notes_url,
notesIds: @notes.map(&:id),
now: Time.now.to_i,
diffView: diff_view,
autocomplete: autocomplete
}
end
end end
class Burndown class Burndown
Issue = Struct.new(:closed_at, :weight, :state) class Issue
attr_reader :closed_at, :weight, :state
def initialize(closed_at, weight, state)
@closed_at = closed_at
@weight = weight
@state = state
end
def reopened?
@state == 'opened' && @closed_at.present?
end
end
attr_reader :start_date, :due_date, :end_date, :issues_count, :issues_weight, :accurate, :legacy_data attr_reader :start_date, :due_date, :end_date, :issues_count, :issues_weight, :accurate, :legacy_data
alias_method :accurate?, :accurate alias_method :accurate?, :accurate
...@@ -12,8 +24,8 @@ class Burndown ...@@ -12,8 +24,8 @@ class Burndown
@end_date = @milestone.due_date @end_date = @milestone.due_date
@end_date = Date.today if @end_date.present? && @end_date > Date.today @end_date = Date.today if @end_date.present? && @end_date > Date.today
@accurate = milestone_closed_issues.all?(&:closed_at) @accurate = milestone_issues.all?(&:closed_at)
@legacy_data = milestone_closed_issues.any? && milestone_closed_issues.none?(&:closed_at) @legacy_data = milestone_issues.any? && milestone_issues.none?(&:closed_at)
@issues_count, @issues_weight = milestone.issues.reorder(nil).pluck('COUNT(*), COALESCE(SUM(weight), 0)').first @issues_count, @issues_weight = milestone.issues.reorder(nil).pluck('COUNT(*), COALESCE(SUM(weight), 0)').first
end end
...@@ -59,21 +71,21 @@ class Burndown ...@@ -59,21 +71,21 @@ class Burndown
current_date = date.to_date current_date = date.to_date
closed = closed =
milestone_closed_issues.select do |issue| milestone_issues.select do |issue|
(issue.closed_at&.to_date || start_date) == current_date (issue.closed_at&.to_date || start_date) == current_date
end end
reopened = closed.select { |issue| issue.state == 'reopened' } reopened = closed.select(&:reopened?)
[closed, reopened] [closed, reopened]
end end
def milestone_closed_issues def milestone_issues
@milestone_closed_issues ||= @milestone_issues ||=
@milestone.issues @milestone.issues
.where("state IN ('reopened', 'closed')") .where("state = 'closed' OR (state = 'opened' AND closed_at IS NOT NULL)")
.order("closed_at ASC") .reorder("closed_at ASC")
.pluck("closed_at, weight, state") .pluck("closed_at, weight, state")
.map {|attrs| ::Burndown::Issue.new(*attrs) } .map {|attrs| Issue.new(*attrs) }
end end
end end
...@@ -223,6 +223,7 @@ module Ci ...@@ -223,6 +223,7 @@ module Ci
variables += project.group.secret_variables_for(ref, project).map(&:to_runner_variable) if project.group variables += project.group.secret_variables_for(ref, project).map(&:to_runner_variable) if project.group
variables += secret_variables(environment: environment) variables += secret_variables(environment: environment)
variables += trigger_request.user_variables if trigger_request variables += trigger_request.user_variables if trigger_request
variables += pipeline.variables.map(&:to_runner_variable)
variables += pipeline.pipeline_schedule.job_variables if pipeline.pipeline_schedule variables += pipeline.pipeline_schedule.job_variables if pipeline.pipeline_schedule
variables += persisted_environment_variables if environment variables += persisted_environment_variables if environment
......
...@@ -27,6 +27,7 @@ module Ci ...@@ -27,6 +27,7 @@ module Ci
has_many :statuses, class_name: 'CommitStatus', foreign_key: :commit_id has_many :statuses, class_name: 'CommitStatus', foreign_key: :commit_id
has_many :builds, foreign_key: :commit_id has_many :builds, foreign_key: :commit_id
has_many :trigger_requests, dependent: :destroy, foreign_key: :commit_id # rubocop:disable Cop/ActiveRecordDependent has_many :trigger_requests, dependent: :destroy, foreign_key: :commit_id # rubocop:disable Cop/ActiveRecordDependent
has_many :variables, class_name: 'Ci::PipelineVariable'
# Merge requests for which the current pipeline is running against # Merge requests for which the current pipeline is running against
# the merge request's latest commit. # the merge request's latest commit.
......
module Ci
class PipelineVariable < ActiveRecord::Base
extend Ci::Model
include HasVariable
belongs_to :pipeline
validates :key, uniqueness: { scope: :pipeline_id }
end
end
...@@ -71,9 +71,8 @@ module Issuable ...@@ -71,9 +71,8 @@ module Issuable
scope :of_projects, ->(ids) { where(project_id: ids) } scope :of_projects, ->(ids) { where(project_id: ids) }
scope :of_milestones, ->(ids) { where(milestone_id: ids) } scope :of_milestones, ->(ids) { where(milestone_id: ids) }
scope :with_milestone, ->(title) { left_joins_milestones.where(milestones: { title: title }) } scope :with_milestone, ->(title) { left_joins_milestones.where(milestones: { title: title }) }
scope :opened, -> { with_state(:opened, :reopened) } scope :opened, -> { with_state(:opened) }
scope :only_opened, -> { with_state(:opened) } scope :only_opened, -> { with_state(:opened) }
scope :only_reopened, -> { with_state(:reopened) }
scope :closed, -> { with_state(:closed) } scope :closed, -> { with_state(:closed) }
scope :order_milestone_due_desc, -> { outer_join_milestone.reorder('milestones.due_date IS NULL ASC, milestones.due_date DESC, milestones.id DESC') } scope :order_milestone_due_desc, -> { outer_join_milestone.reorder('milestones.due_date IS NULL ASC, milestones.due_date DESC, milestones.id DESC') }
scope :order_milestone_due_asc, -> { outer_join_milestone.reorder('milestones.due_date IS NULL ASC, milestones.due_date ASC, milestones.id ASC') } scope :order_milestone_due_asc, -> { outer_join_milestone.reorder('milestones.due_date IS NULL ASC, milestones.due_date ASC, milestones.id ASC') }
...@@ -241,7 +240,7 @@ module Issuable ...@@ -241,7 +240,7 @@ module Issuable
end end
def open? def open?
opened? || reopened? opened?
end end
def user_notes_count def user_notes_count
......
...@@ -39,7 +39,8 @@ module EE ...@@ -39,7 +39,8 @@ module EE
repository_size_limit: 0, repository_size_limit: 0,
mirror_max_delay: Settings.gitlab['mirror_max_delay'], mirror_max_delay: Settings.gitlab['mirror_max_delay'],
mirror_max_capacity: Settings.gitlab['mirror_max_capacity'], mirror_max_capacity: Settings.gitlab['mirror_max_capacity'],
mirror_capacity_threshold: Settings.gitlab['mirror_capacity_threshold'] mirror_capacity_threshold: Settings.gitlab['mirror_capacity_threshold'],
allow_group_owners_to_manage_ldap: true
) )
end end
end end
......
...@@ -73,15 +73,14 @@ class Issue < ActiveRecord::Base ...@@ -73,15 +73,14 @@ class Issue < ActiveRecord::Base
state_machine :state, initial: :opened do state_machine :state, initial: :opened do
event :close do event :close do
transition [:reopened, :opened] => :closed transition [:opened] => :closed
end end
event :reopen do event :reopen do
transition closed: :reopened transition closed: :opened
end end
state :opened state :opened
state :reopened
state :closed state :closed
before_transition any => :closed do |issue| before_transition any => :closed do |issue|
......
...@@ -45,23 +45,23 @@ class MergeRequest < ActiveRecord::Base ...@@ -45,23 +45,23 @@ class MergeRequest < ActiveRecord::Base
state_machine :state, initial: :opened do state_machine :state, initial: :opened do
event :close do event :close do
transition [:reopened, :opened] => :closed transition [:opened] => :closed
end end
event :mark_as_merged do event :mark_as_merged do
transition [:reopened, :opened, :locked] => :merged transition [:opened, :locked] => :merged
end end
event :reopen do event :reopen do
transition closed: :reopened transition closed: :opened
end end
event :lock_mr do event :lock_mr do
transition [:reopened, :opened] => :locked transition [:opened] => :locked
end end
event :unlock_mr do event :unlock_mr do
transition locked: :reopened transition locked: :opened
end end
after_transition any => :locked do |merge_request, transition| after_transition any => :locked do |merge_request, transition|
...@@ -75,7 +75,6 @@ class MergeRequest < ActiveRecord::Base ...@@ -75,7 +75,6 @@ class MergeRequest < ActiveRecord::Base
end end
state :opened state :opened
state :reopened
state :closed state :closed
state :merged state :merged
state :locked state :locked
...@@ -372,7 +371,7 @@ class MergeRequest < ActiveRecord::Base ...@@ -372,7 +371,7 @@ class MergeRequest < ActiveRecord::Base
errors.add :branch_conflict, "You can not use same project/branch for source and target" errors.add :branch_conflict, "You can not use same project/branch for source and target"
end end
if opened? || reopened? if opened?
similar_mrs = self.target_project.merge_requests.where(source_branch: source_branch, target_branch: target_branch, source_project_id: source_project.try(:id)).opened similar_mrs = self.target_project.merge_requests.where(source_branch: source_branch, target_branch: target_branch, source_project_id: source_project.try(:id)).opened
similar_mrs = similar_mrs.where('id not in (?)', self.id) if self.id similar_mrs = similar_mrs.where('id not in (?)', self.id) if self.id
if similar_mrs.any? if similar_mrs.any?
......
...@@ -114,7 +114,7 @@ class DroneCiService < CiService ...@@ -114,7 +114,7 @@ class DroneCiService < CiService
end end
def merge_request_valid?(data) def merge_request_valid?(data)
%w(opened reopened).include?(data[:object_attributes][:state]) && data[:object_attributes][:state] == 'opened' &&
data[:object_attributes][:merge_status] == 'unchecked' data[:object_attributes][:merge_status] == 'unchecked'
end end
end end
...@@ -6,19 +6,19 @@ module EE ...@@ -6,19 +6,19 @@ module EE
with_scope :subject with_scope :subject
condition(:ldap_synced) { @subject.ldap_synced? } condition(:ldap_synced) { @subject.ldap_synced? }
rule { ldap_synced }.prevent :admin_group_member condition(:can_owners_manage_ldap, scope: :global) do
current_application_settings.allow_group_owners_to_manage_ldap
rule { ldap_synced & admin }.policy do
enable :override_group_member
enable :update_group_member
end
rule { ldap_synced & owner }.policy do
enable :override_group_member
enable :update_group_member
end end
rule { auditor }.enable :read_group rule { auditor }.enable :read_group
rule { admin | (can_owners_manage_ldap & owner) }.enable :admin_ldap_group_links
rule { ldap_synced }.prevent :admin_group_member
rule { ldap_synced & (admin | owner) }.enable :update_group_member
rule { ldap_synced & (admin | (can_owners_manage_ldap & owner)) }.enable :override_group_member
end end
end end
end end
...@@ -2,7 +2,7 @@ module Ci ...@@ -2,7 +2,7 @@ module Ci
class CreatePipelineService < BaseService class CreatePipelineService < BaseService
attr_reader :pipeline attr_reader :pipeline
def execute(source, ignore_skip_ci: false, save_on_errors: true, trigger_request: nil, schedule: nil, mirror_update: false, &block) def execute(source, ignore_skip_ci: false, save_on_errors: true, trigger_request: nil, schedule: nil, mirror_update: false)
@pipeline = Ci::Pipeline.new( @pipeline = Ci::Pipeline.new(
source: source, source: source,
project: project, project: project,
...@@ -22,7 +22,27 @@ module Ci ...@@ -22,7 +22,27 @@ module Ci
return result if result return result if result
_create_pipeline(source, &block) begin
Ci::Pipeline.transaction do
pipeline.save!
yield(pipeline) if block_given?
Ci::CreatePipelineStagesService
.new(project, current_user)
.execute(pipeline)
end
rescue ActiveRecord::RecordInvalid => e
return error("Failed to persist the pipeline: #{e}")
end
update_merge_requests_head_pipeline
cancel_pending_pipelines if project.auto_cancel_pending_pipelines?
pipeline_created_counter.increment(source: source)
pipeline.tap(&:process!)
end end
private private
...@@ -69,24 +89,6 @@ module Ci ...@@ -69,24 +89,6 @@ module Ci
end end
end end
def _create_pipeline(source)
Ci::Pipeline.transaction do
update_merge_requests_head_pipeline if pipeline.save
yield(pipeline) if block_given?
Ci::CreatePipelineStagesService
.new(project, current_user)
.execute(pipeline)
end
cancel_pending_pipelines if project.auto_cancel_pending_pipelines?
pipeline_created_counter.increment(source: source)
pipeline.tap(&:process!)
end
def allowed_to_trigger_pipeline?(triggering_user) def allowed_to_trigger_pipeline?(triggering_user)
if triggering_user if triggering_user
allowed_to_create?(triggering_user) allowed_to_create?(triggering_user)
......
# This class is deprecated because we're closing Ci::TriggerRequest.
# New class is PipelineTriggerService (app/services/ci/pipeline_trigger_service.rb)
# which is integrated with Ci::PipelineVariable instaed of Ci::TriggerRequest.
# We remove this class after we removed v1 and v3 API. This class is still being
# referred by such legacy code.
module Ci module Ci
module CreateTriggerRequestService module CreateTriggerRequestService
Result = Struct.new(:trigger_request, :pipeline) Result = Struct.new(:trigger_request, :pipeline)
......
...@@ -14,9 +14,11 @@ module Ci ...@@ -14,9 +14,11 @@ module Ci
# this check is to not leak the presence of the project if user cannot read it # this check is to not leak the presence of the project if user cannot read it
return unless trigger.project == project return unless trigger.project == project
trigger_request = trigger.trigger_requests.create(variables: params[:variables])
pipeline = Ci::CreatePipelineService.new(project, trigger.owner, ref: params[:ref]) pipeline = Ci::CreatePipelineService.new(project, trigger.owner, ref: params[:ref])
.execute(:trigger, ignore_skip_ci: true, trigger_request: trigger_request) .execute(:trigger, ignore_skip_ci: true) do |pipeline|
trigger.trigger_requests.create!(pipeline: pipeline)
create_pipeline_variables!(pipeline)
end
if pipeline.persisted? if pipeline.persisted?
success(pipeline: pipeline) success(pipeline: pipeline)
...@@ -47,17 +49,27 @@ module Ci ...@@ -47,17 +49,27 @@ module Ci
error(pipeline.errors.messages, 400) error(pipeline.errors.messages, 400)
end end
end end
def trigger_from_token def trigger_from_token
return @trigger if defined?(@trigger) return @trigger if defined?(@trigger)
@trigger = Ci::Trigger.find_by_token(params[:token].to_s) @trigger = Ci::Trigger.find_by_token(params[:token].to_s)
end end
def job_from_token def job_from_token
return @job if defined?(@job) return @job if defined?(@job)
@job = Ci::Build.find_by_token(params[:token].to_s) @job = Ci::Build.find_by_token(params[:token].to_s)
end end
def create_pipeline_variables!(pipeline)
return unless params[:variables]
variables = params[:variables].map do |key, value|
{ key: key, value: value }
end
pipeline.variables.create!(variables)
end
end end
end end
...@@ -5,7 +5,7 @@ module Issues ...@@ -5,7 +5,7 @@ module Issues
if issue.reopen if issue.reopen
event_service.reopen_issue(issue, current_user) event_service.reopen_issue(issue, current_user)
create_note(issue) create_note(issue, 'reopened')
notification_service.reopen_issue(issue, current_user) notification_service.reopen_issue(issue, current_user)
execute_hooks(issue, 'reopen') execute_hooks(issue, 'reopen')
invalidate_cache_counts(issue, users: issue.assignees) invalidate_cache_counts(issue, users: issue.assignees)
...@@ -16,8 +16,8 @@ module Issues ...@@ -16,8 +16,8 @@ module Issues
private private
def create_note(issue) def create_note(issue, state = issue.state)
SystemNoteService.change_status(issue, issue.project, current_user, issue.state, nil) SystemNoteService.change_status(issue, issue.project, current_user, state, nil)
end end
end end
end end
...@@ -2,8 +2,8 @@ module MergeRequests ...@@ -2,8 +2,8 @@ module MergeRequests
class BaseService < ::IssuableBaseService class BaseService < ::IssuableBaseService
prepend EE::MergeRequests::BaseService prepend EE::MergeRequests::BaseService
def create_note(merge_request) def create_note(merge_request, state = merge_request.state)
SystemNoteService.change_status(merge_request, merge_request.target_project, current_user, merge_request.state, nil) SystemNoteService.change_status(merge_request, merge_request.target_project, current_user, state, nil)
end end
def create_title_change_note(issuable, old_title) def create_title_change_note(issuable, old_title)
...@@ -46,7 +46,7 @@ module MergeRequests ...@@ -46,7 +46,7 @@ module MergeRequests
end end
# Returns all origin and fork merge requests from `@project` satisfying passed arguments. # Returns all origin and fork merge requests from `@project` satisfying passed arguments.
def merge_requests_for(source_branch, mr_states: [:opened, :reopened]) def merge_requests_for(source_branch, mr_states: [:opened])
MergeRequest MergeRequest
.with_state(mr_states) .with_state(mr_states)
.where(source_branch: source_branch, source_project_id: @project.id) .where(source_branch: source_branch, source_project_id: @project.id)
......
...@@ -82,7 +82,7 @@ module MergeRequests ...@@ -82,7 +82,7 @@ module MergeRequests
# Note: Closed merge requests also need approvals reset. # Note: Closed merge requests also need approvals reset.
def reset_approvals_for_merge_requests def reset_approvals_for_merge_requests
merge_requests = merge_requests_for(@branch_name, mr_states: [:opened, :reopened, :closed]) merge_requests = merge_requests_for(@branch_name, mr_states: [:opened, :closed])
merge_requests.each do |merge_request| merge_requests.each do |merge_request|
target_project = merge_request.target_project target_project = merge_request.target_project
......
...@@ -5,7 +5,7 @@ module MergeRequests ...@@ -5,7 +5,7 @@ module MergeRequests
if merge_request.reopen if merge_request.reopen
event_service.reopen_mr(merge_request, current_user) event_service.reopen_mr(merge_request, current_user)
create_note(merge_request) create_note(merge_request, 'reopened')
notification_service.reopen_mr(merge_request, current_user) notification_service.reopen_mr(merge_request, current_user)
execute_hooks(merge_request, 'reopen') execute_hooks(merge_request, 'reopen')
merge_request.reload_diff(current_user) merge_request.reload_diff(current_user)
......
...@@ -48,6 +48,17 @@ ...@@ -48,6 +48,17 @@
= select(:application_setting, :enabled_git_access_protocol, [['Both SSH and HTTP(S)', nil], ['Only SSH', 'ssh'], ['Only HTTP(S)', 'http']], {}, class: 'form-control') = select(:application_setting, :enabled_git_access_protocol, [['Both SSH and HTTP(S)', nil], ['Only SSH', 'ssh'], ['Only HTTP(S)', 'http']], {}, class: 'form-control')
%span.help-block#clone-protocol-help %span.help-block#clone-protocol-help
Allow only the selected protocols to be used for Git access. Allow only the selected protocols to be used for Git access.
- if ldap_enabled?
.form-group
= f.label :allow_group_owners_to_manage_ldap, 'LDAP settings', class: 'control-label col-sm-2'
.col-sm-10
.checkbox
= f.label :allow_group_owners_to_manage_ldap do
= f.check_box :allow_group_owners_to_manage_ldap
Allow group owners to manage LDAP-related settings
%span.help-block
If checked, group owners can manage LDAP group links and LDAP member overrides
= link_to icon('question-circle'), help_page_path('administration/auth/ldap-ee')
%fieldset %fieldset
%legend Account and Limit Settings %legend Account and Limit Settings
......
- if Gitlab::LDAP::Config.enabled_extras? - if Gitlab::LDAP::Config.enabled_extras? && can?(current_user, :admin_ldap_group_links, @group)
= nav_link(path: 'ldap_group_links#index') do = nav_link(path: 'ldap_group_links#index') do
= link_to group_ldap_group_links_path(@group), title: 'LDAP Group' do = link_to group_ldap_group_links_path(@group), title: 'LDAP Group' do
%span %span
......
.page-with-sidebar{ class: "#{('page-with-new-sidebar' if defined?(@new_sidebar) && @new_sidebar)} #{page_gutter_class}" } .page-with-sidebar{ class: page_with_sidebar_class }
- if show_new_nav? - if show_new_nav?
- if defined?(nav) && nav - if defined?(nav) && nav
= render "layouts/nav/#{nav}" = render "layouts/nav/#{nav}"
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
= render "layouts/nav/#{nav}" = render "layouts/nav/#{nav}"
- if content_for?(:sub_nav) - if content_for?(:sub_nav)
= yield :sub_nav = yield :sub_nav
.content-wrapper{ class: "#{(layout_nav_class unless show_new_nav?)}" } .content-wrapper{ class: layout_nav_class }
- if show_new_nav? - if show_new_nav?
.mobile-overlay .mobile-overlay
.alert-wrapper .alert-wrapper
......
!!! 5 !!! 5
%html{ lang: I18n.locale, class: "#{page_class}" } %html{ lang: I18n.locale, class: page_class }
= render "layouts/head" = render "layouts/head"
%body{ class: @body_class, data: { page: body_data_page, project: "#{@project.path if @project}", group: "#{@group.path if @group}", find_file: find_file_path } } %body{ class: @body_class, data: { page: body_data_page, project: "#{@project.path if @project}", group: "#{@group.path if @group}", find_file: find_file_path } }
= render "layouts/init_auto_complete" if @gfm_form = render "layouts/init_auto_complete" if @gfm_form
= render 'peek/bar'
- if show_new_nav? - if show_new_nav?
= render "layouts/header/new" = render "layouts/header/new"
- else - else
...@@ -10,5 +11,3 @@ ...@@ -10,5 +11,3 @@
= render 'layouts/page', sidebar: sidebar, nav: nav = render 'layouts/page', sidebar: sidebar, nav: nav
= yield :scripts_body = yield :scripts_body
= render 'peek/bar'
%span.current-host
= truncate(view.hostname)
...@@ -17,7 +17,11 @@ ...@@ -17,7 +17,11 @@
- if @remote_mirror.last_error.present? - if @remote_mirror.last_error.present?
.panel.panel-danger .panel.panel-danger
.panel-heading .panel-heading
The remote repository failed to update #{time_ago_with_tooltip(@remote_mirror.last_update_at)}. - if @remote_mirror.last_update_at
The remote repository failed to update #{time_ago_with_tooltip(@remote_mirror.last_update_at)}.
- else
The remote repository failed to update.
- if @remote_mirror.last_successful_update_at - if @remote_mirror.last_successful_update_at
Last successful update #{time_ago_with_tooltip(@remote_mirror.last_successful_update_at)}. Last successful update #{time_ago_with_tooltip(@remote_mirror.last_successful_update_at)}.
.panel-body .panel-body
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
- page_title 'New Project' - page_title 'New Project'
- header_title "Projects", dashboard_projects_path - header_title "Projects", dashboard_projects_path
- visibility_level = params.dig(:project, :visibility_level) || default_project_visibility - visibility_level = params.dig(:project, :visibility_level) || default_project_visibility
- content_for :page_specific_javascripts do
= webpack_bundle_tag 'project_new'
.project-edit-container .project-edit-container
.project-edit-errors .project-edit-errors
...@@ -111,49 +113,3 @@ ...@@ -111,49 +113,3 @@
%i.fa.fa-spinner.fa-spin %i.fa.fa-spinner.fa-spin
Creating project &amp; repository. Creating project &amp; repository.
%p Please wait a moment, this page will automatically refresh when ready. %p Please wait a moment, this page will automatically refresh when ready.
:javascript
var importBtnTooltip = "Please enter a valid project name.";
var $importBtnWrapper = $('.import_gitlab_project');
$('.how_to_import_link').bind('click', function (e) {
e.preventDefault();
var import_modal = $(this).next(".modal").show();
});
$('.modal-header .close').bind('click', function() {
$(".modal").hide();
});
$('.btn_import_gitlab_project').bind('click', function() {
var _href = $("a.btn_import_gitlab_project").attr("href");
$(".btn_import_gitlab_project").attr("href", _href + '?namespace_id=' + $("#project_namespace_id").val() + '&path=' + $("#project_path").val());
});
$('.btn_import_gitlab_project').attr('disabled', $('#project_path').val().trim().length === 0);
$importBtnWrapper.attr('title', importBtnTooltip);
$('#new_project').submit(function(){
var $path = $('#project_path');
$path.val($path.val().trim());
});
$('#project_path').keyup(function(){
if($(this).val().trim().length !== 0) {
$('.btn_import_gitlab_project').attr('disabled', false);
$importBtnWrapper.attr('title','');
$importBtnWrapper.removeClass('has-tooltip');
} else {
$('.btn_import_gitlab_project').attr('disabled',true);
$importBtnWrapper.addClass('has-tooltip');
}
});
$('#project_import_url').disable();
$('.import_git').click(function( event ) {
$projectImportUrl = $('#project_import_url');
$projectMirror = $('#project_mirror');
$projectImportUrl.attr('disabled', !$projectImportUrl.attr('disabled'));
$projectMirror.attr('disabled', !$projectMirror.attr('disabled'));
});
- content_for :page_specific_javascripts do
= webpack_bundle_tag('pipelines_times')
%div %div
%p.light %p.light
= _("Commit duration in minutes for last 30 commits") = _("Commit duration in minutes for last 30 commits")
%canvas#build_timesChart{ height: 200 } %canvas#build_timesChart{ height: 200 }
:javascript %script#pipelinesTimesChartsData{ type: "application/json" }= { :labels => @charts[:pipeline_times].labels, :values => @charts[:pipeline_times].pipeline_times }.to_json.html_safe
var data = {
labels : #{@charts[:pipeline_times].labels.to_json},
datasets : [
{
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)",
barStrokeWidth: 1,
barValueSpacing: 1,
barDatasetSpacing: 1,
data : #{@charts[:pipeline_times].pipeline_times.to_json}
}
]
}
var ctx = $("#build_timesChart").get(0).getContext("2d");
var options = { scaleOverlay: true, responsive: true, maintainAspectRatio: false };
if (window.innerWidth < 768) {
// Scale fonts if window width lower than 768px (iPad portrait)
options.scaleFontSize = 8
}
new Chart(ctx).Bar(data, options);
- content_for :page_specific_javascripts do
= webpack_bundle_tag('pipelines_charts')
%h4= _("Pipelines charts") %h4= _("Pipelines charts")
%p %p
&nbsp; &nbsp;
...@@ -26,31 +29,8 @@ ...@@ -26,31 +29,8 @@
= _("Jobs for last year") = _("Jobs for last year")
%canvas#yearChart.padded{ height: 250 } %canvas#yearChart.padded{ height: 250 }
- [:week, :month, :year].each do |scope| %script#pipelinesChartsData{ type: "application/json" }
:javascript - chartData = []
var data = { - [:week, :month, :year].each do |scope|
labels : #{@charts[scope].labels.to_json}, - chartData.push({ 'scope' => scope, 'labels' => @charts[scope].labels, 'totalValues' => @charts[scope].total, 'successValues' => @charts[scope].success })
datasets : [ = chartData.to_json.html_safe
{
fillColor : "#7f8fa4",
strokeColor : "#7f8fa4",
pointColor : "#7f8fa4",
pointStrokeColor : "#EEE",
data : #{@charts[scope].total.to_json}
},
{
fillColor : "#44aa22",
strokeColor : "#44aa22",
pointColor : "#44aa22",
pointStrokeColor : "#fff",
data : #{@charts[scope].success.to_json}
}
]
}
var ctx = $("##{scope}Chart").get(0).getContext("2d");
var options = { scaleOverlay: true, responsive: true, maintainAspectRatio: false };
if (window.innerWidth < 768) {
// Scale fonts if window width lower than 768px (iPad portrait)
options.scaleFontSize = 8
}
new Chart(ctx).Line(data, options);
...@@ -20,7 +20,4 @@ ...@@ -20,7 +20,4 @@
= f.submit 'Create pipeline', class: 'btn btn-create', tabindex: 3 = f.submit 'Create pipeline', class: 'btn btn-create', tabindex: 3
= link_to 'Cancel', project_pipelines_path(@project), class: 'btn btn-cancel' = link_to 'Cancel', project_pipelines_path(@project), class: 'btn btn-cancel'
:javascript %script#availableRefs{ type: "application/json" }= @project.repository.ref_names.to_json.html_safe
var availableRefs = #{@project.repository.ref_names.to_json};
new NewBranchForm($('.js-new-pipeline-form'), availableRefs)
...@@ -40,7 +40,4 @@ ...@@ -40,7 +40,4 @@
.form-actions .form-actions
= button_tag 'Create tag', class: 'btn btn-create', tabindex: 3 = button_tag 'Create tag', class: 'btn btn-create', tabindex: 3
= link_to 'Cancel', project_tags_path(@project), class: 'btn btn-cancel' = link_to 'Cancel', project_tags_path(@project), class: 'btn btn-cancel'
%script#availableRefs{ type: "application/json" }= @project.repository.ref_names.to_json.html_safe
:javascript
window.gl = window.gl || { };
window.gl.availableRefs = #{@project.repository.ref_names.to_json};
.tree-content-holder .tree-content-holder.js-tree-content{ 'data-logs-path': @logs_path, 'data-path-locks-available': (@project.feature_available?(:file_locks) ? 'true' : 'false'), 'data-path-locks-toggle': toggle_project_path_locks_path(@project), 'data-path-locks-path': @path }
.table-holder .table-holder
%table.table#tree-slider{ class: "table_#{@hex_path} tree-table" } %table.table#tree-slider{ class: "table_#{@hex_path} tree-table" }
%thead %thead
...@@ -22,17 +22,3 @@ ...@@ -22,17 +22,3 @@
- if can_edit_tree? - if can_edit_tree?
= render 'projects/blob/upload', title: _('Upload New File'), placeholder: _('Upload New File'), button_title: _('Upload file'), form_path: project_create_blob_path(@project, @id), method: :post = render 'projects/blob/upload', title: _('Upload New File'), placeholder: _('Upload New File'), button_title: _('Upload file'), form_path: project_create_blob_path(@project, @id), method: :post
= render 'projects/blob/new_dir' = render 'projects/blob/new_dir'
- if @project.feature_available?(:file_locks)
:javascript
PathLocks.init(
'#{toggle_project_path_locks_path(@project)}',
'#{@path}'
);
:javascript
// Load last commit log for each file in tree
$('#tree-slider').waitForImages(function() {
gl.utils.ajaxGet("#{escape_javascript(@logs_path)}");
});
...@@ -19,6 +19,3 @@ ...@@ -19,6 +19,3 @@
More Pages More Pages
= render 'projects/wikis/new' = render 'projects/wikis/new'
:javascript
new Sidebar();
...@@ -26,23 +26,4 @@ ...@@ -26,23 +26,4 @@
= geo_button(modal_target: '#modal-geo-info') if Gitlab::Geo.secondary? = geo_button(modal_target: '#modal-geo-info') if Gitlab::Geo.secondary?
:javascript
$('ul.clone-options-dropdown a').on('click',function(e){
e.preventDefault();
var $this = $(this);
$('a.clone-dropdown-btn span').text($this.text());
$('#project_clone').val($this.attr('href'));
});
// Change URLs in Geo Clone Dialog information text
$('ul.clone-options-dropdown a').on('click',function(e){
e.preventDefault();
var $this = $(this);
$('#modal-geo-info').data({
cloneUrlSecondary: $this.attr('href'),
cloneUrlPrimary: $this.data('primaryUrl') || ''
});
});
= render 'shared/geo_info_modal', project: project if Gitlab::Geo.secondary? = render 'shared/geo_info_modal', project: project if Gitlab::Geo.secondary?
...@@ -76,11 +76,3 @@ ...@@ -76,11 +76,3 @@
= link_to destroy_label_path(label), title: "Delete", class: 'btn btn-transparent btn-action remove-row', method: :delete, data: {confirm: label_deletion_confirm_text(label), toggle: "tooltip"} do = link_to destroy_label_path(label), title: "Delete", class: 'btn btn-transparent btn-action remove-row', method: :delete, data: {confirm: label_deletion_confirm_text(label), toggle: "tooltip"} do
%span.sr-only Delete %span.sr-only Delete
= icon('trash-o') = icon('trash-o')
- if current_user
- if can_subscribe_to_label_in_different_levels?(label)
:javascript
new gl.GroupLabelSubscription('##{dom_id(label)} .label-subscription');
- else
:javascript
new gl.ProjectLabelSubscription('##{dom_id(label)} .label-subscription');
...@@ -23,18 +23,3 @@ ...@@ -23,18 +23,3 @@
.prepend-top-default .prepend-top-default
= f.submit "Create #{type} token", class: "btn btn-create" = f.submit "Create #{type} token", class: "btn btn-create"
:javascript
var $dateField = $('.datepicker');
var date = $dateField.val();
new Pikaday({
field: $dateField.get(0),
theme: 'gitlab-theme animate-picker',
format: 'yyyy-mm-dd',
minDate: new Date(),
container: $dateField.parent().get(0),
onSelect: function(dateText) {
$dateField.val(dateFormat(new Date(dateText), 'yyyy-mm-dd'));
}
});
...@@ -37,14 +37,3 @@ ...@@ -37,14 +37,3 @@
.row-content-block.second-block.filtered-labels{ class: ("hidden" unless has_labels) } .row-content-block.second-block.filtered-labels{ class: ("hidden" unless has_labels) }
- if has_labels - if has_labels
= render 'shared/labels_row', labels: @labels = render 'shared/labels_row', labels: @labels
:javascript
new LabelsSelect();
new MilestoneSelect();
new IssueStatusSelect();
new WeightSelect();
new SubscriptionSelect();
$('form.filter-form').on('submit', function (event) {
event.preventDefault();
gl.utils.visitUrl(this.action + '&' + $(this).serialize());
});
...@@ -16,5 +16,3 @@ ...@@ -16,5 +16,3 @@
.hide-collapsed.participants-more .hide-collapsed.participants-more
%a.js-participants-more{ href: "#", data: { original_text: "+ #{participants_size - 7} more", less_text: "- show less" } } %a.js-participants-more{ href: "#", data: { original_text: "+ #{participants_size - 7} more", less_text: "- show less" } }
+ #{participants_extra} more + #{participants_extra} more
:javascript
IssuableContext.prototype.PARTICIPANTS_ROW_COUNT = #{participants_row};
...@@ -128,12 +128,3 @@ ...@@ -128,12 +128,3 @@
#js-add-issues-btn.prepend-left-10 #js-add-issues-btn.prepend-left-10
- elsif type != :boards_modal - elsif type != :boards_modal
= render 'shared/sort_dropdown' = render 'shared/sort_dropdown'
- unless type === :boards_modal
:javascript
$(document).off('page:restore').on('page:restore', function (event) {
if (gl.FilteredSearchManager) {
const filteredSearchManager = new gl.FilteredSearchManager();
filteredSearchManager.setup();
}
});
...@@ -165,18 +165,4 @@ ...@@ -165,18 +165,4 @@
= project_ref = project_ref
= clipboard_button(text: project_ref, title: "Copy reference to clipboard", placement: "left") = clipboard_button(text: project_ref, title: "Copy reference to clipboard", placement: "left")
:javascript %script.js-sidebar-options{ type: "application/json" }= issuable_sidebar_options(issuable, can_edit_issuable).to_json.html_safe
gl.sidebarOptions = {
endpoint: "#{issuable_json_path(issuable)}?basic=true",
editable: #{can_edit_issuable ? true : false},
currentUser: #{current_user.to_json(only: [:username, :id, :name], methods: :avatar_url)},
rootPath: "#{root_path}"
};
new MilestoneSelect('{"full_path":"#{@project.full_path}"}');
new LabelsSelect();
new WeightSelect();
new IssuableContext('#{escape_javascript(current_user.to_json(only: [:username, :id, :name]))}');
gl.Subscription.bindAll('.subscription');
new gl.DueDateSelectors();
window.sidebar = new Sidebar();
...@@ -22,5 +22,4 @@ ...@@ -22,5 +22,4 @@
= link_to "sign in", new_session_path(:user, redirect_to_referer: 'yes') = link_to "sign in", new_session_path(:user, redirect_to_referer: 'yes')
to comment to comment
:javascript %script.js-notes-data{ type: "application/json" }= initial_notes_data(autocomplete).to_json.html_safe
var notes = new Notes("#{notes_url}", #{@notes.map(&:id).to_json}, #{Time.now.to_i}, "#{diff_view}", #{autocomplete})
- remote = local_assigns.fetch(:remote, false)
- link_project = local_assigns.fetch(:link_project, false) - link_project = local_assigns.fetch(:link_project, false)
.snippets-list-holder .snippets-list-holder
...@@ -8,7 +7,4 @@ ...@@ -8,7 +7,4 @@
%li %li
.nothing-here-block Nothing here. .nothing-here-block Nothing here.
= paginate @snippets, theme: 'gitlab', remote: remote = paginate @snippets, theme: 'gitlab'
:javascript
gl.SnippetsList();
---
title: Fix CSS for mini graph with downstream pipeline
merge_request:
author:
---
title: Add admin application setting to allow group owners to manage LDAP.
merge_request: 2529
author:
---
title: Adds lower bound to pull mirror scheduling feature
merge_request: 2366
author:
---
title: Renamed board to boards in new project sidebar
merge_request:
author:
---
title: Add warning and option toggle when rebuilding authorized_keys.
merge_request: 2508
author:
---
title: Fixed issue boards focus mode when new navigation is turned on
merge_request:
author:
---
title: Fix vertical alignment in firefox and safari for pipeline mini graph
merge_request:
author:
---
title: Fix crash on /help/ui
merge_request:
author:
---
title: Pending delete projects should not show in deploy keys.
merge_request: 13088
author:
---
title: Fixes 500 error caused by pending delete projects in admin dashboard
merge_request: 13067
author:
---
title: Allow admin to read_users_list even if it's restricted
merge_request: 13066
author:
---
title: Add instrumentation to MarkupHelper#link_to_gfm
merge_request: 13069
author:
---
title: Fix job merge request link to a forked source project
merge_request: 12965
author:
--- ---
title: Fix Rebasing not working with Merge Requests title: Merge issuable "reopened" state into "opened"
merge_request: merge_request:
author: author:
---
title: Fix sizing of custom header logo in new navigation
merge_request:
author:
...@@ -57,8 +57,11 @@ var config = { ...@@ -57,8 +57,11 @@ var config = {
notebook_viewer: './blob/notebook_viewer.js', notebook_viewer: './blob/notebook_viewer.js',
pdf_viewer: './blob/pdf_viewer.js', pdf_viewer: './blob/pdf_viewer.js',
pipelines: './pipelines/pipelines_bundle.js', pipelines: './pipelines/pipelines_bundle.js',
pipelines_details: './pipelines/pipeline_details_bundle.js', pipelines_charts: './pipelines/pipelines_charts.js',
pipelines_details: './pipelines/pipeline_details_bundle.js',
pipelines_times: './pipelines/pipelines_times.js',
profile: './profile/profile_bundle.js', profile: './profile/profile_bundle.js',
project_new: './projects/project_new.js',
prometheus_metrics: './prometheus_metrics', prometheus_metrics: './prometheus_metrics',
protected_branches: './protected_branches', protected_branches: './protected_branches',
ee_protected_branches: './protected_branches/ee', ee_protected_branches: './protected_branches/ee',
......
class CreateCiPipelineVariables < ActiveRecord::Migration
DOWNTIME = false
def up
create_table :ci_pipeline_variables do |t|
t.string :key, null: false
t.text :value
t.text :encrypted_value
t.string :encrypted_value_salt
t.string :encrypted_value_iv
t.integer :pipeline_id, null: false
end
add_index :ci_pipeline_variables, [:pipeline_id, :key], unique: true
end
def down
drop_table :ci_pipeline_variables
end
end
class AddForeignKeyToCiPipelineVariables < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_concurrent_foreign_key(:ci_pipeline_variables, :ci_pipelines, column: :pipeline_id)
end
def down
remove_foreign_key(:ci_pipeline_variables, column: :pipeline_id)
end
end
class AddRestrictGroupOwnersToAdminsOptionToApplicationSettings < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_column_with_default(:application_settings, :allow_group_owners_to_manage_ldap, :boolean, default: true)
end
def down
remove_column(:application_settings, :allow_group_owners_to_manage_ldap)
end
end
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class MergeIssuableReopenedIntoOpenedState < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
class Issue < ActiveRecord::Base
self.table_name = 'issues'
include EachBatch
end
class MergeRequest < ActiveRecord::Base
self.table_name = 'merge_requests'
include EachBatch
end
def up
[Issue, MergeRequest].each do |model|
say "Changing #{model.table_name}.state from 'reopened' to 'opened'"
model.where(state: 'reopened').each_batch do |batch|
batch.update_all(state: 'opened')
end
end
end
end
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20170725145659) do ActiveRecord::Schema.define(version: 20170726111039) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
...@@ -149,6 +149,7 @@ ActiveRecord::Schema.define(version: 20170725145659) do ...@@ -149,6 +149,7 @@ ActiveRecord::Schema.define(version: 20170725145659) do
t.string "slack_app_verification_token" t.string "slack_app_verification_token"
t.integer "performance_bar_allowed_group_id" t.integer "performance_bar_allowed_group_id"
t.boolean "password_authentication_enabled" t.boolean "password_authentication_enabled"
t.boolean "allow_group_owners_to_manage_ldap", default: true, null: false
end end
create_table "approvals", force: :cascade do |t| create_table "approvals", force: :cascade do |t|
...@@ -356,6 +357,17 @@ ActiveRecord::Schema.define(version: 20170725145659) do ...@@ -356,6 +357,17 @@ ActiveRecord::Schema.define(version: 20170725145659) do
add_index "ci_pipeline_schedules", ["next_run_at", "active"], name: "index_ci_pipeline_schedules_on_next_run_at_and_active", using: :btree add_index "ci_pipeline_schedules", ["next_run_at", "active"], name: "index_ci_pipeline_schedules_on_next_run_at_and_active", using: :btree
add_index "ci_pipeline_schedules", ["project_id"], name: "index_ci_pipeline_schedules_on_project_id", using: :btree add_index "ci_pipeline_schedules", ["project_id"], name: "index_ci_pipeline_schedules_on_project_id", using: :btree
create_table "ci_pipeline_variables", force: :cascade do |t|
t.string "key", null: false
t.text "value"
t.text "encrypted_value"
t.string "encrypted_value_salt"
t.string "encrypted_value_iv"
t.integer "pipeline_id", null: false
end
add_index "ci_pipeline_variables", ["pipeline_id", "key"], name: "index_ci_pipeline_variables_on_pipeline_id_and_key", unique: true, using: :btree
create_table "ci_pipelines", force: :cascade do |t| create_table "ci_pipelines", force: :cascade do |t|
t.string "ref" t.string "ref"
t.string "sha" t.string "sha"
...@@ -1937,6 +1949,7 @@ ActiveRecord::Schema.define(version: 20170725145659) do ...@@ -1937,6 +1949,7 @@ ActiveRecord::Schema.define(version: 20170725145659) do
add_foreign_key "ci_group_variables", "namespaces", column: "group_id", name: "fk_33ae4d58d8", on_delete: :cascade add_foreign_key "ci_group_variables", "namespaces", column: "group_id", name: "fk_33ae4d58d8", on_delete: :cascade
add_foreign_key "ci_pipeline_schedules", "projects", name: "fk_8ead60fcc4", on_delete: :cascade add_foreign_key "ci_pipeline_schedules", "projects", name: "fk_8ead60fcc4", on_delete: :cascade
add_foreign_key "ci_pipeline_schedules", "users", column: "owner_id", name: "fk_9ea99f58d2", on_delete: :nullify add_foreign_key "ci_pipeline_schedules", "users", column: "owner_id", name: "fk_9ea99f58d2", on_delete: :nullify
add_foreign_key "ci_pipeline_variables", "ci_pipelines", column: "pipeline_id", name: "fk_f29c5f4380", on_delete: :cascade
add_foreign_key "ci_pipelines", "ci_pipeline_schedules", column: "pipeline_schedule_id", name: "fk_3d34ab2e06", on_delete: :nullify add_foreign_key "ci_pipelines", "ci_pipeline_schedules", column: "pipeline_schedule_id", name: "fk_3d34ab2e06", on_delete: :nullify
add_foreign_key "ci_pipelines", "ci_pipelines", column: "auto_canceled_by_id", name: "fk_262d4c2d19", on_delete: :nullify add_foreign_key "ci_pipelines", "ci_pipelines", column: "auto_canceled_by_id", name: "fk_262d4c2d19", on_delete: :nullify
add_foreign_key "ci_pipelines", "projects", name: "fk_86635dbd80", on_delete: :cascade add_foreign_key "ci_pipelines", "projects", name: "fk_86635dbd80", on_delete: :cascade
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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