Add latest changes from gitlab-org/gitlab@master
|
@ -51,7 +51,6 @@ rules:
|
||||||
no-jquery/no-animate-toggle: off
|
no-jquery/no-animate-toggle: off
|
||||||
no-jquery/no-event-shorthand: off
|
no-jquery/no-event-shorthand: off
|
||||||
no-jquery/no-serialize: error
|
no-jquery/no-serialize: error
|
||||||
no-jquery/no-sizzle: off
|
|
||||||
promise/always-return: off
|
promise/always-return: off
|
||||||
promise/no-callback-in-promise: off
|
promise/no-callback-in-promise: off
|
||||||
overrides:
|
overrides:
|
||||||
|
|
|
@ -1359,7 +1359,8 @@ export default class Notes {
|
||||||
const $systemNote = $(systemNote);
|
const $systemNote = $(systemNote);
|
||||||
const headerMessage = $systemNote
|
const headerMessage = $systemNote
|
||||||
.find('.note-text')
|
.find('.note-text')
|
||||||
.find('p:first')
|
.find('p')
|
||||||
|
.first()
|
||||||
.text()
|
.text()
|
||||||
.replace(':', '');
|
.replace(':', '');
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,9 @@ export default function notificationsDropdown() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const notificationLevel = $(this).data('notificationLevel');
|
const notificationLevel = $(this).data('notificationLevel');
|
||||||
const form = $(this).parents('.notification-form:first');
|
const form = $(this)
|
||||||
|
.parents('.notification-form')
|
||||||
|
.first();
|
||||||
|
|
||||||
form.find('.js-notification-loading').toggleClass('fa-bell fa-spin fa-spinner');
|
form.find('.js-notification-loading').toggleClass('fa-bell fa-spin fa-spinner');
|
||||||
if (form.hasClass('no-label')) {
|
if (form.hasClass('no-label')) {
|
||||||
|
|
|
@ -31,7 +31,7 @@ export default class NotificationsForm {
|
||||||
}
|
}
|
||||||
|
|
||||||
saveEvent($checkbox, $parent) {
|
saveEvent($checkbox, $parent) {
|
||||||
const form = $parent.parents('form:first');
|
const form = $parent.parents('form').first();
|
||||||
|
|
||||||
this.showCheckboxLoadingSpinner($parent);
|
this.showCheckboxLoadingSpinner($parent);
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
<script>
|
<script>
|
||||||
import GetSnippetQuery from '../queries/snippet.query.graphql';
|
import GetSnippetQuery from '../queries/snippet.query.graphql';
|
||||||
import SnippetHeader from './snippet_header.vue';
|
import SnippetHeader from './snippet_header.vue';
|
||||||
|
import SnippetTitle from './snippet_title.vue';
|
||||||
import { GlLoadingIcon } from '@gitlab/ui';
|
import { GlLoadingIcon } from '@gitlab/ui';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
SnippetHeader,
|
SnippetHeader,
|
||||||
|
SnippetTitle,
|
||||||
GlLoadingIcon,
|
GlLoadingIcon,
|
||||||
},
|
},
|
||||||
apollo: {
|
apollo: {
|
||||||
|
@ -45,6 +47,9 @@ export default {
|
||||||
:size="2"
|
:size="2"
|
||||||
class="loading-animation prepend-top-20 append-bottom-20"
|
class="loading-animation prepend-top-20 append-bottom-20"
|
||||||
/>
|
/>
|
||||||
<snippet-header v-else :snippet="snippet" />
|
<template v-else>
|
||||||
|
<snippet-header :snippet="snippet" />
|
||||||
|
<snippet-title :snippet="snippet" />
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
<script>
|
||||||
|
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||||
|
import { GlSprintf } from '@gitlab/ui';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
TimeAgoTooltip,
|
||||||
|
GlSprintf,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
snippet: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div class="snippet-header limited-header-width">
|
||||||
|
<h2 class="snippet-title prepend-top-0 mb-3" data-qa-selector="snippet_title">
|
||||||
|
{{ snippet.title }}
|
||||||
|
</h2>
|
||||||
|
<div v-if="snippet.description" class="description" data-qa-selector="snippet_description">
|
||||||
|
<div class="md">{{ snippet.description }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<small v-if="snippet.updatedAt !== snippet.createdAt" class="edited-text">
|
||||||
|
<gl-sprintf message="Edited %{timeago}">
|
||||||
|
<template #timeago>
|
||||||
|
<time-ago-tooltip :time="snippet.updatedAt" tooltip-placement="bottom" />
|
||||||
|
</template>
|
||||||
|
</gl-sprintf>
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -21,7 +21,9 @@ export default class TreeView {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Show the "Loading commit data" for only the first element
|
// Show the "Loading commit data" for only the first element
|
||||||
$('span.log_loading:first').removeClass('hide');
|
$('span.log_loading')
|
||||||
|
.first()
|
||||||
|
.removeClass('hide');
|
||||||
}
|
}
|
||||||
|
|
||||||
initKeyNav() {
|
initKeyNav() {
|
||||||
|
|
|
@ -625,7 +625,7 @@ Note: It is recommended to log into the `git` user using `sudo -i -u git` or `su
|
||||||
|
|
||||||
## GitLab.com
|
## GitLab.com
|
||||||
|
|
||||||
We've also detailed [our architecture of GitLab.com](https://about.gitlab.com/handbook/engineering/infrastructure/production-architecture/) but this is probably over the top unless you have millions of users.
|
We've also detailed [our architecture of GitLab.com](https://about.gitlab.com/handbook/engineering/infrastructure/production/architecture/) but this is probably over the top unless you have millions of users.
|
||||||
|
|
||||||
[alertmanager-omnibus]: https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/files/gitlab-config-template/gitlab.rb.template
|
[alertmanager-omnibus]: https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/files/gitlab-config-template/gitlab.rb.template
|
||||||
[alertmanager-charts]: https://github.com/helm/charts/tree/master/stable/prometheus
|
[alertmanager-charts]: https://github.com/helm/charts/tree/master/stable/prometheus
|
||||||
|
|
|
@ -58,6 +58,7 @@ are very appreciative of the work done by translators and proofreaders!
|
||||||
- Japanese
|
- Japanese
|
||||||
- Hiroyuki Sato - [GitLab](https://gitlab.com/hiroponz), [Crowdin](https://crowdin.com/profile/hiroponz)
|
- Hiroyuki Sato - [GitLab](https://gitlab.com/hiroponz), [Crowdin](https://crowdin.com/profile/hiroponz)
|
||||||
- Tomo Dote - [GitLab](https://gitlab.com/fu7mu4), [Crowdin](https://crowdin.com/profile/fu7mu4)
|
- Tomo Dote - [GitLab](https://gitlab.com/fu7mu4), [Crowdin](https://crowdin.com/profile/fu7mu4)
|
||||||
|
- Hiromi Nozawa - [GitLab](https://gitlab.com/hir0mi), [Crowdin](https://crowdin.com/profile/hir0mi)
|
||||||
- Korean
|
- Korean
|
||||||
- Chang-Ho Cha - [GitLab](https://gitlab.com/changho-cha), [Crowdin](https://crowdin.com/profile/zzazang)
|
- Chang-Ho Cha - [GitLab](https://gitlab.com/changho-cha), [Crowdin](https://crowdin.com/profile/zzazang)
|
||||||
- Ji Hun Oh - [GitLab](https://gitlab.com/Baw-Appie), [Crowdin](https://crowdin.com/profile/BawAppie)
|
- Ji Hun Oh - [GitLab](https://gitlab.com/Baw-Appie), [Crowdin](https://crowdin.com/profile/BawAppie)
|
||||||
|
|
After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 64 KiB |
After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 31 KiB |
|
@ -6,7 +6,7 @@ type: reference, howto
|
||||||
|
|
||||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/41766) in GitLab 11.7.
|
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/41766) in GitLab 11.7.
|
||||||
|
|
||||||
It's typical to create a [Git tag](../../../university/training/topics/tags.md) at
|
It is typical to create a [Git tag](../../../university/training/topics/tags.md) at
|
||||||
the moment of release to introduce a checkpoint in your source code
|
the moment of release to introduce a checkpoint in your source code
|
||||||
history, but in most cases your users will need compiled objects or other
|
history, but in most cases your users will need compiled objects or other
|
||||||
assets output by your CI system to use them, not just the raw source
|
assets output by your CI system to use them, not just the raw source
|
||||||
|
@ -38,7 +38,7 @@ Release descriptions are unrelated. Description supports [Markdown](../../markdo
|
||||||
|
|
||||||
You can currently add the following types of assets to each Release:
|
You can currently add the following types of assets to each Release:
|
||||||
|
|
||||||
- [Source code](#source-code): state of the repo at the time of the Release
|
- [Source code](#source-code): state of the repository at the time of the Release
|
||||||
- [Links](#links): to content such as built binaries or documentation
|
- [Links](#links): to content such as built binaries or documentation
|
||||||
|
|
||||||
GitLab will support more asset types in the future, including objects such
|
GitLab will support more asset types in the future, including objects such
|
||||||
|
@ -117,11 +117,14 @@ of GitLab.
|
||||||
|
|
||||||
You can be notified by email when a new Release is created for your project.
|
You can be notified by email when a new Release is created for your project.
|
||||||
|
|
||||||
To subscribe to these notifications, navigate to your **Project**'s landing page, then click on the
|
To subscribe to Release notifications:
|
||||||
bell icon. Choose **Custom** from the dropdown menu. The
|
|
||||||
following modal window will be then displayed, from which you can select **New release** to complete your subscription to new Releases notifications.
|
|
||||||
|
|
||||||
![Custom notification - New release](img/custom_notifications_new_release_v12_4.png)
|
1. Navigate to your **Project**'s landing page.
|
||||||
|
1. Click the bell icon (**Notification setting**).
|
||||||
|
1. Select **Custom** from the dropdown menu.
|
||||||
|
![Custom notification - Dropdown menu](img/custom_notifications_dropdown_v12_5.png)
|
||||||
|
1. Select **New release**.
|
||||||
|
![Custom notification - New release](img/custom_notifications_new_release_v12_5.png)
|
||||||
|
|
||||||
## Add release notes to Git tags
|
## Add release notes to Git tags
|
||||||
|
|
||||||
|
@ -145,7 +148,7 @@ You can also edit an existing tag to add release notes:
|
||||||
|
|
||||||
![tags](img/tags_12_5.png "Addition of note to an existing tag")
|
![tags](img/tags_12_5.png "Addition of note to an existing tag")
|
||||||
|
|
||||||
## Release Evidence
|
## Release evidence
|
||||||
|
|
||||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/26019) in GitLab 12.6.
|
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/26019) in GitLab 12.6.
|
||||||
|
|
||||||
|
@ -154,11 +157,11 @@ parallel. This dataset will be a snapshot this new release (including linked
|
||||||
milestones and issues) at moment of creation. Such collection of data will
|
milestones and issues) at moment of creation. Such collection of data will
|
||||||
provide a chain of custody and facilitate processes like external audits, for example.
|
provide a chain of custody and facilitate processes like external audits, for example.
|
||||||
|
|
||||||
The gathered Evidence data is stored in the database upon creation of a new
|
The gathered evidence data is stored in the database upon creation of a new
|
||||||
release as a JSON object. In GitLab 12.6, a link to
|
release as a JSON object. In GitLab 12.6, a link to
|
||||||
the Evidence data is provided for [each Release](#releases-list).
|
the evidence data is provided for [each Release](#releases-list).
|
||||||
|
|
||||||
Here's what this object can look like:
|
Here is what this object can look like:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
|
|
@ -88,6 +88,7 @@ module Gitlab
|
||||||
end
|
end
|
||||||
|
|
||||||
def shas_eql?(sha1, sha2)
|
def shas_eql?(sha1, sha2)
|
||||||
|
return true if sha1.nil? && sha2.nil?
|
||||||
return false if sha1.nil? || sha2.nil?
|
return false if sha1.nil? || sha2.nil?
|
||||||
return false unless sha1.class == sha2.class
|
return false unless sha1.class == sha2.class
|
||||||
|
|
||||||
|
|
|
@ -117,7 +117,7 @@ module Gitlab
|
||||||
def format_time(timestamp)
|
def format_time(timestamp)
|
||||||
return timestamp if timestamp.is_a?(String)
|
return timestamp if timestamp.is_a?(String)
|
||||||
|
|
||||||
Time.at(timestamp).utc.iso8601(6)
|
Time.at(timestamp).utc.iso8601(3)
|
||||||
end
|
end
|
||||||
|
|
||||||
def limited_job_args(args)
|
def limited_job_args(args)
|
||||||
|
|
|
@ -50,7 +50,8 @@ module QA
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'Auto DevOps support', :orchestrated, :kubernetes do
|
# Failure issue: https://gitlab.com/gitlab-org/gitlab/issues/118481
|
||||||
|
describe 'Auto DevOps support', :orchestrated, :kubernetes, :quarantine do
|
||||||
context 'when rbac is enabled' do
|
context 'when rbac is enabled' do
|
||||||
before(:all) do
|
before(:all) do
|
||||||
@cluster = Service::KubernetesCluster.new.create!
|
@cluster = Service::KubernetesCluster.new.create!
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
import SnippetTitle from '~/snippets/components/snippet_title.vue';
|
||||||
|
import { GlSprintf } from '@gitlab/ui';
|
||||||
|
import { shallowMount } from '@vue/test-utils';
|
||||||
|
|
||||||
|
describe('Snippet header component', () => {
|
||||||
|
let wrapper;
|
||||||
|
const title = 'The property of Thor';
|
||||||
|
const description = 'Do not touch this hammer';
|
||||||
|
const snippet = {
|
||||||
|
snippet: {
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function createComponent({ props = snippet } = {}) {
|
||||||
|
const defaultProps = Object.assign({}, props);
|
||||||
|
|
||||||
|
wrapper = shallowMount(SnippetTitle, {
|
||||||
|
sync: false,
|
||||||
|
propsData: {
|
||||||
|
...defaultProps,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
wrapper.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders itself', () => {
|
||||||
|
createComponent();
|
||||||
|
expect(wrapper.find('.snippet-header').exists()).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders snippets title and description', () => {
|
||||||
|
createComponent();
|
||||||
|
expect(wrapper.text().trim()).toContain(title);
|
||||||
|
expect(wrapper.text().trim()).toContain(description);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not render recent changes time stamp if there were no updates', () => {
|
||||||
|
createComponent();
|
||||||
|
expect(wrapper.find(GlSprintf).exists()).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not render recent changes time stamp if the time for creation and updates match', () => {
|
||||||
|
const props = Object.assign(snippet, {
|
||||||
|
snippet: {
|
||||||
|
...snippet.snippet,
|
||||||
|
createdAt: '2019-12-16T21:45:36Z',
|
||||||
|
updatedAt: '2019-12-16T21:45:36Z',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
createComponent({ props });
|
||||||
|
|
||||||
|
expect(wrapper.find(GlSprintf).exists()).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders translated string with most recent changes timestamp if changes were made', () => {
|
||||||
|
const props = Object.assign(snippet, {
|
||||||
|
snippet: {
|
||||||
|
...snippet.snippet,
|
||||||
|
createdAt: '2019-12-16T21:45:36Z',
|
||||||
|
updatedAt: '2019-15-16T21:45:36Z',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
createComponent({ props });
|
||||||
|
|
||||||
|
expect(wrapper.find(GlSprintf).exists()).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
|
@ -73,7 +73,8 @@ describe Gitlab::Git do
|
||||||
[sha, short_sha, true],
|
[sha, short_sha, true],
|
||||||
[sha, sha.reverse, false],
|
[sha, sha.reverse, false],
|
||||||
[sha, too_short_sha, false],
|
[sha, too_short_sha, false],
|
||||||
[sha, nil, false]
|
[sha, nil, false],
|
||||||
|
[nil, nil, true]
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ require 'fast_spec_helper'
|
||||||
|
|
||||||
describe Gitlab::SidekiqLogging::StructuredLogger do
|
describe Gitlab::SidekiqLogging::StructuredLogger do
|
||||||
describe '#call' do
|
describe '#call' do
|
||||||
let(:timestamp) { Time.iso8601('2018-01-01T12:00:00Z') }
|
let(:timestamp) { Time.iso8601('2018-01-01T12:00:00.000Z') }
|
||||||
let(:created_at) { timestamp - 1.second }
|
let(:created_at) { timestamp - 1.second }
|
||||||
let(:scheduling_latency_s) { 1.0 }
|
let(:scheduling_latency_s) { 1.0 }
|
||||||
|
|
||||||
|
@ -30,8 +30,8 @@ describe Gitlab::SidekiqLogging::StructuredLogger do
|
||||||
'message' => 'TestWorker JID-da883554ee4fe414012f5f42: start',
|
'message' => 'TestWorker JID-da883554ee4fe414012f5f42: start',
|
||||||
'job_status' => 'start',
|
'job_status' => 'start',
|
||||||
'pid' => Process.pid,
|
'pid' => Process.pid,
|
||||||
'created_at' => created_at.iso8601(6),
|
'created_at' => created_at.iso8601(3),
|
||||||
'enqueued_at' => created_at.iso8601(6),
|
'enqueued_at' => created_at.iso8601(3),
|
||||||
'scheduling_latency_s' => scheduling_latency_s
|
'scheduling_latency_s' => scheduling_latency_s
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -40,7 +40,7 @@ describe Gitlab::SidekiqLogging::StructuredLogger do
|
||||||
'message' => 'TestWorker JID-da883554ee4fe414012f5f42: done: 0.0 sec',
|
'message' => 'TestWorker JID-da883554ee4fe414012f5f42: done: 0.0 sec',
|
||||||
'job_status' => 'done',
|
'job_status' => 'done',
|
||||||
'duration' => 0.0,
|
'duration' => 0.0,
|
||||||
"completed_at" => timestamp.iso8601(6),
|
"completed_at" => timestamp.iso8601(3),
|
||||||
"cpu_s" => 1.111112
|
"cpu_s" => 1.111112
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -145,7 +145,7 @@ describe Gitlab::SidekiqLogging::StructuredLogger do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with latency' do
|
context 'with latency' do
|
||||||
let(:created_at) { Time.iso8601('2018-01-01T10:00:00Z') }
|
let(:created_at) { Time.iso8601('2018-01-01T10:00:00.000Z') }
|
||||||
let(:scheduling_latency_s) { 7200.0 }
|
let(:scheduling_latency_s) { 7200.0 }
|
||||||
|
|
||||||
it 'logs with scheduling latency' do
|
it 'logs with scheduling latency' do
|
||||||
|
|
|
@ -63,6 +63,20 @@ describe Commit do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#diff_refs' do
|
||||||
|
it 'is equal to itself' do
|
||||||
|
expect(commit.diff_refs).to eq(commit.diff_refs)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'from a factory' do
|
||||||
|
let(:commit) { create(:commit) }
|
||||||
|
|
||||||
|
it 'is equal to itself' do
|
||||||
|
expect(commit.diff_refs).to eq(commit.diff_refs)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#author', :request_store do
|
describe '#author', :request_store do
|
||||||
it 'looks up the author in a case-insensitive way' do
|
it 'looks up the author in a case-insensitive way' do
|
||||||
user = create(:user, email: commit.author_email.upcase)
|
user = create(:user, email: commit.author_email.upcase)
|
||||||
|
|