Commit 4d7f3df2 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab-ce master

parents a96bce2b 1f36297f
$item-path-max-width: 160px;
$item-milestone-max-width: 120px;
$item-weight-max-width: 48px;
.related-items-list {
padding: $gl-padding-4;
&,
.list-item:last-child {
margin-bottom: 0;
}
}
.item-body {
display: flex;
position: relative;
align-items: center;
padding: $gl-padding-8;
line-height: $gl-line-height;
.item-contents {
display: flex;
align-items: center;
flex-wrap: wrap;
flex-grow: 1;
}
.issue-token-state-icon-open,
.issue-token-state-icon-closed,
.confidential-icon,
.item-milestone .icon,
.item-weight .board-card-info-icon {
min-width: $gl-padding;
cursor: help;
}
.issue-token-state-icon-open,
.issue-token-state-icon-closed {
margin-right: $gl-padding-4;
}
.confidential-icon {
align-self: baseline;
color: $orange-600;
margin-right: $gl-padding-4;
}
.item-title {
flex-basis: 100%;
margin-bottom: $gl-padding-8;
font-size: $gl-font-size-small;
&.mr-title {
font-weight: $gl-font-weight-bold;
}
.sortable-link {
max-width: 85%;
}
.issue-token-state-icon-open,
.issue-token-state-icon-closed {
display: none;
}
}
.item-meta {
display: flex;
flex-wrap: wrap;
flex-basis: 100%;
font-size: $gl-font-size-small;
color: $gl-text-color-secondary;
.item-meta-child {
order: 0;
display: flex;
flex-wrap: wrap;
flex-basis: 100%;
.item-due-date,
.item-weight {
margin-left: $gl-padding-8;
}
.item-milestone,
.item-weight {
cursor: help;
}
.item-milestone {
text-decoration: none;
max-width: $item-milestone-max-width;
}
.item-due-date {
margin-right: 0;
}
.item-weight {
margin-right: 0;
max-width: $item-weight-max-width;
}
}
.item-path-id .path-id-text,
.item-milestone .milestone-title,
.item-due-date,
.item-weight .board-card-info-text {
color: $gl-text-color-secondary;
display: inline-block;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.item-path-id {
margin-top: $gl-padding-4;
font-size: $gl-font-size-xs;
white-space: nowrap;
.path-id-text {
font-weight: $gl-font-weight-bold;
max-width: $item-path-max-width;
}
.issue-token-state-icon-open,
.issue-token-state-icon-closed {
display: block;
}
&:not(.mr-item-path) {
order: 1;
}
}
.item-milestone .ic-clock {
color: $gl-text-color-tertiary;
margin-right: $gl-padding-4;
}
.item-assignees {
order: 2;
align-self: flex-end;
align-items: center;
margin-left: auto;
.user-avatar-link {
margin-right: -$gl-padding-4;
&:nth-of-type(1) {
z-index: 2;
}
&:nth-of-type(2) {
z-index: 1;
}
&:last-child {
margin-right: 0;
}
}
.avatar {
height: $gl-padding;
width: $gl-padding;
margin-right: 0;
vertical-align: bottom;
}
.avatar-counter {
height: $gl-padding;
border: 1px solid transparent;
background-color: $gl-text-color-tertiary;
font-weight: $gl-font-weight-bold;
padding: 0 $gl-padding-4;
line-height: $gl-padding;
}
}
}
.btn-item-remove {
position: absolute;
right: 0;
top: $gl-padding-4 / 2;
padding: $gl-padding-4;
margin-right: $gl-padding-4 / 2;
line-height: 0;
border-color: transparent;
color: $gl-text-color-secondary;
&:hover {
color: $gl-text-color;
}
}
}
.mr-status-wrapper,
.mr-ci-status
{
line-height: 0;
}
@include media-breakpoint-up(sm) {
.item-body {
.item-contents .item-title {
.mr-title-link,
.sortable-link {
max-width: 90%;
}
}
}
}
/* Small devices (landscape phones, 768px and up) */
@include media-breakpoint-up(md) {
.item-body {
.item-contents {
min-width: 0;
.item-title {
flex-basis: unset;
// 95% because we compensate
// for remove button which is
// positioned absolutely
width: 95%;
margin-bottom: $gl-padding-4;
.mr-title-link,
.sortable-link {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
max-width: 100%;
}
}
.item-meta {
.item-path-id {
order: 0;
margin-top: 0;
}
.item-meta-child {
flex-basis: unset;
margin-left: auto;
margin-right: $gl-padding-4;
~ .item-assignees {
margin-left: $gl-padding-4;
}
}
.item-assignees {
margin-bottom: 0;
margin-left: 0;
order: 2;
}
}
}
.btn-item-remove {
order: 1;
}
}
}
/* Medium devices (desktops, 992px and up) */
@include media-breakpoint-up(lg) {
.item-body {
padding: $gl-padding;
.item-title {
font-size: $gl-font-size;
}
.item-meta .item-path-id {
font-size: inherit; // Base size given to `item-meta` is `$gl-font-size-small`
}
.issue-token-state-icon-open,
.issue-token-state-icon-closed {
margin-right: $gl-padding-4;
}
}
}
/* Large devices (large desktops, 1200px and up) */
@include media-breakpoint-up(xl) {
.item-body {
padding: $gl-padding-8;
padding-left: $gl-padding;
.item-contents {
flex-wrap: nowrap;
overflow: hidden;
.item-title {
display: flex;
margin-bottom: 0;
min-width: 0;
width: auto;
flex-basis: unset;
font-weight: $gl-font-weight-normal;
.mr-title-link,
.sortable-link {
display: block;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.issue-token-state-icon-open,
.issue-token-state-icon-closed {
display: block;
margin-right: $gl-padding-8;
}
.confidential-icon {
align-self: auto;
margin-top: 0;
}
}
.item-meta {
margin-top: 0;
justify-content: flex-end;
flex: 1;
flex-wrap: nowrap;
.item-path-id {
order: 0;
margin-top: 0;
margin-left: $gl-padding-8;
margin-right: auto;
.issue-token-state-icon-open,
.issue-token-state-icon-closed {
display: none;
}
}
.item-meta-child {
margin-left: $gl-padding-8;
flex-wrap: nowrap;
}
.item-assignees {
flex-grow: 0;
margin-top: 0;
margin-right: $gl-padding-4;
.avatar {
height: $gl-padding-24;
width: $gl-padding-24;
}
.avatar-counter {
height: $gl-padding-24;
min-width: $gl-padding-24;
line-height: $gl-padding-24;
border-radius: $gl-padding-24;
}
}
}
}
.btn-item-remove {
position: relative;
align-self: center;
top: initial;
right: 0;
margin-right: 0;
padding: $btn-sm-side-margin;
&:hover {
border-color: $border-color;
}
}
}
}
...@@ -80,7 +80,6 @@ ul.related-merge-requests > li { ...@@ -80,7 +80,6 @@ ul.related-merge-requests > li {
} }
} }
.merge-requests-title,
.related-branches-title { .related-branches-title {
font-size: 16px; font-size: 16px;
font-weight: $gl-font-weight-bold; font-weight: $gl-font-weight-bold;
...@@ -91,23 +90,16 @@ ul.related-merge-requests > li { ...@@ -91,23 +90,16 @@ ul.related-merge-requests > li {
} }
.merge-request-status { .merge-request-status {
font-size: 13px;
padding: 0 5px;
color: $white-light;
height: 20px;
border-radius: 3px;
line-height: 18px;
&.merged { &.merged {
background: $blue-500; color: $blue-500;
} }
&.closed { &.closed {
background: $red-500; color: $red-500;
} }
&.open { &.open {
background: $green-500; color: $green-500;
} }
} }
......
.issue-count-badge { .issue-count-badge,
.mr-count-badge {
display: inline-flex; display: inline-flex;
border-radius: $border-radius-base; border-radius: $border-radius-base;
border: 1px solid $border-color; border: 1px solid $border-color;
padding: 5px $gl-padding-8; padding: 5px $gl-padding-8;
} }
.issue-count-badge-count { .issue-count-badge-count,
.mr-count-badge-count {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
} }
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
module Clusters module Clusters
module Applications module Applications
class Runner < ActiveRecord::Base class Runner < ActiveRecord::Base
VERSION = '0.1.43'.freeze VERSION = '0.1.45'.freeze
self.table_name = 'clusters_applications_runners' self.table_name = 'clusters_applications_runners'
......
- if @merge_requests.any? - if @merge_requests.any?
%h2.merge-requests-title .card-slim.mt-3
= pluralize(@merge_requests.count, 'Related Merge Request') .card-header
%ul.unstyled-list.related-merge-requests %h2.card-title.mt-0.mb-0.h5.merge-requests-title
- has_any_head_pipeline = @merge_requests.any?(&:head_pipeline_id) %span.mr-1.bold
- @merge_requests.each do |merge_request| = _('Related merge requests')
%li .d-inline-flex.lh-100.align-middle
%span.merge-request-ci-status .mr-count-badge
- if merge_request.head_pipeline .mr-count-badge-count
= render_pipeline_status(merge_request.head_pipeline) = sprite_icon('merge-request', size: 16, css_class: 'mr-1 text-secondary')
- elsif has_any_head_pipeline = @merge_requests.count
= icon('blank fw') %ul.content-list.related-items-list
%span.merge-request-id - has_any_head_pipeline = @merge_requests.any?(&:head_pipeline_id)
= merge_request.to_reference - @merge_requests.each do |merge_request|
%span.merge-request-info %li.list-item.py-0.px-0
%strong .item-body.issuable-info-container.py-lg-3.px-lg-3.pl-md-3
= link_to merge_request.title, merge_request_path(merge_request), class: "row_title" .item-contents
- unless @issue.project.id == merge_request.target_project.id .item-title.d-flex.align-items-center.mr-title
in = render partial: 'projects/issues/merge_requests_status', locals: { merge_request: merge_request, css_class: 'd-none d-xl-block append-right-8' }
- project = merge_request.target_project = link_to merge_request.title, merge_request_path(merge_request), { class: 'mr-title-link'}
= link_to project.full_name, project_path(project) .item-meta
= render partial: 'projects/issues/merge_requests_status', locals: { merge_request: merge_request, css_class: 'd-xl-none d-lg-block append-right-5' }
%span.d-flex.align-items-center.append-right-8.mr-item-path.item-path-id.mt-0
%span.path-id-text.bold.text-truncate{ data: { toggle: 'tooltip'}, title: merge_request.target_project.full_path }
= merge_request.target_project.full_path
= merge_request.to_reference
%span.mr-ci-status.flex-md-grow-1.justify-content-end.d-flex.ml-md-2
- if merge_request.head_pipeline
= render_pipeline_status(merge_request.head_pipeline, tooltip_placement: 'bottom')
- elsif has_any_head_pipeline
= icon('blank fw')
- if merge_request.merged? - if @closed_by_merge_requests.present?
%span.merge-request-status.prepend-left-10.merged %p
Merged = render partial: 'projects/issues/closed_by_box', locals: {merge_request_count: @merge_requests.count}
- elsif merge_request.closed?
%span.merge-request-status.prepend-left-10.closed
Closed
- else
%span.merge-request-status.prepend-left-10.open
Open
- if @closed_by_merge_requests.present?
%li
= render partial: 'projects/issues/closed_by_box', locals: {merge_request_count: @merge_requests.count}
- time_format = '%b %e, %Y %l:%M%P %Z%z'
- if merge_request.merged?
- mr_status_date = merge_request.merged_at
- mr_status_title = _('Merged')
- mr_status_icon = 'merge'
- mr_status_class = 'merged'
- elsif merge_request.closed?
- mr_status_date = merge_request.closed_event&.created_at
- mr_status_title = _('Closed')
- mr_status_icon = 'issue-close'
- mr_status_class = 'closed'
- else
- mr_status_date = merge_request.created_at
- mr_status_title = _('Opened')
- mr_status_icon = 'issue-open-m'
- mr_status_class = 'open'
- mr_status_tooltip = "<div><span class=\"bold\">#{mr_status_title}</span> #{time_ago_in_words(mr_status_date)} ago</div><span class=\"text-tertiary\">#{l(mr_status_date.to_time, format: time_format)}</span>"
%span.mr-status-wrapper.suggestion-help-hover{ class: css_class, data: { toggle: 'tooltip', placement: 'bottom', html: 'true', title: mr_status_tooltip } }
= sprite_icon(mr_status_icon, size: 16, css_class: "merge-request-status #{mr_status_class}")
---
title: Redesigned related merge requests in issue page.
merge_request: 24270
author:
type: changed
---
title: Prevent Sidekiq arguments over 10 KB in size from being logged to JSON
merge_request: 24493
author:
type: changed
---
title: Update GitLab Runner Helm Chart to 0.1.45
merge_request: 24564
author:
type: other
...@@ -32,7 +32,7 @@ to be reviewed. ...@@ -32,7 +32,7 @@ to be reviewed.
| Tech writer | Stage(s) | | Tech writer | Stage(s) |
| ------------ | ------------------------------------------------------------ | | ------------ | ------------------------------------------------------------ |
| `@marcia` | ~Create ~Release + ~"development guidelines" | | `@marcia` | ~Create ~Release + ~"development guidelines" |
| `@axil` | ~Distribution ~Gitaly ~Gitter ~Monitoring ~Package ~Secure | | `@axil` | ~Distribution ~Gitaly ~Gitter ~Monitor ~Package ~Secure |
| `@eread` | ~Manage ~Configure ~Geo ~Verify | | `@eread` | ~Manage ~Configure ~Geo ~Verify |
| `@mikelewis` | ~Plan | | `@mikelewis` | ~Plan |
......
...@@ -11,6 +11,11 @@ Example: ...@@ -11,6 +11,11 @@ Example:
gitlab_rails['env'] = {"SIDEKIQ_LOG_ARGUMENTS" => "1"} gitlab_rails['env'] = {"SIDEKIQ_LOG_ARGUMENTS" => "1"}
``` ```
Please note: It is not recommend to enable this setting in production because some Please note: It is not recommend to enable this setting in production because some
Sidekiq jobs (such as sending a password reset email) take secret arguments (for Sidekiq jobs (such as sending a password reset email) take secret arguments (for
example the password reset token). example the password reset token).
\ No newline at end of file
When using [Sidekiq JSON logging](../administration/logs.md#sidekiqlog),
arguments logs are limited to a maximum size of 10 kilobytes of text;
any arguments after this limit will be discarded and replaced with a
single argument containing the string `"..."`.
...@@ -5,6 +5,7 @@ module Gitlab ...@@ -5,6 +5,7 @@ module Gitlab
class StructuredLogger class StructuredLogger
START_TIMESTAMP_FIELDS = %w[created_at enqueued_at].freeze START_TIMESTAMP_FIELDS = %w[created_at enqueued_at].freeze
DONE_TIMESTAMP_FIELDS = %w[started_at retried_at failed_at completed_at].freeze DONE_TIMESTAMP_FIELDS = %w[started_at retried_at failed_at completed_at].freeze
MAXIMUM_JOB_ARGUMENTS_LENGTH = 10.kilobytes
def call(job, queue) def call(job, queue)
started_at = current_time started_at = current_time
...@@ -64,6 +65,7 @@ module Gitlab ...@@ -64,6 +65,7 @@ module Gitlab
job['pid'] = ::Process.pid job['pid'] = ::Process.pid
job.delete('args') unless ENV['SIDEKIQ_LOG_ARGUMENTS'] job.delete('args') unless ENV['SIDEKIQ_LOG_ARGUMENTS']
job['args'] = limited_job_args(job['args']) if job['args']
convert_to_iso8601(job, START_TIMESTAMP_FIELDS) convert_to_iso8601(job, START_TIMESTAMP_FIELDS)
...@@ -93,6 +95,21 @@ module Gitlab ...@@ -93,6 +95,21 @@ module Gitlab
Time.at(timestamp).utc.iso8601(3) Time.at(timestamp).utc.iso8601(3)
end end
def limited_job_args(args)
return unless args.is_a?(Array)
total_length = 0
limited_args = args.take_while do |arg|
total_length += arg.to_json.length
total_length <= MAXIMUM_JOB_ARGUMENTS_LENGTH
end
limited_args.push('...') if total_length > MAXIMUM_JOB_ARGUMENTS_LENGTH
limited_args
end
end end
end end
end end
...@@ -64,11 +64,13 @@ describe "Internal references", :js do ...@@ -64,11 +64,13 @@ describe "Internal references", :js do
it "shows references" do it "shows references" do
page.within("#merge-requests .merge-requests-title") do page.within("#merge-requests .merge-requests-title") do
expect(page).to have_content("1 Related Merge Request") expect(page).to have_content("Related merge requests")
expect(page).to have_css(".mr-count-badge")
end end
page.within("#merge-requests ul") do page.within("#merge-requests ul") do
expect(page).to have_content(private_project_merge_request.title) expect(page).to have_content(private_project_merge_request.title)
expect(page).to have_css(".merge-request-status")
end end
expect(page).to have_content("mentioned in merge request #{private_project_merge_request.to_reference(public_project)}") expect(page).to have_content("mentioned in merge request #{private_project_merge_request.to_reference(public_project)}")
......
...@@ -141,7 +141,7 @@ describe 'User creates branch and merge request on issue page', :js do ...@@ -141,7 +141,7 @@ describe 'User creates branch and merge request on issue page', :js do
it 'disables the create branch button' do it 'disables the create branch button' do
expect(page).to have_css('.create-mr-dropdown-wrap .unavailable:not(.hidden)') expect(page).to have_css('.create-mr-dropdown-wrap .unavailable:not(.hidden)')
expect(page).to have_css('.create-mr-dropdown-wrap .available.hidden', visible: false) expect(page).to have_css('.create-mr-dropdown-wrap .available.hidden', visible: false)
expect(page).to have_content /1 Related Merge Request/ expect(page).to have_content /Related merge requests/
end end
end end
......
...@@ -82,15 +82,36 @@ describe Gitlab::SidekiqLogging::StructuredLogger do ...@@ -82,15 +82,36 @@ describe Gitlab::SidekiqLogging::StructuredLogger do
end.to raise_error(ArgumentError) end.to raise_error(ArgumentError)
end end
end end
context 'when the job args are bigger than the maximum allowed' do
it 'keeps args from the front until they exceed the limit' do
Timecop.freeze(timestamp) do
job['args'] = [
1,
2,
'a' * (described_class::MAXIMUM_JOB_ARGUMENTS_LENGTH / 2),
'b' * (described_class::MAXIMUM_JOB_ARGUMENTS_LENGTH / 2),
3
]
expected_args = job['args'].take(3) + ['...']
expect(logger).to receive(:info).with(start_payload.merge('args' => expected_args)).ordered
expect(logger).to receive(:info).with(end_payload.merge('args' => expected_args)).ordered
expect(subject).to receive(:log_job_start).and_call_original
expect(subject).to receive(:log_job_done).and_call_original
subject.call(job, 'test_queue') { }
end
end
end
end end
context 'with SIDEKIQ_LOG_ARGUMENTS disabled' do context 'with SIDEKIQ_LOG_ARGUMENTS disabled' do
it 'logs start and end of job' do it 'logs start and end of job without args' do
Timecop.freeze(timestamp) do Timecop.freeze(timestamp) do
start_payload.delete('args') expect(logger).to receive(:info).with(start_payload.except('args')).ordered
expect(logger).to receive(:info).with(end_payload.except('args')).ordered
expect(logger).to receive(:info).with(start_payload).ordered
expect(logger).to receive(:info).with(end_payload).ordered
expect(subject).to receive(:log_job_start).and_call_original expect(subject).to receive(:log_job_start).and_call_original
expect(subject).to receive(:log_job_done).and_call_original expect(subject).to receive(:log_job_done).and_call_original
......
...@@ -18,7 +18,7 @@ describe Clusters::Applications::Runner do ...@@ -18,7 +18,7 @@ describe Clusters::Applications::Runner do
let(:application) { create(:clusters_applications_runner, :scheduled, version: '0.1.30') } let(:application) { create(:clusters_applications_runner, :scheduled, version: '0.1.30') }
it 'updates the application version' do it 'updates the application version' do
expect(application.reload.version).to eq('0.1.43') expect(application.reload.version).to eq('0.1.45')
end end
end end
end end
...@@ -46,7 +46,7 @@ describe Clusters::Applications::Runner do ...@@ -46,7 +46,7 @@ describe Clusters::Applications::Runner do
it 'should be initialized with 4 arguments' do it 'should be initialized with 4 arguments' do
expect(subject.name).to eq('runner') expect(subject.name).to eq('runner')
expect(subject.chart).to eq('runner/gitlab-runner') expect(subject.chart).to eq('runner/gitlab-runner')
expect(subject.version).to eq('0.1.43') expect(subject.version).to eq('0.1.45')
expect(subject).to be_rbac expect(subject).to be_rbac
expect(subject.repository).to eq('https://charts.gitlab.io') expect(subject.repository).to eq('https://charts.gitlab.io')
expect(subject.files).to eq(gitlab_runner.files) expect(subject.files).to eq(gitlab_runner.files)
...@@ -64,7 +64,7 @@ describe Clusters::Applications::Runner do ...@@ -64,7 +64,7 @@ describe Clusters::Applications::Runner do
let(:gitlab_runner) { create(:clusters_applications_runner, :errored, runner: ci_runner, version: '0.1.13') } let(:gitlab_runner) { create(:clusters_applications_runner, :errored, runner: ci_runner, version: '0.1.13') }
it 'should be initialized with the locked version' do it 'should be initialized with the locked version' do
expect(subject.version).to eq('0.1.43') expect(subject.version).to eq('0.1.45')
end end
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment