Merge remote-tracking branch 'origin/active-record-each-batch' into fix/gb/stage-id-reference-background-migration
* origin/active-record-each-batch: (59 commits) Added EachBatch for iterating tables in batches Extend MR tabs a bit to cover up the avatar holder and collapse icon on scroll Update VERSION to 9.4.0-pre. Add CHANGELOG Fix some N+1 queries in the GET /projects API Don't show auxiliary blob viewer for README when there is no wiki Improve & fix the performance bar UI and behavior Remove orphaned haml files Fixed CHANGELOG.md for 9.3.4 release Add table for merge request commits 34727 Remove two columned layout from project member settings Just draw :legacy_builds Re-enable polling for environments Cleanup minor UX issues in the performance dashboard Upgrade GitLab Workhorse to v2.3.0 Added test for the chart legend Use correct field for label name, fix default for unit to be blank Fix shorter route helpers in production environment Encode certificate-authority-data in base64 Revert "Merge branch 'winh-mr-widget-no-pipeline' into 'master'" ...
This commit is contained in:
commit
b7b3aef444
|
@ -12,7 +12,7 @@ entry.
|
|||
|
||||
## 9.3.4 (2017-07-03)
|
||||
|
||||
- No changes.
|
||||
- Update gitlab-shell to 5.1.1 !12615
|
||||
|
||||
## 9.3.3 (2017-06-30)
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.4.3
|
||||
0.5.0
|
||||
|
|
|
@ -1 +1 @@
|
|||
2.2.0
|
||||
2.3.0
|
||||
|
|
|
@ -56,6 +56,8 @@ import GfmAutoComplete from './gfm_auto_complete';
|
|||
import ShortcutsBlob from './shortcuts_blob';
|
||||
import initSettingsPanels from './settings_panels';
|
||||
import initExperimentalFlags from './experimental_flags';
|
||||
import OAuthRememberMe from './oauth_remember_me';
|
||||
import PerformanceBar from './performance_bar';
|
||||
|
||||
(function() {
|
||||
var Dispatcher;
|
||||
|
@ -127,6 +129,7 @@ import initExperimentalFlags from './experimental_flags';
|
|||
case 'sessions:new':
|
||||
new UsernameValidator();
|
||||
new ActiveTabMemoizer();
|
||||
new OAuthRememberMe({ container: $(".omniauth-container") }).bindEvents();
|
||||
break;
|
||||
case 'projects:boards:show':
|
||||
case 'projects:boards:index':
|
||||
|
@ -513,6 +516,10 @@ import initExperimentalFlags from './experimental_flags';
|
|||
if (!shortcut_handler) {
|
||||
new Shortcuts();
|
||||
}
|
||||
|
||||
if (document.querySelector('#peek')) {
|
||||
new PerformanceBar({ container: '#peek' });
|
||||
}
|
||||
};
|
||||
|
||||
Dispatcher.prototype.initSearch = function() {
|
||||
|
|
|
@ -105,9 +105,9 @@
|
|||
this.measurements = measurements.small;
|
||||
}
|
||||
this.data = query.result[0].values;
|
||||
this.unitOfDisplay = query.unit || 'N/A';
|
||||
this.unitOfDisplay = query.unit || '';
|
||||
this.yAxisLabel = this.columnData.y_label || 'Values';
|
||||
this.legendTitle = query.legend || 'Average';
|
||||
this.legendTitle = query.label || 'Average';
|
||||
this.graphWidth = this.$refs.baseSvg.clientWidth -
|
||||
this.margin.left - this.margin.right;
|
||||
this.graphHeight = this.graphHeight - this.margin.top - this.margin.bottom;
|
||||
|
@ -159,12 +159,12 @@
|
|||
|
||||
const xAxis = d3.svg.axis()
|
||||
.scale(axisXScale)
|
||||
.ticks(measurements.ticks)
|
||||
.ticks(measurements.xTicks)
|
||||
.orient('bottom');
|
||||
|
||||
const yAxis = d3.svg.axis()
|
||||
.scale(this.yScale)
|
||||
.ticks(measurements.ticks)
|
||||
.ticks(measurements.yTicks)
|
||||
.orient('left');
|
||||
|
||||
d3.select(this.$refs.baseSvg).select('.x-axis').call(xAxis);
|
||||
|
@ -172,8 +172,12 @@
|
|||
const width = this.graphWidth;
|
||||
d3.select(this.$refs.baseSvg).select('.y-axis').call(yAxis)
|
||||
.selectAll('.tick')
|
||||
.each(function createTickLines() {
|
||||
d3.select(this).select('line').attr('x2', width);
|
||||
.each(function createTickLines(d, i) {
|
||||
if (i > 0) {
|
||||
d3.select(this).select('line')
|
||||
.attr('x2', width)
|
||||
.attr('class', 'axis-tick');
|
||||
} // Avoid adding the class to the first tick, to prevent coloring
|
||||
}); // This will select all of the ticks once they're rendered
|
||||
|
||||
this.xScale = d3.time.scale()
|
||||
|
@ -215,16 +219,16 @@
|
|||
};
|
||||
</script>
|
||||
<template>
|
||||
<div
|
||||
<div
|
||||
:class="classType">
|
||||
<h5
|
||||
<h5
|
||||
class="text-center graph-title">
|
||||
{{columnData.title}}
|
||||
</h5>
|
||||
<div
|
||||
class="prometheus-svg-container"
|
||||
:style="paddingBottomRootSvg">
|
||||
<svg
|
||||
<svg
|
||||
:viewBox="outterViewBox"
|
||||
ref="baseSvg">
|
||||
<g
|
||||
|
@ -235,7 +239,7 @@
|
|||
class="y-axis"
|
||||
transform="translate(70, 20)">
|
||||
</g>
|
||||
<monitoring-legends
|
||||
<monitoring-legends
|
||||
:graph-width="graphWidth"
|
||||
:graph-height="graphHeight"
|
||||
:margin="margin"
|
||||
|
@ -245,7 +249,7 @@
|
|||
:y-axis-label="yAxisLabel"
|
||||
:metric-usage="metricUsage"
|
||||
/>
|
||||
<svg
|
||||
<svg
|
||||
class="graph-data"
|
||||
:viewBox="innerViewBox"
|
||||
ref="graphData">
|
||||
|
@ -263,7 +267,7 @@
|
|||
stroke-width="2"
|
||||
transform="translate(-5, 20)">
|
||||
</path>
|
||||
<rect
|
||||
<rect
|
||||
class="prometheus-graph-overlay"
|
||||
:width="(graphWidth - 70)"
|
||||
:height="(graphHeight - 100)"
|
||||
|
@ -277,7 +281,7 @@
|
|||
:graph-height="graphHeight"
|
||||
:graph-height-offset="graphHeightOffset"
|
||||
/>
|
||||
<monitoring-flag
|
||||
<monitoring-flag
|
||||
v-if="showFlag"
|
||||
:current-x-coordinate="currentXCoordinate"
|
||||
:current-y-coordinate="currentYCoordinate"
|
||||
|
|
|
@ -87,14 +87,14 @@
|
|||
</rect>
|
||||
<text
|
||||
class="text-metric text-metric-bold"
|
||||
x="8"
|
||||
x="16"
|
||||
y="35"
|
||||
transform="translate(-5, 20)">
|
||||
{{formatTime}}
|
||||
</text>
|
||||
<text
|
||||
class="text-metric-date"
|
||||
x="8"
|
||||
class="text-metric"
|
||||
x="16"
|
||||
y="15"
|
||||
transform="translate(-5, 20)">
|
||||
{{formatDate}}
|
||||
|
|
|
@ -109,13 +109,13 @@
|
|||
</text>
|
||||
<rect
|
||||
class="rect-axis-text"
|
||||
:x="xPosition + 50"
|
||||
:x="xPosition + 60"
|
||||
:y="graphHeight - 80"
|
||||
width="50"
|
||||
width="35"
|
||||
height="50">
|
||||
</rect>
|
||||
<text
|
||||
class="label-axis-text"
|
||||
class="label-axis-text x-label-text"
|
||||
:x="xPosition + 60"
|
||||
:y="yPosition"
|
||||
dy=".35em">
|
||||
|
@ -131,13 +131,13 @@
|
|||
<text
|
||||
class="text-metric-title"
|
||||
x="50"
|
||||
:y="graphHeight - 40">
|
||||
:y="graphHeight - 25">
|
||||
{{legendTitle}}
|
||||
</text>
|
||||
<text
|
||||
class="text-metric-usage"
|
||||
x="50"
|
||||
:y="graphHeight - 25">
|
||||
:y="graphHeight - 10">
|
||||
{{metricUsage}}
|
||||
</text>
|
||||
</g>
|
||||
|
|
|
@ -8,14 +8,14 @@ export default {
|
|||
},
|
||||
legends: {
|
||||
width: 15,
|
||||
height: 30,
|
||||
height: 25,
|
||||
},
|
||||
backgroundLegend: {
|
||||
width: 30,
|
||||
height: 50,
|
||||
},
|
||||
axisLabelLineOffset: -20,
|
||||
legendOffset: 52,
|
||||
legendOffset: 35,
|
||||
},
|
||||
large: { // This covers both md and lg screen sizes
|
||||
margin: {
|
||||
|
@ -26,14 +26,15 @@ export default {
|
|||
},
|
||||
legends: {
|
||||
width: 20,
|
||||
height: 35,
|
||||
height: 30,
|
||||
},
|
||||
backgroundLegend: {
|
||||
width: 30,
|
||||
height: 150,
|
||||
},
|
||||
axisLabelLineOffset: 20,
|
||||
legendOffset: 55,
|
||||
legendOffset: 38,
|
||||
},
|
||||
ticks: 3,
|
||||
xTicks: 8,
|
||||
yTicks: 3,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
* OAuth-based login buttons have a separate "remember me" checkbox.
|
||||
*
|
||||
* Toggling this checkbox adds/removes a `remember_me` parameter to the
|
||||
* login buttons' href, which is passed on to the omniauth callback.
|
||||
**/
|
||||
|
||||
export default class OAuthRememberMe {
|
||||
constructor(opts = {}) {
|
||||
this.container = opts.container || '';
|
||||
this.loginLinkSelector = '.oauth-login';
|
||||
}
|
||||
|
||||
bindEvents() {
|
||||
$('#remember_me', this.container).on('click', this.toggleRememberMe);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
toggleRememberMe(event) {
|
||||
const rememberMe = $(event.target).is(':checked');
|
||||
|
||||
$('.oauth-login', this.container).each((i, element) => {
|
||||
const href = $(element).attr('href');
|
||||
|
||||
if (rememberMe) {
|
||||
$(element).attr('href', `${href}?remember_me=1`);
|
||||
} else {
|
||||
$(element).attr('href', href.replace('?remember_me=1', ''));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
import 'vendor/peek';
|
||||
import 'vendor/peek.performance_bar';
|
||||
|
||||
$(document).on('click', '#peek-show-queries', (e) => {
|
||||
e.preventDefault();
|
||||
$('.peek-rblineprof-modal').hide();
|
||||
const $modal = $('#modal-peek-pg-queries');
|
||||
if ($modal.length) {
|
||||
$modal.modal('toggle');
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('click', '.js-lineprof-file', (e) => {
|
||||
e.preventDefault();
|
||||
$(e.target).parents('.peek-rblineprof-file').find('.data').toggle();
|
||||
});
|
|
@ -0,0 +1,62 @@
|
|||
import 'vendor/peek';
|
||||
import 'vendor/peek.performance_bar';
|
||||
|
||||
export default class PerformanceBar {
|
||||
constructor(opts) {
|
||||
if (!PerformanceBar.singleton) {
|
||||
this.init(opts);
|
||||
PerformanceBar.singleton = this;
|
||||
}
|
||||
return PerformanceBar.singleton;
|
||||
}
|
||||
|
||||
init(opts) {
|
||||
const $container = $(opts.container);
|
||||
this.$sqlProfileLink = $container.find('.js-toggle-modal-peek-sql');
|
||||
this.$sqlProfileModal = $container.find('#modal-peek-pg-queries');
|
||||
this.$lineProfileLink = $container.find('.js-toggle-modal-peek-line-profile');
|
||||
this.$lineProfileModal = $('#modal-peek-line-profile');
|
||||
this.initEventListeners();
|
||||
this.showModalOnLoad();
|
||||
}
|
||||
|
||||
initEventListeners() {
|
||||
this.$sqlProfileLink.on('click', () => this.handleSQLProfileLink());
|
||||
this.$lineProfileLink.on('click', e => this.handleLineProfileLink(e));
|
||||
$(document).on('click', '.js-lineprof-file', PerformanceBar.toggleLineProfileFile);
|
||||
}
|
||||
|
||||
showModalOnLoad() {
|
||||
// When a lineprofiler query-string param is present, we show the line
|
||||
// profiler modal upon page load
|
||||
if (/lineprofiler/.test(window.location.search)) {
|
||||
PerformanceBar.toggleModal(this.$lineProfileModal);
|
||||
}
|
||||
}
|
||||
|
||||
handleSQLProfileLink() {
|
||||
PerformanceBar.toggleModal(this.$sqlProfileModal);
|
||||
}
|
||||
|
||||
handleLineProfileLink(e) {
|
||||
const lineProfilerParameter = gl.utils.getParameterValues('lineprofiler');
|
||||
const lineProfilerParameterRegex = new RegExp(`lineprofiler=${lineProfilerParameter[0]}`);
|
||||
const shouldToggleModal = lineProfilerParameter.length > 0 &&
|
||||
lineProfilerParameterRegex.test(e.currentTarget.href);
|
||||
|
||||
if (shouldToggleModal) {
|
||||
e.preventDefault();
|
||||
PerformanceBar.toggleModal(this.$lineProfileModal);
|
||||
}
|
||||
}
|
||||
|
||||
static toggleModal($modal) {
|
||||
if ($modal.length) {
|
||||
$modal.modal('toggle');
|
||||
}
|
||||
}
|
||||
|
||||
static toggleLineProfileFile(e) {
|
||||
$(e.currentTarget).parents('.peek-rblineprof-file').find('.data').toggle();
|
||||
}
|
||||
}
|
|
@ -17,9 +17,6 @@ export default {
|
|||
|
||||
return hasCI && !ciStatus;
|
||||
},
|
||||
hasPipeline() {
|
||||
return Object.keys(this.mr.pipeline || {}).length > 0;
|
||||
},
|
||||
svg() {
|
||||
return statusIconEntityMap.icon_status_failed;
|
||||
},
|
||||
|
@ -33,11 +30,7 @@ export default {
|
|||
template: `
|
||||
<div class="mr-widget-heading">
|
||||
<div class="ci-widget">
|
||||
<template v-if="!hasPipeline">
|
||||
<i class="fa fa-spinner fa-spin append-right-10" aria-hidden="true"></i>
|
||||
Waiting for pipeline...
|
||||
</template>
|
||||
<template v-else-if="hasCIError">
|
||||
<template v-if="hasCIError">
|
||||
<div class="ci-status-icon ci-status-icon-failed ci-error js-ci-error">
|
||||
<span class="js-icon-link icon-link">
|
||||
<span
|
||||
|
|
|
@ -21,3 +21,9 @@ body.modal-open {
|
|||
width: 860px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: $screen-lg-min) {
|
||||
.modal-full {
|
||||
width: 98%;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -594,3 +594,15 @@ Convdev Index
|
|||
$color-high-score: $green-400;
|
||||
$color-average-score: $orange-400;
|
||||
$color-low-score: $red-400;
|
||||
|
||||
/*
|
||||
Performance Bar
|
||||
*/
|
||||
$perf-bar-text: #999;
|
||||
$perf-bar-production: #222;
|
||||
$perf-bar-staging: #291430;
|
||||
$perf-bar-development: #4c1210;
|
||||
$perf-bar-bucket-bg: #111;
|
||||
$perf-bar-bucket-color: #ccc;
|
||||
$perf-bar-bucket-box-shadow-from: rgba($white-light, .2);
|
||||
$perf-bar-bucket-box-shadow-to: rgba($black, .25);
|
||||
|
|
|
@ -187,8 +187,7 @@
|
|||
}
|
||||
|
||||
.text-metric {
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.selected-metric-line {
|
||||
|
@ -232,10 +231,6 @@
|
|||
width: 100%;
|
||||
padding: 0;
|
||||
padding-bottom: 100%;
|
||||
|
||||
.text-metric-bold {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.prometheus-svg-container > svg {
|
||||
|
@ -250,6 +245,10 @@
|
|||
stroke-width: 0;
|
||||
}
|
||||
|
||||
.text-metric-bold {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.label-axis-text,
|
||||
.text-metric-usage {
|
||||
fill: $black;
|
||||
|
@ -269,6 +268,15 @@
|
|||
font-size: 12px;
|
||||
}
|
||||
|
||||
.y-label-text,
|
||||
.x-label-text {
|
||||
fill: $gray-darkest;
|
||||
}
|
||||
|
||||
.axis-tick {
|
||||
stroke: $gray-darker;
|
||||
}
|
||||
|
||||
@media (max-width: $screen-sm-max) {
|
||||
.label-axis-text,
|
||||
.text-metric-usage,
|
||||
|
|
|
@ -731,11 +731,11 @@
|
|||
|
||||
.merge-request-tabs-holder {
|
||||
top: $header-height;
|
||||
z-index: 100;
|
||||
z-index: 200;
|
||||
background-color: $white-light;
|
||||
border-bottom: 1px solid $border-color;
|
||||
|
||||
@media(min-width: $screen-sm-min) {
|
||||
@media (min-width: $screen-sm-min) {
|
||||
position: sticky;
|
||||
position: -webkit-sticky;
|
||||
}
|
||||
|
@ -770,6 +770,12 @@
|
|||
max-width: $limited-layout-width;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
|
||||
.inner-page-scroll-tabs {
|
||||
background-color: $white-light;
|
||||
margin-left: -$gl-padding;
|
||||
padding-left: $gl-padding;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,47 +1,44 @@
|
|||
//= require peek/views/performance_bar
|
||||
//= require peek/views/rblineprof
|
||||
|
||||
header.navbar-gitlab.with-peek {
|
||||
top: 35px;
|
||||
}
|
||||
@import "framework/variables";
|
||||
@import "peek/views/performance_bar";
|
||||
@import "peek/views/rblineprof";
|
||||
|
||||
#peek {
|
||||
height: 35px;
|
||||
background: #000;
|
||||
background: $black;
|
||||
line-height: 35px;
|
||||
color: #999;
|
||||
color: $perf-bar-text;
|
||||
|
||||
&.disabled {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.production {
|
||||
background-color: #222;
|
||||
background-color: $perf-bar-production;
|
||||
}
|
||||
|
||||
&.staging {
|
||||
background-color: #291430;
|
||||
background-color: $perf-bar-staging;
|
||||
}
|
||||
|
||||
&.development {
|
||||
background-color: #4c1210;
|
||||
background-color: $perf-bar-development;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
width: 800px;
|
||||
width: 1000px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
// UI Elements
|
||||
.bucket {
|
||||
background: #111;
|
||||
background: $perf-bar-bucket-bg;
|
||||
display: inline-block;
|
||||
padding: 4px 6px;
|
||||
font-family: Consolas, "Liberation Mono", Courier, monospace;
|
||||
line-height: 1;
|
||||
color: #ccc;
|
||||
color: $perf-bar-bucket-color;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 1px 0 rgba(255,255,255,.2), inset 0 1px 2px rgba(0,0,0,.25);
|
||||
box-shadow: 0 1px 0 $perf-bar-bucket-box-shadow-from, inset 0 1px 2px $perf-bar-bucket-box-shadow-to;
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
|
@ -53,12 +50,14 @@ header.navbar-gitlab.with-peek {
|
|||
}
|
||||
|
||||
strong {
|
||||
color: #fff;
|
||||
color: $white-light;
|
||||
}
|
||||
|
||||
table {
|
||||
color: $black;
|
||||
|
||||
strong {
|
||||
color: #000;
|
||||
color: $black;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,5 +89,15 @@ header.navbar-gitlab.with-peek {
|
|||
}
|
||||
|
||||
#modal-peek-pg-queries-content {
|
||||
color: #000;
|
||||
color: $black;
|
||||
}
|
||||
|
||||
.peek-rblineprof-file {
|
||||
pre.duration {
|
||||
width: 280px;
|
||||
}
|
||||
|
||||
.data {
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
|
@ -47,7 +47,7 @@ module IssuableCollections
|
|||
end
|
||||
|
||||
def merge_requests_collection
|
||||
merge_requests_finder.execute.preload(:source_project, :target_project, :author, :assignee, :labels, :milestone, :merge_request_diff, :head_pipeline, target_project: :namespace)
|
||||
merge_requests_finder.execute.preload(:source_project, :target_project, :author, :assignee, :labels, :milestone, :head_pipeline, target_project: :namespace, merge_request_diff: :merge_request_diff_commits)
|
||||
end
|
||||
|
||||
def issues_finder
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
||||
include AuthenticatesWithTwoFactor
|
||||
include Devise::Controllers::Rememberable
|
||||
|
||||
protect_from_forgery except: [:kerberos, :saml, :cas3]
|
||||
|
||||
|
@ -115,8 +116,10 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
|||
if @user.persisted? && @user.valid?
|
||||
log_audit_event(@user, with: oauth['provider'])
|
||||
if @user.two_factor_enabled?
|
||||
params[:remember_me] = '1' if remember_me?
|
||||
prompt_for_two_factor(@user)
|
||||
else
|
||||
remember_me(@user) if remember_me?
|
||||
sign_in_and_redirect(@user)
|
||||
end
|
||||
else
|
||||
|
@ -147,4 +150,9 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
|||
AuditEventService.new(user, user, options)
|
||||
.for_authentication.security_event
|
||||
end
|
||||
|
||||
def remember_me?
|
||||
request_params = request.env['omniauth.params']
|
||||
(request_params['remember_me'] == '1') if request_params.present?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,6 +15,8 @@ class Projects::EnvironmentsController < Projects::ApplicationController
|
|||
respond_to do |format|
|
||||
format.html
|
||||
format.json do
|
||||
Gitlab::PollingInterval.set_header(response, interval: 3_000)
|
||||
|
||||
render json: {
|
||||
environments: EnvironmentSerializer
|
||||
.new(project: @project, current_user: @current_user)
|
||||
|
|
|
@ -14,7 +14,7 @@ class Projects::VariablesController < Projects::ApplicationController
|
|||
def update
|
||||
@variable = @project.variables.find(params[:id])
|
||||
|
||||
if @variable.update_attributes(project_params)
|
||||
if @variable.update_attributes(variable_params)
|
||||
redirect_to project_variables_path(project), notice: 'Variable was successfully updated.'
|
||||
else
|
||||
render action: "show"
|
||||
|
@ -22,9 +22,9 @@ class Projects::VariablesController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
def create
|
||||
@variable = Ci::Variable.new(project_params)
|
||||
@variable = @project.variables.new(variable_params)
|
||||
|
||||
if @variable.valid? && @project.variables << @variable
|
||||
if @variable.save
|
||||
flash[:notice] = 'Variables were successfully updated.'
|
||||
redirect_to project_settings_ci_cd_path(project)
|
||||
else
|
||||
|
@ -43,8 +43,11 @@ class Projects::VariablesController < Projects::ApplicationController
|
|||
|
||||
private
|
||||
|
||||
def project_params
|
||||
params.require(:variable)
|
||||
.permit([:id, :key, :value, :protected, :_destroy])
|
||||
def variable_params
|
||||
params.require(:variable).permit(*variable_params_attributes)
|
||||
end
|
||||
|
||||
def variable_params_attributes
|
||||
%i[id key value protected _destroy]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,7 +28,14 @@ class ProjectsFinder < UnionFinder
|
|||
end
|
||||
|
||||
def execute
|
||||
collection = init_collection
|
||||
user = params.delete(:user)
|
||||
collection =
|
||||
if user
|
||||
PersonalProjectsFinder.new(user).execute(current_user)
|
||||
else
|
||||
init_collection
|
||||
end
|
||||
|
||||
collection = by_ids(collection)
|
||||
collection = by_personal(collection)
|
||||
collection = by_starred(collection)
|
||||
|
|
|
@ -23,7 +23,6 @@ module NavHelper
|
|||
def nav_header_class
|
||||
class_name = ''
|
||||
class_name << " with-horizontal-nav" if defined?(nav) && nav
|
||||
class_name << " with-peek" if peek_enabled?
|
||||
|
||||
class_name
|
||||
end
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
module PerformanceBarHelper
|
||||
# This is a hack since using `alias_method :performance_bar_enabled?, :peek_enabled?`
|
||||
# in WithPerformanceBar breaks tests (but works in the browser).
|
||||
def performance_bar_enabled?
|
||||
peek_enabled?
|
||||
end
|
||||
end
|
|
@ -10,5 +10,5 @@ class Appearance < ActiveRecord::Base
|
|||
|
||||
mount_uploader :logo, AttachmentUploader
|
||||
mount_uploader :header_logo, AttachmentUploader
|
||||
has_many :uploads, as: :model, dependent: :destroy
|
||||
has_many :uploads, as: :model, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
end
|
||||
|
|
|
@ -13,13 +13,13 @@ class ApplicationSetting < ActiveRecord::Base
|
|||
[\r\n] # any number of newline characters
|
||||
}x
|
||||
|
||||
serialize :restricted_visibility_levels # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :import_sources # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :disabled_oauth_sign_in_sources, Array # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :domain_whitelist, Array # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :domain_blacklist, Array # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :repository_storages # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :sidekiq_throttling_queues, Array # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :restricted_visibility_levels # rubocop:disable Cop/ActiveRecordSerialize
|
||||
serialize :import_sources # rubocop:disable Cop/ActiveRecordSerialize
|
||||
serialize :disabled_oauth_sign_in_sources, Array # rubocop:disable Cop/ActiveRecordSerialize
|
||||
serialize :domain_whitelist, Array # rubocop:disable Cop/ActiveRecordSerialize
|
||||
serialize :domain_blacklist, Array # rubocop:disable Cop/ActiveRecordSerialize
|
||||
serialize :repository_storages # rubocop:disable Cop/ActiveRecordSerialize
|
||||
serialize :sidekiq_throttling_queues, Array # rubocop:disable Cop/ActiveRecordSerialize
|
||||
|
||||
cache_markdown_field :sign_in_text
|
||||
cache_markdown_field :help_page_text
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class AuditEvent < ActiveRecord::Base
|
||||
serialize :details, Hash # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :details, Hash # rubocop:disable Cop/ActiveRecordSerialize
|
||||
|
||||
belongs_to :user, foreign_key: :author_id
|
||||
|
||||
|
|
|
@ -10,5 +10,11 @@ module BlobViewer
|
|||
def visible_to?(current_user)
|
||||
can?(current_user, :read_wiki, project)
|
||||
end
|
||||
|
||||
def render_error
|
||||
return if project.has_external_wiki? || (project.wiki_enabled? && project.wiki.has_home_page?)
|
||||
|
||||
:no_wiki
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class Board < ActiveRecord::Base
|
||||
belongs_to :project
|
||||
|
||||
has_many :lists, -> { order(:list_type, :position) }, dependent: :delete_all
|
||||
has_many :lists, -> { order(:list_type, :position) }, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
validates :project, presence: true
|
||||
|
||||
|
|
|
@ -19,8 +19,8 @@ module Ci
|
|||
)
|
||||
end
|
||||
|
||||
serialize :options # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :yaml_variables, Gitlab::Serializer::Ci::Variables # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :options # rubocop:disable Cop/ActiveRecordSerialize
|
||||
serialize :yaml_variables, Gitlab::Serializer::Ci::Variables # rubocop:disable Cop/ActiveRecordSerialize
|
||||
|
||||
delegate :name, to: :project, prefix: true
|
||||
|
||||
|
@ -186,6 +186,12 @@ module Ci
|
|||
|
||||
# Variables whose value does not depend on environment
|
||||
def simple_variables
|
||||
variables(environment: nil)
|
||||
end
|
||||
|
||||
# All variables, including those dependent on environment, which could
|
||||
# contain unexpanded variables.
|
||||
def variables(environment: persisted_environment)
|
||||
variables = predefined_variables
|
||||
variables += project.predefined_variables
|
||||
variables += pipeline.predefined_variables
|
||||
|
@ -194,15 +200,11 @@ module Ci
|
|||
variables += project.deployment_variables if has_environment?
|
||||
variables += yaml_variables
|
||||
variables += user_variables
|
||||
variables += project.secret_variables_for(ref).map(&:to_runner_variable)
|
||||
variables += secret_variables(environment: environment)
|
||||
variables += trigger_request.user_variables if trigger_request
|
||||
variables
|
||||
end
|
||||
variables += persisted_environment_variables if environment
|
||||
|
||||
# All variables, including those dependent on environment, which could
|
||||
# contain unexpanded variables.
|
||||
def variables
|
||||
simple_variables.concat(persisted_environment_variables)
|
||||
variables
|
||||
end
|
||||
|
||||
def merge_request
|
||||
|
@ -216,7 +218,7 @@ module Ci
|
|||
.reorder(iid: :desc)
|
||||
|
||||
merge_requests.find do |merge_request|
|
||||
merge_request.commits_sha.include?(pipeline.sha)
|
||||
merge_request.commit_shas.include?(pipeline.sha)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -370,6 +372,11 @@ module Ci
|
|||
]
|
||||
end
|
||||
|
||||
def secret_variables(environment: persisted_environment)
|
||||
project.secret_variables_for(ref: ref, environment: environment)
|
||||
.map(&:to_runner_variable)
|
||||
end
|
||||
|
||||
def steps
|
||||
[Gitlab::Ci::Build::Step.from_commands(self),
|
||||
Gitlab::Ci::Build::Step.from_after_script(self)].compact
|
||||
|
|
|
@ -14,7 +14,7 @@ module Ci
|
|||
has_many :stages
|
||||
has_many :statuses, class_name: 'CommitStatus', foreign_key: :commit_id
|
||||
has_many :builds, foreign_key: :commit_id
|
||||
has_many :trigger_requests, dependent: :destroy, foreign_key: :commit_id
|
||||
has_many :trigger_requests, dependent: :destroy, foreign_key: :commit_id # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
# Merge requests for which the current pipeline is running against
|
||||
# the merge request's latest commit.
|
||||
|
|
|
@ -8,7 +8,7 @@ module Ci
|
|||
FORM_EDITABLE = %i[description tag_list active run_untagged locked].freeze
|
||||
|
||||
has_many :builds
|
||||
has_many :runner_projects, dependent: :destroy
|
||||
has_many :runner_projects, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :projects, through: :runner_projects
|
||||
|
||||
has_one :last_build, ->() { order('id DESC') }, class_name: 'Ci::Build'
|
||||
|
|
|
@ -6,7 +6,7 @@ module Ci
|
|||
belongs_to :pipeline, foreign_key: :commit_id
|
||||
has_many :builds
|
||||
|
||||
serialize :variables # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :variables # rubocop:disable Cop/ActiveRecordSerialize
|
||||
|
||||
def user_variables
|
||||
return [] unless variables
|
||||
|
|
|
@ -138,7 +138,7 @@ class Commit
|
|||
|
||||
safe_message.split("\n", 2)[1].try(:chomp)
|
||||
end
|
||||
|
||||
|
||||
def description?
|
||||
description.present?
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@ module Awardable
|
|||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
has_many :award_emoji, -> { includes(:user).order(:id) }, as: :awardable, dependent: :destroy
|
||||
has_many :award_emoji, -> { includes(:user).order(:id) }, as: :awardable, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
if self < Participable
|
||||
# By default we always load award_emoji user association
|
||||
|
|
|
@ -78,7 +78,7 @@ module CacheMarkdownField
|
|||
def cached_html_up_to_date?(markdown_field)
|
||||
html_field = cached_markdown_fields.html_field(markdown_field)
|
||||
|
||||
cached = !cached_html_for(markdown_field).nil? && !__send__(markdown_field).nil?
|
||||
cached = cached_html_for(markdown_field).present? && __send__(markdown_field).present?
|
||||
return false unless cached
|
||||
|
||||
markdown_changed = attribute_changed?(markdown_field) || false
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
module EachBatch
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
module ClassMethods
|
||||
# Iterates over the rows in a relation in batches, similar to Rails'
|
||||
# `in_batches` but in a more efficient way.
|
||||
#
|
||||
# Unlike `in_batches` provided by Rails this method does not support a
|
||||
# custom start/end range, nor does it provide support for the `load:`
|
||||
# keyword argument.
|
||||
#
|
||||
# This method will yield an ActiveRecord::Relation to the supplied block, or
|
||||
# return an Enumerator if no block is given.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# User.each_batch do |relation|
|
||||
# relation.update_all(updated_at: Time.now)
|
||||
# end
|
||||
#
|
||||
# This will produce SQL queries along the lines of:
|
||||
#
|
||||
# User Load (0.7ms) SELECT "users"."id" FROM "users" WHERE ("users"."id" >= 41654) ORDER BY "users"."id" ASC LIMIT 1 OFFSET 1000
|
||||
# (0.7ms) SELECT COUNT(*) FROM "users" WHERE ("users"."id" >= 41654) AND ("users"."id" < 42687)
|
||||
#
|
||||
# of - The number of rows to retrieve per batch.
|
||||
def each_batch(of: 1000)
|
||||
start = except(:select)
|
||||
.select(primary_key)
|
||||
.reorder(primary_key => :asc)
|
||||
.take
|
||||
|
||||
return unless start
|
||||
|
||||
start_id = start[primary_key]
|
||||
arel_table = self.arel_table
|
||||
|
||||
loop do
|
||||
stop = except(:select)
|
||||
.select(primary_key)
|
||||
.where(arel_table[primary_key].gteq(start_id))
|
||||
.reorder(primary_key => :asc)
|
||||
.offset(of)
|
||||
.limit(1)
|
||||
.take
|
||||
|
||||
relation = where(arel_table[primary_key].gteq(start_id))
|
||||
|
||||
if stop
|
||||
stop_id = stop[primary_key]
|
||||
start_id = stop_id
|
||||
relation = relation.where(arel_table[primary_key].lt(stop_id))
|
||||
end
|
||||
|
||||
# Any ORDER BYs are useless for this relation and can lead to less
|
||||
# efficient UPDATE queries, hence we get rid of it.
|
||||
yield relation.except(:order)
|
||||
|
||||
break unless stop
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -30,7 +30,7 @@ module Issuable
|
|||
belongs_to :updated_by, class_name: "User"
|
||||
belongs_to :last_edited_by, class_name: 'User'
|
||||
belongs_to :milestone
|
||||
has_many :notes, as: :noteable, inverse_of: :noteable, dependent: :destroy do
|
||||
has_many :notes, as: :noteable, inverse_of: :noteable, dependent: :destroy do # rubocop:disable Cop/ActiveRecordDependent
|
||||
def authors_loaded?
|
||||
# We check first if we're loaded to not load unnecessarily.
|
||||
loaded? && to_a.all? { |note| note.association(:author).loaded? }
|
||||
|
@ -42,9 +42,9 @@ module Issuable
|
|||
end
|
||||
end
|
||||
|
||||
has_many :label_links, as: :target, dependent: :destroy
|
||||
has_many :label_links, as: :target, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :labels, through: :label_links
|
||||
has_many :todos, as: :target, dependent: :destroy
|
||||
has_many :todos, as: :target, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
has_one :metrics
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ module ProtectedRef
|
|||
class_methods do
|
||||
def protected_ref_access_levels(*types)
|
||||
types.each do |type|
|
||||
has_many :"#{type}_access_levels", dependent: :destroy
|
||||
has_many :"#{type}_access_levels", dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
validates :"#{type}_access_levels", length: { is: 1, message: "are restricted to a single instance per #{self.model_name.human}." }
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@ module Routable
|
|||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
has_one :route, as: :source, autosave: true, dependent: :destroy
|
||||
has_many :redirect_routes, as: :source, autosave: true, dependent: :destroy
|
||||
has_one :route, as: :source, autosave: true, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :redirect_routes, as: :source, autosave: true, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
validates_associated :route
|
||||
validates :route, presence: true
|
||||
|
|
|
@ -8,7 +8,7 @@ module Spammable
|
|||
end
|
||||
|
||||
included do
|
||||
has_one :user_agent_detail, as: :subject, dependent: :destroy
|
||||
has_one :user_agent_detail, as: :subject, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
attr_accessor :spam
|
||||
attr_accessor :spam_log
|
||||
|
|
|
@ -9,7 +9,7 @@ module Subscribable
|
|||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
has_many :subscriptions, dependent: :destroy, as: :subscribable
|
||||
has_many :subscriptions, dependent: :destroy, as: :subscribable # rubocop:disable Cop/ActiveRecordDependent
|
||||
end
|
||||
|
||||
def subscribed?(user, project = nil)
|
||||
|
|
|
@ -18,7 +18,7 @@ module TimeTrackable
|
|||
validates :time_estimate, numericality: { message: 'has an invalid format' }, allow_nil: false
|
||||
validate :check_negative_time_spent
|
||||
|
||||
has_many :timelogs, dependent: :destroy
|
||||
has_many :timelogs, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
end
|
||||
|
||||
def spend_time(options)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class DeployKey < Key
|
||||
has_many :deploy_keys_projects, dependent: :destroy
|
||||
has_many :deploy_keys_projects, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :projects, through: :deploy_keys_projects
|
||||
|
||||
scope :in_projects, ->(projects) { joins(:deploy_keys_projects).where('deploy_keys_projects.project_id in (?)', projects) }
|
||||
|
|
|
@ -6,9 +6,9 @@ class DiffNote < Note
|
|||
|
||||
NOTEABLE_TYPES = %w(MergeRequest Commit).freeze
|
||||
|
||||
serialize :original_position, Gitlab::Diff::Position # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :position, Gitlab::Diff::Position # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :change_position, Gitlab::Diff::Position # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :original_position, Gitlab::Diff::Position # rubocop:disable Cop/ActiveRecordSerialize
|
||||
serialize :position, Gitlab::Diff::Position # rubocop:disable Cop/ActiveRecordSerialize
|
||||
serialize :change_position, Gitlab::Diff::Position # rubocop:disable Cop/ActiveRecordSerialize
|
||||
|
||||
validates :original_position, presence: true
|
||||
validates :position, presence: true
|
||||
|
|
|
@ -6,7 +6,7 @@ class Environment < ActiveRecord::Base
|
|||
|
||||
belongs_to :project, required: true, validate: true
|
||||
|
||||
has_many :deployments, dependent: :destroy
|
||||
has_many :deployments, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_one :last_deployment, -> { order('deployments.id DESC') }, class_name: 'Deployment'
|
||||
|
||||
before_validation :nullify_external_url
|
||||
|
|
|
@ -50,7 +50,7 @@ class Event < ActiveRecord::Base
|
|||
belongs_to :target, polymorphic: true # rubocop:disable Cop/PolymorphicAssociations
|
||||
|
||||
# For Hash only
|
||||
serialize :data # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :data # rubocop:disable Cop/ActiveRecordSerialize
|
||||
|
||||
# Callbacks
|
||||
after_create :reset_project_activity
|
||||
|
|
|
@ -8,7 +8,7 @@ class Group < Namespace
|
|||
include Referable
|
||||
include SelectForProjectAuthorization
|
||||
|
||||
has_many :group_members, -> { where(requested_at: nil) }, dependent: :destroy, as: :source
|
||||
has_many :group_members, -> { where(requested_at: nil) }, dependent: :destroy, as: :source # rubocop:disable Cop/ActiveRecordDependent
|
||||
alias_method :members, :group_members
|
||||
has_many :users, through: :group_members
|
||||
has_many :owners,
|
||||
|
@ -16,11 +16,11 @@ class Group < Namespace
|
|||
through: :group_members,
|
||||
source: :user
|
||||
|
||||
has_many :requesters, -> { where.not(requested_at: nil) }, dependent: :destroy, as: :source, class_name: 'GroupMember'
|
||||
has_many :requesters, -> { where.not(requested_at: nil) }, dependent: :destroy, as: :source, class_name: 'GroupMember' # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
has_many :project_group_links, dependent: :destroy
|
||||
has_many :project_group_links, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :shared_projects, through: :project_group_links, source: :project
|
||||
has_many :notification_settings, dependent: :destroy, as: :source
|
||||
has_many :notification_settings, dependent: :destroy, as: :source # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :labels, class_name: 'GroupLabel'
|
||||
|
||||
validate :avatar_type, if: ->(user) { user.avatar.present? && user.avatar_changed? }
|
||||
|
@ -31,7 +31,7 @@ class Group < Namespace
|
|||
validates :two_factor_grace_period, presence: true, numericality: { greater_than_or_equal_to: 0 }
|
||||
|
||||
mount_uploader :avatar, AvatarUploader
|
||||
has_many :uploads, as: :model, dependent: :destroy
|
||||
has_many :uploads, as: :model, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
after_create :post_create_hook
|
||||
after_destroy :post_destroy_hook
|
||||
|
|
|
@ -12,7 +12,7 @@ class WebHook < ActiveRecord::Base
|
|||
default_value_for :repository_update_events, false
|
||||
default_value_for :enable_ssl_verification, true
|
||||
|
||||
has_many :web_hook_logs, dependent: :destroy
|
||||
has_many :web_hook_logs, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
scope :push_hooks, -> { where(push_events: true) }
|
||||
scope :tag_push_hooks, -> { where(tag_push_events: true) }
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
class WebHookLog < ActiveRecord::Base
|
||||
belongs_to :web_hook
|
||||
|
||||
serialize :request_headers, Hash # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :request_data, Hash # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :response_headers, Hash # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :request_headers, Hash # rubocop:disable Cop/ActiveRecordSerialize
|
||||
serialize :request_data, Hash # rubocop:disable Cop/ActiveRecordSerialize
|
||||
serialize :response_headers, Hash # rubocop:disable Cop/ActiveRecordSerialize
|
||||
|
||||
validates :web_hook, presence: true
|
||||
|
||||
|
|
|
@ -23,9 +23,14 @@ class Issue < ActiveRecord::Base
|
|||
belongs_to :project
|
||||
belongs_to :moved_to, class_name: 'Issue'
|
||||
|
||||
has_many :events, as: :target, dependent: :destroy
|
||||
has_many :events, as: :target, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
has_many :merge_requests_closing_issues, class_name: 'MergeRequestsClosingIssues', dependent: :delete_all
|
||||
has_many :merge_requests_closing_issues,
|
||||
class_name: 'MergeRequestsClosingIssues',
|
||||
dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
has_many :issue_assignees
|
||||
has_many :assignees, class_name: "User", through: :issue_assignees
|
||||
|
||||
has_many :issue_assignees
|
||||
has_many :assignees, class_name: "User", through: :issue_assignees
|
||||
|
|
|
@ -15,9 +15,9 @@ class Label < ActiveRecord::Base
|
|||
|
||||
default_value_for :color, DEFAULT_COLOR
|
||||
|
||||
has_many :lists, dependent: :destroy
|
||||
has_many :lists, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :priorities, class_name: 'LabelPriority'
|
||||
has_many :label_links, dependent: :destroy
|
||||
has_many :label_links, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :issues, through: :label_links, source: :target, source_type: 'Issue'
|
||||
has_many :merge_requests, through: :label_links, source: :target, source_type: 'MergeRequest'
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
class LegacyDiffNote < Note
|
||||
include NoteOnDiff
|
||||
|
||||
serialize :st_diff # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :st_diff # rubocop:disable Cop/ActiveRecordSerialize
|
||||
|
||||
validates :line_code, presence: true, line_code: true
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class LfsObject < ActiveRecord::Base
|
||||
has_many :lfs_objects_projects, dependent: :destroy
|
||||
has_many :lfs_objects_projects, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :projects, through: :lfs_objects_projects
|
||||
|
||||
validates :oid, presence: true, uniqueness: true
|
||||
|
|
|
@ -12,24 +12,26 @@ class MergeRequest < ActiveRecord::Base
|
|||
belongs_to :source_project, class_name: "Project"
|
||||
belongs_to :merge_user, class_name: "User"
|
||||
|
||||
has_many :merge_request_diffs, dependent: :destroy
|
||||
has_many :merge_request_diffs
|
||||
has_one :merge_request_diff,
|
||||
-> { order('merge_request_diffs.id DESC') }
|
||||
|
||||
belongs_to :head_pipeline, foreign_key: "head_pipeline_id", class_name: "Ci::Pipeline"
|
||||
|
||||
has_many :events, as: :target, dependent: :destroy
|
||||
has_many :events, as: :target, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
has_many :merge_requests_closing_issues, class_name: 'MergeRequestsClosingIssues', dependent: :delete_all
|
||||
has_many :merge_requests_closing_issues,
|
||||
class_name: 'MergeRequestsClosingIssues',
|
||||
dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
belongs_to :assignee, class_name: "User"
|
||||
|
||||
serialize :merge_params, Hash # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :merge_params, Hash # rubocop:disable Cop/ActiveRecordSerialize
|
||||
|
||||
after_create :ensure_merge_request_diff, unless: :importing?
|
||||
after_update :reload_diff_if_branch_changed
|
||||
|
||||
delegate :commits, :real_size, :commits_sha, :commits_count,
|
||||
delegate :commits, :real_size, :commit_shas, :commits_count,
|
||||
to: :merge_request_diff, prefix: nil
|
||||
|
||||
# When this attribute is true some MR validation is ignored
|
||||
|
@ -516,7 +518,7 @@ class MergeRequest < ActiveRecord::Base
|
|||
def related_notes
|
||||
# Fetch comments only from last 100 commits
|
||||
commits_for_notes_limit = 100
|
||||
commit_ids = commits.last(commits_for_notes_limit).map(&:id)
|
||||
commit_ids = commit_shas.take(commits_for_notes_limit)
|
||||
|
||||
Note.where(
|
||||
"(project_id = :target_project_id AND noteable_type = 'MergeRequest' AND noteable_id = :mr_id) OR" +
|
||||
|
@ -839,15 +841,15 @@ class MergeRequest < ActiveRecord::Base
|
|||
return Ci::Pipeline.none unless source_project
|
||||
|
||||
@all_pipelines ||= source_project.pipelines
|
||||
.where(sha: all_commits_sha, ref: source_branch)
|
||||
.where(sha: all_commit_shas, ref: source_branch)
|
||||
.order(id: :desc)
|
||||
end
|
||||
|
||||
# Note that this could also return SHA from now dangling commits
|
||||
#
|
||||
def all_commits_sha
|
||||
def all_commit_shas
|
||||
if persisted?
|
||||
merge_request_diffs.flat_map(&:commits_sha).uniq
|
||||
merge_request_diffs.preload(:merge_request_diff_commits).flat_map(&:commit_shas).uniq
|
||||
elsif compare_commits
|
||||
compare_commits.to_a.reverse.map(&:id)
|
||||
else
|
||||
|
|
|
@ -11,9 +11,10 @@ class MergeRequestDiff < ActiveRecord::Base
|
|||
|
||||
belongs_to :merge_request
|
||||
has_many :merge_request_diff_files, -> { order(:merge_request_diff_id, :relative_order) }
|
||||
has_many :merge_request_diff_commits, -> { order(:merge_request_diff_id, :relative_order) }
|
||||
|
||||
serialize :st_commits # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :st_diffs # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :st_commits # rubocop:disable Cop/ActiveRecordSerialize
|
||||
serialize :st_diffs # rubocop:disable Cop/ActiveRecordSerialize
|
||||
|
||||
state_machine :state, initial: :empty do
|
||||
state :collected
|
||||
|
@ -47,14 +48,13 @@ class MergeRequestDiff < ActiveRecord::Base
|
|||
# Collect information about commits and diff from repository
|
||||
# and save it to the database as serialized data
|
||||
def save_git_content
|
||||
ensure_commits_sha
|
||||
ensure_commit_shas
|
||||
save_commits
|
||||
reload_commits
|
||||
save_diffs
|
||||
keep_around_commits
|
||||
end
|
||||
|
||||
def ensure_commits_sha
|
||||
def ensure_commit_shas
|
||||
merge_request.fetch_ref
|
||||
self.start_commit_sha ||= merge_request.target_branch_sha
|
||||
self.head_commit_sha ||= merge_request.source_branch_sha
|
||||
|
@ -66,7 +66,7 @@ class MergeRequestDiff < ActiveRecord::Base
|
|||
# created before version 8.4 that does not store head_commit_sha in separate db field.
|
||||
def head_commit_sha
|
||||
if persisted? && super.nil?
|
||||
last_commit.try(:sha)
|
||||
last_commit_sha
|
||||
else
|
||||
super
|
||||
end
|
||||
|
@ -97,16 +97,11 @@ class MergeRequestDiff < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def commits
|
||||
@commits ||= load_commits(st_commits)
|
||||
@commits ||= load_commits
|
||||
end
|
||||
|
||||
def reload_commits
|
||||
@commits = nil
|
||||
commits
|
||||
end
|
||||
|
||||
def last_commit
|
||||
commits.first
|
||||
def last_commit_sha
|
||||
commit_shas.first
|
||||
end
|
||||
|
||||
def first_commit
|
||||
|
@ -131,8 +126,12 @@ class MergeRequestDiff < ActiveRecord::Base
|
|||
project.commit(head_commit_sha)
|
||||
end
|
||||
|
||||
def commits_sha
|
||||
st_commits.map { |commit| commit[:id] }
|
||||
def commit_shas
|
||||
if st_commits.present?
|
||||
st_commits.map { |commit| commit[:id] }
|
||||
else
|
||||
merge_request_diff_commits.map(&:sha)
|
||||
end
|
||||
end
|
||||
|
||||
def diff_refs=(new_diff_refs)
|
||||
|
@ -207,7 +206,11 @@ class MergeRequestDiff < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def commits_count
|
||||
st_commits.count
|
||||
if st_commits.present?
|
||||
st_commits.size
|
||||
else
|
||||
merge_request_diff_commits.size
|
||||
end
|
||||
end
|
||||
|
||||
def utf8_st_diffs
|
||||
|
@ -231,29 +234,6 @@ class MergeRequestDiff < ActiveRecord::Base
|
|||
raw.any? { |element| VALID_CLASSES.include?(element.class) }
|
||||
end
|
||||
|
||||
def dump_commits(commits)
|
||||
commits.map(&:to_hash)
|
||||
end
|
||||
|
||||
def load_commits(array)
|
||||
array.map { |hash| Commit.new(Gitlab::Git::Commit.new(hash), merge_request.source_project) }
|
||||
end
|
||||
|
||||
# Load all commits related to current merge request diff from repo
|
||||
# and save it as array of hashes in st_commits db field
|
||||
def save_commits
|
||||
new_attributes = {}
|
||||
|
||||
commits = compare.commits
|
||||
|
||||
if commits.present?
|
||||
commits = Commit.decorate(commits, merge_request.source_project).reverse
|
||||
new_attributes[:st_commits] = dump_commits(commits)
|
||||
end
|
||||
|
||||
update_columns_serialized(new_attributes)
|
||||
end
|
||||
|
||||
def create_merge_request_diff_files(diffs)
|
||||
rows = diffs.map.with_index do |diff, index|
|
||||
diff.to_hash.merge(
|
||||
|
@ -294,12 +274,18 @@ class MergeRequestDiff < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
# Load diffs between branches related to current merge request diff from repo
|
||||
# and save it as array of hashes in st_diffs db field
|
||||
def load_commits
|
||||
commits = st_commits.presence || merge_request_diff_commits
|
||||
|
||||
commits.map do |commit|
|
||||
Commit.new(Gitlab::Git::Commit.new(commit.to_hash), merge_request.source_project)
|
||||
end
|
||||
end
|
||||
|
||||
def save_diffs
|
||||
new_attributes = {}
|
||||
|
||||
if commits.size.zero?
|
||||
if compare.commits.size.zero?
|
||||
new_attributes[:state] = :empty
|
||||
else
|
||||
diff_collection = compare.diffs(Commit.max_diff_options)
|
||||
|
@ -319,7 +305,13 @@ class MergeRequestDiff < ActiveRecord::Base
|
|||
new_attributes[:state] = :overflow if diff_collection.overflow?
|
||||
end
|
||||
|
||||
update_columns_serialized(new_attributes)
|
||||
update(new_attributes)
|
||||
end
|
||||
|
||||
def save_commits
|
||||
MergeRequestDiffCommit.create_bulk(self.id, compare.commits.reverse)
|
||||
|
||||
merge_request_diff_commits.reload
|
||||
end
|
||||
|
||||
def repository
|
||||
|
@ -332,29 +324,6 @@ class MergeRequestDiff < ActiveRecord::Base
|
|||
project.merge_base_commit(head_commit_sha, start_commit_sha).try(:sha)
|
||||
end
|
||||
|
||||
#
|
||||
# #save or #update_attributes providing changes on serialized attributes do a lot of
|
||||
# serialization and deserialization calls resulting in bad performance.
|
||||
# Using #update_columns solves the problem with just one YAML.dump per serialized attribute that we provide.
|
||||
# As a tradeoff we need to reload the current instance to properly manage time objects on those serialized
|
||||
# attributes. So to keep the same behaviour as the attribute assignment we reload the instance.
|
||||
# The difference is in the usage of
|
||||
# #write_attribute= (#update_attributes) and #raw_write_attribute= (#update_columns)
|
||||
#
|
||||
# Ex:
|
||||
#
|
||||
# new_attributes[:st_commits].first.slice(:committed_date)
|
||||
# => {:committed_date=>2014-02-27 11:01:38 +0200}
|
||||
# YAML.load(YAML.dump(new_attributes[:st_commits].first.slice(:committed_date)))
|
||||
# => {:committed_date=>2014-02-27 10:01:38 +0100}
|
||||
#
|
||||
def update_columns_serialized(new_attributes)
|
||||
return unless new_attributes.any?
|
||||
|
||||
update_columns(new_attributes.merge(updated_at: current_time_from_proper_timezone))
|
||||
reload
|
||||
end
|
||||
|
||||
def keep_around_commits
|
||||
[repository, merge_request.source_project.repository].each do |repo|
|
||||
repo.keep_around(start_commit_sha)
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
class MergeRequestDiffCommit < ActiveRecord::Base
|
||||
include ShaAttribute
|
||||
|
||||
belongs_to :merge_request_diff
|
||||
|
||||
sha_attribute :sha
|
||||
alias_attribute :id, :sha
|
||||
|
||||
def self.create_bulk(merge_request_diff_id, commits)
|
||||
sha_attribute = Gitlab::Database::ShaAttribute.new
|
||||
|
||||
rows = commits.map.with_index do |commit, index|
|
||||
# See #parent_ids.
|
||||
commit_hash = commit.to_hash.except(:parent_ids)
|
||||
sha = commit_hash.delete(:id)
|
||||
|
||||
commit_hash.merge(
|
||||
merge_request_diff_id: merge_request_diff_id,
|
||||
relative_order: index,
|
||||
sha: sha_attribute.type_cast_for_database(sha)
|
||||
)
|
||||
end
|
||||
|
||||
Gitlab::Database.bulk_insert(self.table_name, rows)
|
||||
end
|
||||
|
||||
def to_hash
|
||||
Gitlab::Git::Commit::SERIALIZE_KEYS.each_with_object({}) do |key, hash|
|
||||
hash[key] = public_send(key)
|
||||
end
|
||||
end
|
||||
|
||||
# We don't save these, because they would need a table or a serialised
|
||||
# field. They aren't used anywhere, so just pretend the commit has no parents.
|
||||
def parent_ids
|
||||
[]
|
||||
end
|
||||
end
|
|
@ -21,7 +21,7 @@ class Milestone < ActiveRecord::Base
|
|||
has_many :issues
|
||||
has_many :labels, -> { distinct.reorder('labels.title') }, through: :issues
|
||||
has_many :merge_requests
|
||||
has_many :events, as: :target, dependent: :destroy
|
||||
has_many :events, as: :target, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
scope :active, -> { with_state(:active) }
|
||||
scope :closed, -> { with_state(:closed) }
|
||||
|
|
|
@ -15,13 +15,13 @@ class Namespace < ActiveRecord::Base
|
|||
|
||||
cache_markdown_field :description, pipeline: :description
|
||||
|
||||
has_many :projects, dependent: :destroy
|
||||
has_many :projects, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :project_statistics
|
||||
belongs_to :owner, class_name: "User"
|
||||
|
||||
belongs_to :parent, class_name: "Namespace"
|
||||
has_many :children, class_name: "Namespace", foreign_key: :parent_id
|
||||
has_one :chat_team, dependent: :destroy
|
||||
has_one :chat_team, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
validates :owner, presence: true, unless: ->(n) { n.type == "Group" }
|
||||
validates :name,
|
||||
|
|
|
@ -46,8 +46,8 @@ class Note < ActiveRecord::Base
|
|||
belongs_to :updated_by, class_name: "User"
|
||||
belongs_to :last_edited_by, class_name: 'User'
|
||||
|
||||
has_many :todos, dependent: :destroy
|
||||
has_many :events, as: :target, dependent: :destroy
|
||||
has_many :todos, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :events, as: :target, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_one :system_note_metadata
|
||||
|
||||
delegate :gfm_reference, :local_reference, to: :noteable
|
||||
|
|
|
@ -3,7 +3,7 @@ class PersonalAccessToken < ActiveRecord::Base
|
|||
include TokenAuthenticatable
|
||||
add_authentication_token_field :token
|
||||
|
||||
serialize :scopes, Array # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :scopes, Array # rubocop:disable Cop/ActiveRecordSerialize
|
||||
|
||||
belongs_to :user
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ class Project < ActiveRecord::Base
|
|||
update_column(:last_repository_updated_at, self.created_at)
|
||||
end
|
||||
|
||||
before_destroy :remove_private_deploy_keys
|
||||
after_destroy :remove_pages
|
||||
|
||||
# update visibility_level of forks
|
||||
|
@ -80,96 +81,108 @@ class Project < ActiveRecord::Base
|
|||
belongs_to :namespace
|
||||
|
||||
has_one :last_event, -> {order 'events.created_at DESC'}, class_name: 'Event'
|
||||
has_many :boards, before_add: :validate_board_limit, dependent: :destroy
|
||||
has_many :boards, before_add: :validate_board_limit
|
||||
|
||||
# Project services
|
||||
has_one :campfire_service, dependent: :destroy
|
||||
has_one :drone_ci_service, dependent: :destroy
|
||||
has_one :emails_on_push_service, dependent: :destroy
|
||||
has_one :pipelines_email_service, dependent: :destroy
|
||||
has_one :irker_service, dependent: :destroy
|
||||
has_one :pivotaltracker_service, dependent: :destroy
|
||||
has_one :hipchat_service, dependent: :destroy
|
||||
has_one :flowdock_service, dependent: :destroy
|
||||
has_one :assembla_service, dependent: :destroy
|
||||
has_one :asana_service, dependent: :destroy
|
||||
has_one :gemnasium_service, dependent: :destroy
|
||||
has_one :mattermost_slash_commands_service, dependent: :destroy
|
||||
has_one :mattermost_service, dependent: :destroy
|
||||
has_one :slack_slash_commands_service, dependent: :destroy
|
||||
has_one :slack_service, dependent: :destroy
|
||||
has_one :buildkite_service, dependent: :destroy
|
||||
has_one :bamboo_service, dependent: :destroy
|
||||
has_one :teamcity_service, dependent: :destroy
|
||||
has_one :pushover_service, dependent: :destroy
|
||||
has_one :jira_service, dependent: :destroy
|
||||
has_one :redmine_service, dependent: :destroy
|
||||
has_one :custom_issue_tracker_service, dependent: :destroy
|
||||
has_one :bugzilla_service, dependent: :destroy
|
||||
has_one :gitlab_issue_tracker_service, dependent: :destroy, inverse_of: :project
|
||||
has_one :external_wiki_service, dependent: :destroy
|
||||
has_one :kubernetes_service, dependent: :destroy, inverse_of: :project
|
||||
has_one :prometheus_service, dependent: :destroy, inverse_of: :project
|
||||
has_one :mock_ci_service, dependent: :destroy
|
||||
has_one :mock_deployment_service, dependent: :destroy
|
||||
has_one :mock_monitoring_service, dependent: :destroy
|
||||
has_one :microsoft_teams_service, dependent: :destroy
|
||||
has_one :campfire_service
|
||||
has_one :drone_ci_service
|
||||
has_one :emails_on_push_service
|
||||
has_one :pipelines_email_service
|
||||
has_one :irker_service
|
||||
has_one :pivotaltracker_service
|
||||
has_one :hipchat_service
|
||||
has_one :flowdock_service
|
||||
has_one :assembla_service
|
||||
has_one :asana_service
|
||||
has_one :gemnasium_service
|
||||
has_one :mattermost_slash_commands_service
|
||||
has_one :mattermost_service
|
||||
has_one :slack_slash_commands_service
|
||||
has_one :slack_service
|
||||
has_one :buildkite_service
|
||||
has_one :bamboo_service
|
||||
has_one :teamcity_service
|
||||
has_one :pushover_service
|
||||
has_one :jira_service
|
||||
has_one :redmine_service
|
||||
has_one :custom_issue_tracker_service
|
||||
has_one :bugzilla_service
|
||||
has_one :gitlab_issue_tracker_service, inverse_of: :project
|
||||
has_one :external_wiki_service
|
||||
has_one :kubernetes_service, inverse_of: :project
|
||||
has_one :prometheus_service, inverse_of: :project
|
||||
has_one :mock_ci_service
|
||||
has_one :mock_deployment_service
|
||||
has_one :mock_monitoring_service
|
||||
has_one :microsoft_teams_service
|
||||
|
||||
has_one :forked_project_link, dependent: :destroy, foreign_key: "forked_to_project_id"
|
||||
has_one :forked_project_link, foreign_key: "forked_to_project_id"
|
||||
has_one :forked_from_project, through: :forked_project_link
|
||||
|
||||
has_many :forked_project_links, foreign_key: "forked_from_project_id"
|
||||
has_many :forks, through: :forked_project_links, source: :forked_to_project
|
||||
|
||||
# Merge Requests for target project should be removed with it
|
||||
has_many :merge_requests, dependent: :destroy, foreign_key: 'target_project_id'
|
||||
has_many :issues, dependent: :destroy
|
||||
has_many :labels, dependent: :destroy, class_name: 'ProjectLabel'
|
||||
has_many :services, dependent: :destroy
|
||||
has_many :events, dependent: :destroy
|
||||
has_many :milestones, dependent: :destroy
|
||||
has_many :notes, dependent: :destroy
|
||||
has_many :snippets, dependent: :destroy, class_name: 'ProjectSnippet'
|
||||
has_many :hooks, dependent: :destroy, class_name: 'ProjectHook'
|
||||
has_many :protected_branches, dependent: :destroy
|
||||
has_many :protected_tags, dependent: :destroy
|
||||
has_many :merge_requests, foreign_key: 'target_project_id'
|
||||
has_many :issues
|
||||
has_many :labels, class_name: 'ProjectLabel'
|
||||
has_many :services
|
||||
has_many :events
|
||||
has_many :milestones
|
||||
has_many :notes
|
||||
has_many :snippets, class_name: 'ProjectSnippet'
|
||||
has_many :hooks, class_name: 'ProjectHook'
|
||||
has_many :protected_branches
|
||||
has_many :protected_tags
|
||||
|
||||
has_many :project_authorizations
|
||||
has_many :authorized_users, through: :project_authorizations, source: :user, class_name: 'User'
|
||||
has_many :project_members, -> { where(requested_at: nil) }, dependent: :destroy, as: :source
|
||||
has_many :project_members, -> { where(requested_at: nil) },
|
||||
as: :source, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
alias_method :members, :project_members
|
||||
has_many :users, through: :project_members
|
||||
|
||||
has_many :requesters, -> { where.not(requested_at: nil) }, dependent: :destroy, as: :source, class_name: 'ProjectMember'
|
||||
has_many :requesters, -> { where.not(requested_at: nil) },
|
||||
as: :source, class_name: 'ProjectMember', dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
has_many :deploy_keys_projects, dependent: :destroy
|
||||
has_many :deploy_keys_projects
|
||||
has_many :deploy_keys, through: :deploy_keys_projects
|
||||
has_many :users_star_projects, dependent: :destroy
|
||||
has_many :users_star_projects
|
||||
has_many :starrers, through: :users_star_projects, source: :user
|
||||
has_many :releases, dependent: :destroy
|
||||
has_many :lfs_objects_projects, dependent: :destroy
|
||||
has_many :releases
|
||||
has_many :lfs_objects_projects, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :lfs_objects, through: :lfs_objects_projects
|
||||
has_many :project_group_links, dependent: :destroy
|
||||
has_many :project_group_links
|
||||
has_many :invited_groups, through: :project_group_links, source: :group
|
||||
has_many :pages_domains, dependent: :destroy
|
||||
has_many :todos, dependent: :destroy
|
||||
has_many :notification_settings, dependent: :destroy, as: :source
|
||||
has_many :pages_domains
|
||||
has_many :todos
|
||||
has_many :notification_settings, as: :source, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
has_one :import_data, dependent: :delete, class_name: 'ProjectImportData'
|
||||
has_one :project_feature, dependent: :destroy
|
||||
has_one :statistics, class_name: 'ProjectStatistics', dependent: :delete
|
||||
has_many :container_repositories, dependent: :destroy
|
||||
has_one :import_data, class_name: 'ProjectImportData'
|
||||
has_one :project_feature
|
||||
has_one :statistics, class_name: 'ProjectStatistics'
|
||||
|
||||
has_many :commit_statuses, dependent: :destroy
|
||||
has_many :pipelines, dependent: :destroy, class_name: 'Ci::Pipeline'
|
||||
has_many :builds, class_name: 'Ci::Build' # the builds are created from the commit_statuses
|
||||
has_many :runner_projects, dependent: :destroy, class_name: 'Ci::RunnerProject'
|
||||
# Container repositories need to remove data from the container registry,
|
||||
# which is not managed by the DB. Hence we're still using dependent: :destroy
|
||||
# here.
|
||||
has_many :container_repositories, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
has_many :commit_statuses
|
||||
has_many :pipelines, class_name: 'Ci::Pipeline'
|
||||
|
||||
# Ci::Build objects store data on the file system such as artifact files and
|
||||
# build traces. Currently there's no efficient way of removing this data in
|
||||
# bulk that doesn't involve loading the rows into memory. As a result we're
|
||||
# still using `dependent: :destroy` here.
|
||||
has_many :builds, class_name: 'Ci::Build', dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :runner_projects, class_name: 'Ci::RunnerProject'
|
||||
has_many :runners, through: :runner_projects, source: :runner, class_name: 'Ci::Runner'
|
||||
has_many :variables, class_name: 'Ci::Variable'
|
||||
has_many :triggers, dependent: :destroy, class_name: 'Ci::Trigger'
|
||||
has_many :environments, dependent: :destroy
|
||||
has_many :deployments, dependent: :destroy
|
||||
has_many :pipeline_schedules, dependent: :destroy, class_name: 'Ci::PipelineSchedule'
|
||||
has_many :triggers, class_name: 'Ci::Trigger'
|
||||
has_many :environments
|
||||
has_many :deployments
|
||||
has_many :pipeline_schedules, class_name: 'Ci::PipelineSchedule'
|
||||
|
||||
has_many :active_runners, -> { active }, through: :runner_projects, source: :runner, class_name: 'Ci::Runner'
|
||||
|
||||
|
@ -224,7 +237,7 @@ class Project < ActiveRecord::Base
|
|||
before_save :ensure_runners_token
|
||||
|
||||
mount_uploader :avatar, AvatarUploader
|
||||
has_many :uploads, as: :model, dependent: :destroy
|
||||
has_many :uploads, as: :model, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
# Scopes
|
||||
scope :pending_delete, -> { where(pending_delete: true) }
|
||||
|
@ -1240,7 +1253,13 @@ class Project < ActiveRecord::Base
|
|||
File.join(pages_path, 'public')
|
||||
end
|
||||
|
||||
def remove_private_deploy_keys
|
||||
deploy_keys.where(public: false).delete_all
|
||||
end
|
||||
|
||||
def remove_pages
|
||||
::Projects::UpdatePagesConfigurationService.new(self).execute
|
||||
|
||||
# 1. We rename pages to temporary directory
|
||||
# 2. We wait 5 minutes, due to NFS caching
|
||||
# 3. We asynchronously remove pages with force
|
||||
|
@ -1326,7 +1345,8 @@ class Project < ActiveRecord::Base
|
|||
variables
|
||||
end
|
||||
|
||||
def secret_variables_for(ref)
|
||||
def secret_variables_for(ref:, environment: nil)
|
||||
# EE would use the environment
|
||||
if protected_for?(ref)
|
||||
variables
|
||||
else
|
||||
|
|
|
@ -10,7 +10,7 @@ class ProjectImportData < ActiveRecord::Base
|
|||
insecure_mode: true,
|
||||
algorithm: 'aes-256-cbc'
|
||||
|
||||
serialize :data, JSON # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :data, JSON # rubocop:disable Cop/ActiveRecordSerialize
|
||||
|
||||
validates :project, presence: true
|
||||
|
||||
|
|
|
@ -96,10 +96,13 @@ class KubernetesService < DeploymentService
|
|||
end
|
||||
|
||||
def predefined_variables
|
||||
config = YAML.dump(kubeconfig)
|
||||
|
||||
variables = [
|
||||
{ key: 'KUBE_URL', value: api_url, public: true },
|
||||
{ key: 'KUBE_TOKEN', value: token, public: false },
|
||||
{ key: 'KUBE_NAMESPACE', value: actual_namespace, public: true }
|
||||
{ key: 'KUBE_NAMESPACE', value: actual_namespace, public: true },
|
||||
{ key: 'KUBECONFIG', value: config, public: false, file: true }
|
||||
]
|
||||
|
||||
if ca_pem.present?
|
||||
|
@ -135,6 +138,14 @@ class KubernetesService < DeploymentService
|
|||
|
||||
private
|
||||
|
||||
def kubeconfig
|
||||
to_kubeconfig(
|
||||
url: api_url,
|
||||
namespace: actual_namespace,
|
||||
token: token,
|
||||
ca_pem: ca_pem)
|
||||
end
|
||||
|
||||
def namespace_placeholder
|
||||
default_namespace || TEMPLATE_PLACEHOLDER
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@ class SlashCommandsService < Service
|
|||
|
||||
prop_accessor :token
|
||||
|
||||
has_many :chat_names, foreign_key: :service_id, dependent: :destroy
|
||||
has_many :chat_names, foreign_key: :service_id, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
def valid_token?(token)
|
||||
self.respond_to?(:token) &&
|
||||
|
|
|
@ -63,6 +63,10 @@ class ProjectWiki
|
|||
!!repository.exists?
|
||||
end
|
||||
|
||||
def has_home_page?
|
||||
!!find_page('home')
|
||||
end
|
||||
|
||||
# Returns an Array of Gitlab WikiPage instances or an
|
||||
# empty Array if this Wiki has no pages.
|
||||
def pages
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class SentNotification < ActiveRecord::Base
|
||||
serialize :position, Gitlab::Diff::Position # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :position, Gitlab::Diff::Position # rubocop:disable Cop/ActiveRecordSerialize
|
||||
|
||||
belongs_to :project
|
||||
belongs_to :noteable, polymorphic: true # rubocop:disable Cop/PolymorphicAssociations
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# and implement a set of methods
|
||||
class Service < ActiveRecord::Base
|
||||
include Sortable
|
||||
serialize :properties, JSON # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :properties, JSON # rubocop:disable Cop/ActiveRecordSerialize
|
||||
|
||||
default_value_for :active, false
|
||||
default_value_for :push_events, true
|
||||
|
@ -51,6 +51,14 @@ class Service < ActiveRecord::Base
|
|||
active
|
||||
end
|
||||
|
||||
def show_active_box?
|
||||
true
|
||||
end
|
||||
|
||||
def editable?
|
||||
true
|
||||
end
|
||||
|
||||
def template?
|
||||
template
|
||||
end
|
||||
|
|
|
@ -30,7 +30,7 @@ class Snippet < ActiveRecord::Base
|
|||
belongs_to :author, class_name: 'User'
|
||||
belongs_to :project
|
||||
|
||||
has_many :notes, as: :noteable, dependent: :destroy
|
||||
has_many :notes, as: :noteable, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
delegate :name, :email, to: :author, prefix: true, allow_nil: true
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ class User < ActiveRecord::Base
|
|||
otp_secret_encryption_key: Gitlab::Application.secrets.otp_key_base
|
||||
|
||||
devise :two_factor_backupable, otp_number_of_backup_codes: 10
|
||||
serialize :otp_backup_codes, JSON # rubocop:disable Cop/ActiverecordSerialize
|
||||
serialize :otp_backup_codes, JSON # rubocop:disable Cop/ActiveRecordSerialize
|
||||
|
||||
devise :lockable, :recoverable, :rememberable, :trackable,
|
||||
:validatable, :omniauthable, :confirmable, :registerable
|
||||
|
@ -67,24 +67,24 @@ class User < ActiveRecord::Base
|
|||
#
|
||||
|
||||
# Namespace for personal projects
|
||||
has_one :namespace, -> { where type: nil }, dependent: :destroy, foreign_key: :owner_id, autosave: true
|
||||
has_one :namespace, -> { where type: nil }, dependent: :destroy, foreign_key: :owner_id, autosave: true # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
# Profile
|
||||
has_many :keys, -> do
|
||||
type = Key.arel_table[:type]
|
||||
where(type.not_eq('DeployKey').or(type.eq(nil)))
|
||||
end, dependent: :destroy
|
||||
has_many :deploy_keys, -> { where(type: 'DeployKey') }, dependent: :destroy
|
||||
end, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :deploy_keys, -> { where(type: 'DeployKey') }, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
has_many :emails, dependent: :destroy
|
||||
has_many :personal_access_tokens, dependent: :destroy
|
||||
has_many :identities, dependent: :destroy, autosave: true
|
||||
has_many :u2f_registrations, dependent: :destroy
|
||||
has_many :chat_names, dependent: :destroy
|
||||
has_many :emails, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :personal_access_tokens, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :identities, dependent: :destroy, autosave: true # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :u2f_registrations, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :chat_names, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
# Groups
|
||||
has_many :members, dependent: :destroy
|
||||
has_many :group_members, -> { where(requested_at: nil) }, dependent: :destroy, source: 'GroupMember'
|
||||
has_many :members, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :group_members, -> { where(requested_at: nil) }, dependent: :destroy, source: 'GroupMember' # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :groups, through: :group_members
|
||||
has_many :owned_groups, -> { where members: { access_level: Gitlab::Access::OWNER } }, through: :group_members, source: :group
|
||||
has_many :masters_groups, -> { where members: { access_level: Gitlab::Access::MASTER } }, through: :group_members, source: :group
|
||||
|
@ -92,35 +92,35 @@ class User < ActiveRecord::Base
|
|||
# Projects
|
||||
has_many :groups_projects, through: :groups, source: :projects
|
||||
has_many :personal_projects, through: :namespace, source: :projects
|
||||
has_many :project_members, -> { where(requested_at: nil) }, dependent: :destroy
|
||||
has_many :project_members, -> { where(requested_at: nil) }, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :projects, through: :project_members
|
||||
has_many :created_projects, foreign_key: :creator_id, class_name: 'Project'
|
||||
has_many :users_star_projects, dependent: :destroy
|
||||
has_many :users_star_projects, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :starred_projects, through: :users_star_projects, source: :project
|
||||
has_many :project_authorizations
|
||||
has_many :authorized_projects, through: :project_authorizations, source: :project
|
||||
|
||||
has_many :snippets, dependent: :destroy, foreign_key: :author_id
|
||||
has_many :notes, dependent: :destroy, foreign_key: :author_id
|
||||
has_many :issues, dependent: :destroy, foreign_key: :author_id
|
||||
has_many :merge_requests, dependent: :destroy, foreign_key: :author_id
|
||||
has_many :events, dependent: :destroy, foreign_key: :author_id
|
||||
has_many :subscriptions, dependent: :destroy
|
||||
has_many :snippets, dependent: :destroy, foreign_key: :author_id # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :notes, dependent: :destroy, foreign_key: :author_id # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :issues, dependent: :destroy, foreign_key: :author_id # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :merge_requests, dependent: :destroy, foreign_key: :author_id # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :events, dependent: :destroy, foreign_key: :author_id # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :subscriptions, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :recent_events, -> { order "id DESC" }, foreign_key: :author_id, class_name: "Event"
|
||||
has_many :oauth_applications, class_name: 'Doorkeeper::Application', as: :owner, dependent: :destroy
|
||||
has_one :abuse_report, dependent: :destroy, foreign_key: :user_id
|
||||
has_many :reported_abuse_reports, dependent: :destroy, foreign_key: :reporter_id, class_name: "AbuseReport"
|
||||
has_many :spam_logs, dependent: :destroy
|
||||
has_many :builds, dependent: :nullify, class_name: 'Ci::Build'
|
||||
has_many :pipelines, dependent: :nullify, class_name: 'Ci::Pipeline'
|
||||
has_many :todos, dependent: :destroy
|
||||
has_many :notification_settings, dependent: :destroy
|
||||
has_many :award_emoji, dependent: :destroy
|
||||
has_many :triggers, dependent: :destroy, class_name: 'Ci::Trigger', foreign_key: :owner_id
|
||||
has_many :oauth_applications, class_name: 'Doorkeeper::Application', as: :owner, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_one :abuse_report, dependent: :destroy, foreign_key: :user_id # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :reported_abuse_reports, dependent: :destroy, foreign_key: :reporter_id, class_name: "AbuseReport" # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :spam_logs, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :builds, dependent: :nullify, class_name: 'Ci::Build' # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :pipelines, dependent: :nullify, class_name: 'Ci::Pipeline' # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :todos, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :notification_settings, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :award_emoji, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :triggers, dependent: :destroy, class_name: 'Ci::Trigger', foreign_key: :owner_id # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
has_many :issue_assignees
|
||||
has_many :assigned_issues, class_name: "Issue", through: :issue_assignees, source: :issue
|
||||
has_many :assigned_merge_requests, dependent: :nullify, foreign_key: :assignee_id, class_name: "MergeRequest"
|
||||
has_many :assigned_merge_requests, dependent: :nullify, foreign_key: :assignee_id, class_name: "MergeRequest" # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
#
|
||||
# Validations
|
||||
|
@ -211,7 +211,7 @@ class User < ActiveRecord::Base
|
|||
end
|
||||
|
||||
mount_uploader :avatar, AvatarUploader
|
||||
has_many :uploads, as: :model, dependent: :destroy
|
||||
has_many :uploads, as: :model, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
# Scopes
|
||||
scope :admins, -> { where(admin: true) }
|
||||
|
|
|
@ -68,7 +68,7 @@ module MergeRequests
|
|||
if merge_request.source_branch == @branch_name || force_push?
|
||||
merge_request.reload_diff(current_user)
|
||||
else
|
||||
mr_commit_ids = merge_request.commits_sha
|
||||
mr_commit_ids = merge_request.commit_shas
|
||||
push_commit_ids = @commits.map(&:id)
|
||||
matches = mr_commit_ids & push_commit_ids
|
||||
merge_request.reload_diff(current_user) if matches.any?
|
||||
|
@ -128,7 +128,7 @@ module MergeRequests
|
|||
return unless @commits.present?
|
||||
|
||||
merge_requests_for_source_branch.each do |merge_request|
|
||||
mr_commit_ids = Set.new(merge_request.commits_sha)
|
||||
mr_commit_ids = Set.new(merge_request.commit_shas)
|
||||
|
||||
new_commits, existing_commits = @commits.partition do |commit|
|
||||
mr_commit_ids.include?(commit.id)
|
||||
|
@ -144,7 +144,7 @@ module MergeRequests
|
|||
return unless @commits.present?
|
||||
|
||||
merge_requests_for_source_branch.each do |merge_request|
|
||||
commit_shas = merge_request.commits_sha
|
||||
commit_shas = merge_request.commit_shas
|
||||
|
||||
wip_commit = @commits.detect do |commit|
|
||||
commit.work_in_progress? && commit_shas.include?(commit.sha)
|
||||
|
|
|
@ -6,4 +6,7 @@
|
|||
- providers.each do |provider|
|
||||
%span.light
|
||||
- has_icon = provider_has_icon?(provider)
|
||||
= link_to provider_image_tag(provider), omniauth_authorize_path(:user, provider), method: :post, class: (has_icon ? 'oauth-image-link' : 'btn')
|
||||
= link_to provider_image_tag(provider), omniauth_authorize_path(:user, provider), method: :post, class: 'oauth-login' + (has_icon ? ' oauth-image-link' : ' btn'), id: "oauth-login-#{provider}"
|
||||
%fieldset
|
||||
= check_box_tag :remember_me
|
||||
= label_tag :remember_me, 'Remember Me'
|
||||
|
|
|
@ -27,10 +27,11 @@
|
|||
%td.shortcut
|
||||
.key f
|
||||
%td Focus Filter
|
||||
%tr
|
||||
%td.shortcut
|
||||
.key p b
|
||||
%td Show/hide the Performance Bar
|
||||
- if performance_bar_enabled?
|
||||
%tr
|
||||
%td.shortcut
|
||||
.key p b
|
||||
%td Show/hide the Performance Bar
|
||||
%tr
|
||||
%td.shortcut
|
||||
.key ?
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
= stylesheet_link_tag "application", media: "all"
|
||||
= stylesheet_link_tag "print", media: "print"
|
||||
= stylesheet_link_tag "test", media: "all" if Rails.env.test?
|
||||
= stylesheet_link_tag 'peek' if peek_enabled?
|
||||
= stylesheet_link_tag 'performance_bar' if performance_bar_enabled?
|
||||
|
||||
- if show_new_nav?
|
||||
= stylesheet_link_tag "new_nav", media: "all"
|
||||
|
@ -44,7 +44,7 @@
|
|||
= webpack_bundle_tag "main"
|
||||
= webpack_bundle_tag "raven" if current_application_settings.clientside_sentry_enabled
|
||||
= webpack_bundle_tag "test" if Rails.env.test?
|
||||
= webpack_bundle_tag 'peek' if peek_enabled?
|
||||
= webpack_bundle_tag 'performance_bar' if performance_bar_enabled?
|
||||
|
||||
- if content_for?(:page_specific_javascripts)
|
||||
= yield :page_specific_javascripts
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
= render "layouts/head"
|
||||
%body{ class: @body_class, data: { page: body_data_page, project: "#{@project.path if @project}", group: "#{@group.path if @group}" } }
|
||||
= render "layouts/init_auto_complete" if @gfm_form
|
||||
= render 'peek/bar'
|
||||
- if show_new_nav?
|
||||
= render "layouts/header/new"
|
||||
- else
|
||||
|
@ -11,3 +10,5 @@
|
|||
= render 'layouts/page', sidebar: sidebar, nav: nav
|
||||
|
||||
= yield :scripts_body
|
||||
|
||||
= render 'peek/bar'
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
Profile:
|
||||
|
||||
= link_to 'all', url_for(lineprofiler: 'true'), class: 'js-toggle-modal-peek-line-profile'
|
||||
\/
|
||||
= link_to 'app & lib', url_for(lineprofiler: 'app'), class: 'js-toggle-modal-peek-line-profile'
|
||||
\/
|
||||
= link_to 'views', url_for(lineprofiler: 'views'), class: 'js-toggle-modal-peek-line-profile'
|
|
@ -1,13 +1,13 @@
|
|||
%strong
|
||||
%a#peek-show-queries{ href: '#' }
|
||||
%a.js-toggle-modal-peek-sql
|
||||
%span{ data: { defer_to: "#{view.defer_key}-duration" } }...
|
||||
\/
|
||||
%span{ data: { defer_to: "#{view.defer_key}-calls" } }...
|
||||
#modal-peek-pg-queries.modal{ tabindex: -1 }
|
||||
.modal-dialog
|
||||
#modal-peek-pg-queries-content.modal-content
|
||||
.modal-dialog.modal-full
|
||||
.modal-content
|
||||
.modal-header
|
||||
%a.close{ href: "#", "data-dismiss" => "modal" } ×
|
||||
%button.close.btn.btn-link.btn-sm{ type: 'button', data: { dismiss: 'modal' } } X
|
||||
%h4
|
||||
SQL queries
|
||||
.modal-body{ data: { defer_to: "#{view.defer_key}-queries" } }...
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
= icon('info-circle fw')
|
||||
= succeed '.' do
|
||||
To learn more about this project, read
|
||||
= link_to "the wiki", project_wikis_path(viewer.project)
|
||||
= link_to "the wiki", get_project_wiki_path(viewer.project)
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
.panel.panel-default
|
||||
.panel-heading
|
||||
Group members with access to
|
||||
%strong= @group.name
|
||||
%span.badge= members.size
|
||||
- if can?(current_user, :admin_group_member, @group)
|
||||
.controls
|
||||
= link_to 'Manage group members',
|
||||
group_group_members_path(@group),
|
||||
class: 'btn'
|
||||
%ul.content-list
|
||||
= render partial: 'shared/members/member',
|
||||
collection: members.limit(20),
|
||||
as: :member,
|
||||
locals: { show_controls: false }
|
||||
- if members.size > 20
|
||||
%li
|
||||
and #{members.count - 20} more. For full list visit #{link_to 'group members page', group_group_members_path(@group)}
|
|
@ -1,6 +1,6 @@
|
|||
.row.prepend-top-default
|
||||
.col-lg-4.settings-sidebar
|
||||
%h4.prepend-top-0
|
||||
.col-lg-12
|
||||
%h4
|
||||
Project members
|
||||
- if can?(current_user, :admin_project_member, @project)
|
||||
%p
|
||||
|
@ -13,7 +13,6 @@
|
|||
%i Masters
|
||||
or
|
||||
%i Owners
|
||||
.col-lg-8
|
||||
.light
|
||||
- if can?(current_user, :admin_project_member, @project)
|
||||
%ul.nav-links.project-member-tabs{ role: 'tablist' }
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
- @project_group_links.each do |group_links|
|
||||
- shared_group = group_links.group
|
||||
- shared_group_members = shared_group.members
|
||||
- shared_group_users_count = shared_group_members.size
|
||||
.panel.panel-default
|
||||
.panel-heading
|
||||
Shared with
|
||||
%strong= shared_group.name
|
||||
group, members with
|
||||
%strong= group_links.human_access
|
||||
role (#{shared_group_users_count})
|
||||
- if can?(current_user, :admin_group, shared_group)
|
||||
.panel-head-actions
|
||||
= link_to group_group_members_path(shared_group), class: 'btn btn-sm' do
|
||||
%i.fa.fa-pencil-square-o
|
||||
Edit group members
|
||||
%ul.content-list
|
||||
= render partial: 'shared/members/member',
|
||||
collection: shared_group_members.order(access_level: :desc).limit(20),
|
||||
as: :member,
|
||||
locals: { show_controls: false, show_roles: false }
|
||||
- if shared_group_users_count > 20
|
||||
%li
|
||||
and #{shared_group_users_count - 20} more. For full list visit #{link_to 'group members page', group_group_members_path(shared_group)}
|
|
@ -11,16 +11,17 @@
|
|||
.col-lg-9
|
||||
= form_for(@service, as: :service, url: project_service_path(@project, @service.to_param), method: :put, html: { class: 'gl-show-field-errors form-horizontal js-integration-settings-form', data: { 'can-test' => @service.can_test?, 'test-url' => test_project_service_path(@project, @service) } }) do |form|
|
||||
= render 'shared/service_settings', form: form, subject: @service
|
||||
.footer-block.row-content-block
|
||||
%button.btn.btn-save{ type: 'submit' }
|
||||
= icon('spinner spin', class: 'hidden js-btn-spinner')
|
||||
%span.js-btn-label
|
||||
Save changes
|
||||
|
||||
- if @service.valid? && @service.activated?
|
||||
- unless @service.can_test?
|
||||
- disabled_class = 'disabled'
|
||||
- disabled_title = @service.disabled_title
|
||||
- if @service.editable?
|
||||
.footer-block.row-content-block
|
||||
%button.btn.btn-save{ type: 'submit' }
|
||||
= icon('spinner spin', class: 'hidden js-btn-spinner')
|
||||
%span.js-btn-label
|
||||
Save changes
|
||||
|
||||
- if @service.valid? && @service.activated?
|
||||
- unless @service.can_test?
|
||||
- disabled_class = 'disabled'
|
||||
- disabled_title = @service.disabled_title
|
||||
|
||||
= link_to 'Cancel', project_settings_integrations_path(@project), class: 'btn btn-cancel'
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
= auto_discovery_link_tag(:atom, project_commits_url(@project, @ref, rss_url_options), title: "#{@project.name}:#{@ref} commits")
|
||||
= render "projects/commits/head"
|
||||
|
||||
= render 'projects/last_push'
|
||||
|
||||
%div{ class: container_class }
|
||||
%div{ class: [container_class, ("limit-container-width" unless fluid_layout)] }
|
||||
= render 'projects/last_push'
|
||||
= render 'projects/files', commit: @last_commit, project: @project, ref: @ref
|
||||
|
|
|
@ -7,10 +7,11 @@
|
|||
= markdown @service.help
|
||||
|
||||
.service-settings
|
||||
.form-group
|
||||
= form.label :active, "Active", class: "control-label"
|
||||
.col-sm-10
|
||||
= form.check_box :active
|
||||
- if @service.show_active_box?
|
||||
.form-group
|
||||
= form.label :active, "Active", class: "control-label"
|
||||
.col-sm-10
|
||||
= form.check_box :active
|
||||
|
||||
- if @service.supported_events.present?
|
||||
.form-group
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Honor the "Remember me" parameter for OAuth-based login
|
||||
merge_request: 11963
|
||||
author:
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Provide KUBECONFIG from KubernetesService for runners
|
||||
merge_request: 12223
|
||||
author:
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Add user projects API
|
||||
merge_request: 12596
|
||||
author: Ivan Chernov
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Improve the performance of the project list API
|
||||
merge_request: 12679
|
||||
author:
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Add Traditional Chinese in Taiwan translations of Commits Page
|
||||
merge_request: 12407
|
||||
author: Huang Tao
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Cleanup minor UX issues in the performance dashboard
|
||||
merge_request:
|
||||
author:
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Fixed the chart legend not being set correctly
|
||||
merge_request: 12628
|
||||
author:
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Remove two columned layout from project member settings
|
||||
merge_request:
|
||||
author:
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Don't show auxiliary blob viewer for README when there is no wiki
|
||||
merge_request:
|
||||
author:
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Re-enable realtime for environments table
|
||||
merge_request:
|
||||
author:
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Speed up project removals by adding foreign keys with cascading deletes to various tables
|
||||
merge_request:
|
||||
author:
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Upgrade GitLab Workhorse to v2.3.0
|
||||
merge_request: 12676
|
||||
author:
|
|
@ -105,7 +105,7 @@ module Gitlab
|
|||
config.assets.precompile << "katex.css"
|
||||
config.assets.precompile << "katex.js"
|
||||
config.assets.precompile << "xterm/xterm.css"
|
||||
config.assets.precompile << "peek.css"
|
||||
config.assets.precompile << "performance_bar.css"
|
||||
config.assets.precompile << "lib/ace.js"
|
||||
config.assets.precompile << "vendor/assets/fonts/*"
|
||||
config.assets.precompile << "test.css"
|
||||
|
@ -166,8 +166,9 @@ module Gitlab
|
|||
config.after_initialize do
|
||||
Rails.application.reload_routes!
|
||||
|
||||
named_routes_set = Gitlab::Application.routes.named_routes
|
||||
project_url_helpers = Module.new do
|
||||
Gitlab::Application.routes.named_routes.helper_names.each do |name|
|
||||
named_routes_set.helper_names.each do |name|
|
||||
next unless name.include?('namespace_project')
|
||||
|
||||
define_method(name.sub('namespace_project', 'project')) do |project, *args|
|
||||
|
@ -176,6 +177,9 @@ module Gitlab
|
|||
end
|
||||
end
|
||||
|
||||
named_routes_set.url_helpers_module.include project_url_helpers
|
||||
named_routes_set.url_helpers_module.extend project_url_helpers
|
||||
|
||||
Gitlab::Routing.url_helpers.include project_url_helpers
|
||||
Gitlab::Routing.url_helpers.extend project_url_helpers
|
||||
|
||||
|
|
|
@ -619,6 +619,49 @@ test:
|
|||
title: "JIRA"
|
||||
url: https://sample_company.atlassian.net
|
||||
project_key: PROJECT
|
||||
|
||||
omniauth:
|
||||
enabled: true
|
||||
allow_single_sign_on: true
|
||||
external_providers: []
|
||||
|
||||
providers:
|
||||
- { name: 'cas3',
|
||||
label: 'cas3',
|
||||
args: { url: 'https://sso.example.com',
|
||||
disable_ssl_verification: false,
|
||||
login_url: '/cas/login',
|
||||
service_validate_url: '/cas/p3/serviceValidate',
|
||||
logout_url: '/cas/logout'} }
|
||||
- { name: 'github',
|
||||
app_id: 'YOUR_APP_ID',
|
||||
app_secret: 'YOUR_APP_SECRET',
|
||||
url: "https://github.com/",
|
||||
verify_ssl: false,
|
||||
args: { scope: 'user:email' } }
|
||||
- { name: 'bitbucket',
|
||||
app_id: 'YOUR_APP_ID',
|
||||
app_secret: 'YOUR_APP_SECRET' }
|
||||
- { name: 'gitlab',
|
||||
app_id: 'YOUR_APP_ID',
|
||||
app_secret: 'YOUR_APP_SECRET',
|
||||
args: { scope: 'api' } }
|
||||
- { name: 'google_oauth2',
|
||||
app_id: 'YOUR_APP_ID',
|
||||
app_secret: 'YOUR_APP_SECRET',
|
||||
args: { access_type: 'offline', approval_prompt: '' } }
|
||||
- { name: 'facebook',
|
||||
app_id: 'YOUR_APP_ID',
|
||||
app_secret: 'YOUR_APP_SECRET' }
|
||||
- { name: 'twitter',
|
||||
app_id: 'YOUR_APP_ID',
|
||||
app_secret: 'YOUR_APP_SECRET' }
|
||||
- { name: 'auth0',
|
||||
args: {
|
||||
client_id: 'YOUR_AUTH0_CLIENT_ID',
|
||||
client_secret: 'YOUR_AUTH0_CLIENT_SECRET',
|
||||
namespace: 'YOUR_AUTH0_DOMAIN' } }
|
||||
|
||||
ldap:
|
||||
enabled: false
|
||||
servers:
|
||||
|
|
|
@ -1,32 +1,82 @@
|
|||
- group: Kubernetes
|
||||
priority: 1
|
||||
- group: AWS Elastic Load Balancer
|
||||
priority: 10
|
||||
metrics:
|
||||
- title: "Memory usage"
|
||||
y_label: "Values"
|
||||
- title: "Throughput"
|
||||
y_label: "Requests / Sec"
|
||||
required_metrics:
|
||||
- aws_elb_request_count_sum
|
||||
weight: 1
|
||||
queries:
|
||||
- query_range: 'sum(aws_elb_request_count_sum{%{environment_filter}}) * 60'
|
||||
label: Total
|
||||
unit: req / sec
|
||||
- title: "Latency"
|
||||
y_label: "Latency (ms)"
|
||||
required_metrics:
|
||||
- aws_elb_latency_average
|
||||
weight: 1
|
||||
queries:
|
||||
- query_range: 'avg(aws_elb_latency_average{%{environment_filter}}) * 1000'
|
||||
label: Average
|
||||
unit: ms
|
||||
- title: "HTTP Error Rate"
|
||||
y_label: "Error Rate (%)"
|
||||
required_metrics:
|
||||
- aws_elb_request_count_sum
|
||||
- aws_elb_httpcode_backend_5_xx_sum
|
||||
weight: 1
|
||||
queries:
|
||||
- query_range: 'sum(aws_elb_httpcode_backend_5_xx_sum{%{environment_filter}}) / sum(aws_elb_request_count_sum{%{environment_filter}})'
|
||||
label: HTTP Errors
|
||||
unit: "%"
|
||||
- group: NGINX
|
||||
priority: 10
|
||||
metrics:
|
||||
- title: "Throughput"
|
||||
y_label: "Requests / Sec"
|
||||
required_metrics:
|
||||
- nginx_requests_total
|
||||
weight: 1
|
||||
queries:
|
||||
- query_range: 'sum(rate(nginx_requests_total{server_zone!="*", server_zone!="_", %{environment_filter}}[2m]))'
|
||||
label: Total
|
||||
unit: req / sec
|
||||
- title: "Latency"
|
||||
y_label: "Latency (ms)"
|
||||
required_metrics:
|
||||
- nginx_upstream_response_msecs_avg
|
||||
weight: 1
|
||||
queries:
|
||||
- query_range: 'avg(nginx_upstream_response_msecs_avg{%{environment_filter}}) * 1000'
|
||||
label: Upstream
|
||||
unit: ms
|
||||
- title: "HTTP Error Rate"
|
||||
y_label: "Error Rate (%)"
|
||||
required_metrics:
|
||||
- nginx_responses_total
|
||||
weight: 1
|
||||
queries:
|
||||
- query_range: 'sum(nginx_responses_total{status_code="5xx", %{environment_filter}}) / sum(nginx_responses_total{server_zone!="*", server_zone!="_", %{environment_filter}})'
|
||||
label: HTTP Errors
|
||||
unit: "%"
|
||||
- group: Kubernetes
|
||||
priority: 5
|
||||
metrics:
|
||||
- title: "Memory Usage"
|
||||
y_label: "Memory Usage (MB)"
|
||||
required_metrics:
|
||||
- container_memory_usage_bytes
|
||||
weight: 1
|
||||
queries:
|
||||
- query_range: 'avg(container_memory_usage_bytes{%{environment_filter}}) / 2^20'
|
||||
label: Container memory
|
||||
unit: MiB
|
||||
- title: "Current memory usage"
|
||||
required_metrics:
|
||||
- container_memory_usage_bytes
|
||||
weight: 1
|
||||
queries:
|
||||
- query: 'avg(container_memory_usage_bytes{%{environment_filter}}) / 2^20'
|
||||
display_empty: false
|
||||
unit: MiB
|
||||
- title: "CPU usage"
|
||||
- query_range: '(sum(container_memory_usage_bytes{container_name!="POD",%{environment_filter}}) / count(container_memory_usage_bytes{container_name!="POD",%{environment_filter}})) /1024/1024'
|
||||
label: Average
|
||||
unit: MB
|
||||
- title: "CPU Utilization"
|
||||
y_label: "CPU Utilization (%)"
|
||||
required_metrics:
|
||||
- container_cpu_usage_seconds_total
|
||||
weight: 1
|
||||
queries:
|
||||
- query_range: 'avg(rate(container_cpu_usage_seconds_total{%{environment_filter}}[2m])) * 100'
|
||||
- title: "Current CPU usage"
|
||||
required_metrics:
|
||||
- container_cpu_usage_seconds_total
|
||||
weight: 1
|
||||
queries:
|
||||
- query: 'avg(rate(container_cpu_usage_seconds_total{%{environment_filter}}[2m])) * 100'
|
||||
- query_range: 'sum(rate(container_cpu_usage_seconds_total{container_name!="POD",%{environment_filter}}[2m])) / count(container_cpu_usage_seconds_total{container_name!="POD",%{environment_filter}}) * 100'
|
||||
label: Average
|
||||
unit: "%"
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue