提交 38c79b69 编写于 作者: G GitLab Bot

Add latest changes from gitlab-org/gitlab@master

上级 2b7a5214
......@@ -56,7 +56,7 @@ Style/FrozenStringLiteralComment:
- 'qa/**/*'
- 'rubocop/**/*'
- 'scripts/**/*'
- 'spec/lib/**/*'
- 'spec/lib/gitlab/**/*'
RSpec/FilePath:
Exclude:
......
/* eslint-disable import/prefer-default-export */
import _ from 'underscore';
/**
* @param {Array} queryResults - Array of Result objects
* @param {Object} defaultConfig - Default chart config values (e.g. lineStyle, name)
* @returns {Array} The formatted values
*/
export const makeDataSeries = (queryResults, defaultConfig) =>
queryResults.reduce((acc, result) => {
const data = result.values.filter(([, value]) => !Number.isNaN(value));
if (!data.length) {
return acc;
}
const relevantMetric = defaultConfig.name.toLowerCase().replace(' ', '_');
const name = result.metric[relevantMetric];
const series = { data };
if (name) {
series.name = `${defaultConfig.name}: ${name}`;
}
queryResults
.map(result => {
const data = result.values.filter(([, value]) => !Number.isNaN(value));
if (!data.length) {
return null;
}
const relevantMetric = defaultConfig.name.toLowerCase().replace(' ', '_');
const name = result.metric[relevantMetric];
const series = { data };
if (name) {
series.name = `${defaultConfig.name}: ${name}`;
} else {
const template = _.template(defaultConfig.name, {
interpolate: /\{\{(.+?)\}\}/g,
});
series.name = template(result.metric);
}
return acc.concat({ ...defaultConfig, ...series });
}, []);
return { ...defaultConfig, ...series };
})
.filter(series => series !== null);
......@@ -553,14 +553,10 @@ export const calculateRemainingMilliseconds = endDate => {
*
* @param {Date} date the date that we will substract days from
* @param {number} daysInPast number of days that are subtracted from a given date
* @returns {String} Date string in ISO format
* @returns {Date} Date in past as Date object
*/
export const getDateInPast = (date, daysInPast) => {
const dateClone = newDate(date);
return new Date(
dateClone.setTime(dateClone.getTime() - daysInPast * 24 * 60 * 60 * 1000),
).toISOString();
};
export const getDateInPast = (date, daysInPast) =>
new Date(newDate(date).setDate(date.getDate() - daysInPast));
export const beginOfDayTime = 'T00:00:00Z';
export const endOfDayTime = 'T23:59:59Z';
......
......@@ -7,7 +7,7 @@ import { s__, __ } from '../../locale';
const MAX_REQUESTS = 3;
function backOffRequest(makeRequestCallback) {
export function backOffRequest(makeRequestCallback) {
let requestCounter = 0;
return backOff((next, stop) => {
makeRequestCallback()
......@@ -111,8 +111,7 @@ export const fetchDashboard = ({ state, dispatch }, params) => {
params.dashboard = state.currentDashboard;
}
return axios
.get(state.dashboardEndpoint, { params })
return backOffRequest(() => axios.get(state.dashboardEndpoint, { params }))
.then(resp => resp.data)
.then(response => {
dispatch('receiveMetricsDashboardSuccess', { response, params });
......
......@@ -18,12 +18,6 @@ class ApplicationSetting < ApplicationRecord
# fix a lot of tests using allow_any_instance_of
include ApplicationSettingImplementation
attr_encrypted :asset_proxy_secret_key,
mode: :per_attribute_iv,
insecure_mode: true,
key: Settings.attr_encrypted_db_key_base_truncated,
algorithm: 'aes-256-cbc'
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
......@@ -286,6 +280,12 @@ class ApplicationSetting < ApplicationRecord
pass: :external_auth_client_key_pass,
if: -> (setting) { setting.external_auth_client_cert.present? }
attr_encrypted :asset_proxy_secret_key,
mode: :per_attribute_iv,
key: Settings.attr_encrypted_db_key_base_truncated,
algorithm: 'aes-256-cbc',
insecure_mode: true
attr_encrypted :external_auth_client_key,
mode: :per_attribute_iv,
key: Settings.attr_encrypted_db_key_base_truncated,
......
---
title: Change return type of getDateInPast to Date
merge_request: 19081
author:
type: changed
......@@ -83,7 +83,7 @@ Therefore "create a new user" would translate into "Benutzer(in) anlegen".
### Updating the glossary
To propose additions to the glossary please
[open an issue](https://gitlab.com/gitlab-org/gitlab-foss/issues).
[open an issue](https://gitlab.com/gitlab-org/gitlab/issues?scope=all&utf8=✓&state=all&label_name[]=Category%3AInternationalization).
## French Translation Guidelines
......
......@@ -30,21 +30,68 @@ The following table describes the version types and their release cadence:
## Patch releases
Patch releases usually only include bug fixes and are only done for the current
stable release. That said, in some cases, we may backport it to previous stable
Our current policy is to support **only the current stable release** at any given time.
Patch releases **only include bug fixes** for the current stable released version of
GitLab.
These two policies are in place because:
1. GitLab has Community and Enterprise distributions, doubling the amount of work
necessary to test/release the software.
1. Backporting to more than one release creates a high development, quality assurance,
and support cost.
1. Supporting parallel version discourages incremental upgrades which over time accumulate in
complexity and create upgrade challenges for all users. GitLab has a dedicated team ensuring that
incremental upgrades (and installations) are as simple as possible.
1. The number of changes created in the GitLab application is high, which contributes to backporting complexity to older releases. In number of cases, backporting has to go through the same
review process a new change goes through.
1. Ensuring that tests pass on older release is a considerable challenge in some cases, and as such is very time consuming.
Including new features in patch releases is not possible as that would break [Semantic Versioning].
Breaking [Semantic Versioning] has the following consequences for users that
have to adhere to various internal requirements (e.g. org. compliance, verifying new features and similar):
1. Inability to quickly upgrade to leverage bug fixes included in patch versions.
1. Inability to quickly upgrade to leverage security fixes included in patch versions.
1. Requirements consisting of extensive testing for not only stable GitLab release, but every patch version.
In cases where a strategic user has a requirement to test a feature before it is
officially released, we can offer to create a Release Candidate (RC) version that will
include the specific feature. This should be needed only in extreme cases, and can be requested for consideration by raising an issue in [release/tasks] issue tracker.
It is important to note that the Release Candidate will also contain other
features and changes as it is not possible to easily isolate a specific feature (similar reasons as noted above). The Release Candidate will be no different than any code that is deployed to GitLab.com or is publicly accessible.
### Backporting to older releases
Backporting to more than one stable release is reserved for [security releases](#security-releases).
In some cases however, we may need to backport *a bug fix* to more than one stable
release, depending on the severity of the bug.
For instance, if we release `10.1.1` with a fix for a severe bug introduced in
`10.0.0`, we could backport the fix to a new `10.0.x` patch release.
Decision on whether backporting a change will be performed is done at the discretion of the [current release managers][release-managers], similar to what is described in the [managing bugs] process, based on *all* of the following:
1. Estimated [severity][severity-labels] of the bug: Highest possible impact to users based on the current definition of severity.
1. Estimated [priority][priority-labels] of the bug: Immediate impact on all impacted users based on the above estimated severity.
1. Potentially incurring data loss and/or security breach.
1. Potentially affecting one or more strategic accounts due to a proven inability by the user to upgrade to the current stable version.
If *all* of the above are satisfied, the backport releases can be created for
the current stable stable release, and two previous monthly releases.
For instance, if we release `11.2.1` with a fix for a severe bug introduced in
`11.0.0`, we could backport the fix to a new `11.0.x`, and `11.1.x` patch release.
To request backporting to more than one stable release for consideration, raise an issue in [release/tasks] issue tracker.
### Security releases
Security releases are a special kind of patch release that only include security
fixes and patches (see below).
Our current policy is to support one stable release at any given time, but for
medium-level security issues, we may backport security fixes to the previous two
monthly releases.
Our current policy is to backport security fixes to the previous two
monthly releases in addition to the current stable release.
For very serious security issues, there is
[precedent](https://about.gitlab.com/blog/2016/05/02/cve-2016-4340-patches/)
......@@ -91,3 +138,9 @@ Please see the table below for some examples:
More information about the release procedures can be found in our
[release documentation](https://gitlab.com/gitlab-org/release/docs). You may also want to read our
[Responsible Disclosure Policy](https://about.gitlab.com/security/disclosure/).
[release-managers]: https://about.gitlab.com/community/release-managers/
[priority-definition]: ../development/contributing/issue_workflow.md#priority-labels
[severity-labels]: ../development/contributing/issue_workflow.html#severity-labels
[managing bugs]: https://gitlab.com/gitlab-org/gitlab/blob/master/PROCESS.md#managing-bugs
[release/tasks]: https://gitlab.com/gitlab-org/release/tasks/issues
......@@ -139,7 +139,7 @@ GitLab supports a limited set of [CI variables](../../../ci/variables/README.htm
- CI_ENVIRONMENT_SLUG
- KUBE_NAMESPACE
To specify a variable in a query, enclose it in curly braces with a leading percent. For example: `%{ci_environment_slug}`.
To specify a variable in a query, enclose it in quotation marks with curly braces with a leading percent. For example: `"%{ci_environment_slug}"`.
### Defining custom dashboards per project
......
......@@ -28,6 +28,10 @@ module Gitlab
true
end
def thread_name
self.class.name.demodulize.underscore
end
def start
return unless enabled?
......@@ -35,7 +39,10 @@ module Gitlab
break thread if thread?
if start_working
@thread = Thread.new { run_thread }
@thread = Thread.new do
Thread.current.name = thread_name
run_thread
end
end
end
end
......
......@@ -4,6 +4,7 @@ module Gitlab
module SidekiqDaemon
class Monitor < Daemon
include ::Gitlab::Utils::StrongMemoize
extend ::Gitlab::Utils::Override
NOTIFICATION_CHANNEL = 'sidekiq:cancel:notifications'
CANCEL_DEADLINE = 24.hours.seconds
......@@ -24,6 +25,11 @@ module Gitlab
@jobs_mutex = Mutex.new
end
override :thread_name
def thread_name
"job_monitor"
end
def within_job(worker_class, jid, queue)
jobs_mutex.synchronize do
jobs[jid] = { worker_class: worker_class, thread: Thread.current, started_at: Gitlab::Metrics::System.monotonic_time }
......
......@@ -41,5 +41,76 @@ describe('monitor helper', () => {
),
).toEqual([{ ...expectedDataSeries[0], data: [[1, 1]] }]);
});
it('updates series name from templates', () => {
const config = {
...defaultConfig,
name: '{{cmd}}',
};
const [result] = monitorHelper.makeDataSeries(
[{ metric: { cmd: 'brpop' }, values: series }],
config,
);
expect(result.name).toEqual('brpop');
});
it('supports space-padded template expressions', () => {
const config = {
...defaultConfig,
name: 'backend: {{ backend }}',
};
const [result] = monitorHelper.makeDataSeries(
[{ metric: { backend: 'HA Server' }, values: series }],
config,
);
expect(result.name).toEqual('backend: HA Server');
});
it('supports repeated template variables', () => {
const config = { ...defaultConfig, name: '{{cmd}}, {{cmd}}' };
const [result] = monitorHelper.makeDataSeries(
[{ metric: { cmd: 'brpop' }, values: series }],
config,
);
expect(result.name).toEqual('brpop, brpop');
});
it('updates multiple series names from templates', () => {
const config = {
...defaultConfig,
name: '{{job}}: {{cmd}}',
};
const [result] = monitorHelper.makeDataSeries(
[{ metric: { cmd: 'brpop', job: 'redis' }, values: series }],
config,
);
expect(result.name).toEqual('redis: brpop');
});
it('updates name for each series', () => {
const config = {
...defaultConfig,
name: '{{cmd}}',
};
const [firstSeries, secondSeries] = monitorHelper.makeDataSeries(
[
{ metric: { cmd: 'brpop' }, values: series },
{ metric: { cmd: 'zrangebyscore' }, values: series },
],
config,
);
expect(firstSeries.name).toEqual('brpop');
expect(secondSeries.name).toEqual('zrangebyscore');
});
});
});
......@@ -428,17 +428,19 @@ describe('newDate', () => {
});
describe('getDateInPast', () => {
const date = new Date(1563235200000); // 2019-07-16T00:00:00.000Z;
const date = new Date('2019-07-16T00:00:00.000Z');
const daysInPast = 90;
it('returns the correct date in the past', () => {
const dateInPast = datetimeUtility.getDateInPast(date, daysInPast);
expect(dateInPast).toBe('2019-04-17T00:00:00.000Z');
const expectedDateInPast = new Date('2019-04-17T00:00:00.000Z');
expect(dateInPast).toStrictEqual(expectedDateInPast);
});
it('does not modifiy the original date', () => {
datetimeUtility.getDateInPast(date, daysInPast);
expect(date).toStrictEqual(new Date(1563235200000));
expect(date).toStrictEqual(new Date('2019-07-16T00:00:00.000Z'));
});
});
......
import axios from '~/lib/utils/axios_utils';
import MockAdapter from 'axios-mock-adapter';
import { TEST_HOST } from 'helpers/test_constants';
import { backOffRequest } from '~/monitoring/stores/actions';
import statusCodes from '~/lib/utils/http_status';
import { backOff } from '~/lib/utils/common_utils';
jest.mock('~/lib/utils/common_utils');
const MAX_REQUESTS = 3;
describe('Monitoring store helpers', () => {
let mock;
// Mock underlying `backOff` function to remove in-built delay.
backOff.mockImplementation(
callback =>
new Promise((resolve, reject) => {
const stop = arg => (arg instanceof Error ? reject(arg) : resolve(arg));
const next = () => callback(next, stop);
callback(next, stop);
}),
);
beforeEach(() => {
mock = new MockAdapter(axios);
});
afterEach(() => {
mock.restore();
});
describe('backOffRequest', () => {
it('returns immediately when recieving a 200 status code', () => {
mock.onGet(TEST_HOST).reply(200);
return backOffRequest(() => axios.get(TEST_HOST)).then(() => {
expect(mock.history.get.length).toBe(1);
});
});
it(`repeats the network call ${MAX_REQUESTS} times when receiving a 204 response`, done => {
mock.onGet(TEST_HOST).reply(statusCodes.NO_CONTENT, {});
backOffRequest(() => axios.get(TEST_HOST))
.then(done.fail)
.catch(() => {
expect(mock.history.get.length).toBe(MAX_REQUESTS);
done();
});
});
});
});
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Release block with default props matches the snapshot 1`] = `
<div
class="card release-block"
id="v0.3"
>
<div
class="card-body"
>
<div
class="d-flex align-items-start"
>
<h2
class="card-title mt-0 mr-auto"
>
New release
<!---->
</h2>
<a
class="btn btn-default js-edit-button ml-2"
data-original-title="Edit this release"
href="http://0.0.0.0:3001/root/release-test/-/releases/v0.3/edit"
title=""
>
<svg
aria-hidden="true"
class="s16 ic-pencil"
>
<use
xlink:href="#pencil"
/>
</svg>
</a>
</div>
<div
class="card-subtitle d-flex flex-wrap text-secondary"
>
<div
class="append-right-8"
>
<svg
aria-hidden="true"
class="align-middle s16 ic-commit"
>
<use
xlink:href="#commit"
/>
</svg>
<span
data-original-title="Initial commit"
title=""
>
c22b0728
</span>
</div>
<div
class="append-right-8"
>
<svg
aria-hidden="true"
class="align-middle s16 ic-tag"
>
<use
xlink:href="#tag"
/>
</svg>
<span
data-original-title="Tag"
title=""
>
v0.3
</span>
</div>
<div
class="js-milestone-list-label"
>
<svg
aria-hidden="true"
class="align-middle s16 ic-flag"
>
<use
xlink:href="#flag"
/>
</svg>
<span
class="js-label-text"
>
Milestones
</span>
</div>
<a
class="append-right-4 prepend-left-4 js-milestone-link"
data-original-title="The 13.6 milestone!"
href="http://0.0.0.0:3001/root/release-test/-/milestones/2"
title=""
>
13.6
</a>
<a
class="append-right-4 prepend-left-4 js-milestone-link"
data-original-title="The 13.5 milestone!"
href="http://0.0.0.0:3001/root/release-test/-/milestones/1"
title=""
>
13.5
</a>
<!---->
<div
class="append-right-4"
>
<span
data-original-title="Aug 26, 2019 5:54pm GMT+0000"
title=""
>
released 1 month ago
</span>
</div>
<div
class="d-flex"
>
by
<a
class="user-avatar-link prepend-left-4"
href=""
>
<span>
<img
alt="root's avatar"
class="avatar s20 "
data-original-title=""
data-src="https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon"
height="20"
src="https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon"
title=""
width="20"
/>
<div
aria-hidden="true"
class="js-user-avatar-image-toolip d-none"
style="display: none;"
>
<div>
root
</div>
</div>
</span>
<!---->
</a>
</div>
</div>
<div
class="card-text prepend-top-default"
>
<b>
Assets
<span
class="js-assets-count badge badge-pill"
>
5
</span>
</b>
<ul
class="pl-0 mb-0 prepend-top-8 list-unstyled js-assets-list"
>
<li
class="append-bottom-8"
>
<a
class=""
data-original-title="Download asset"
href="https://google.com"
title=""
>
<svg
aria-hidden="true"
class="align-middle append-right-4 align-text-bottom s16 ic-package"
>
<use
xlink:href="#package"
/>
</svg>
my link
<span>
(external source)
</span>
</a>
</li>
<li
class="append-bottom-8"
>
<a
class=""
data-original-title="Download asset"
href="https://gitlab.com/gitlab-org/gitlab-foss/-/jobs/artifacts/v11.6.0-rc4/download?job=rspec-mysql+41%2F50"
title=""
>
<svg
aria-hidden="true"
class="align-middle append-right-4 align-text-bottom s16 ic-package"
>
<use
xlink:href="#package"
/>
</svg>
my second link
<!---->
</a>
</li>
</ul>
<div
class="dropdown"
>
<button
aria-expanded="false"
aria-haspopup="true"
class="btn btn-link"
data-toggle="dropdown"
type="button"
>
<svg
aria-hidden="true"
class="align-top append-right-4 s16 ic-doc-code"
>
<use
xlink:href="#doc-code"
/>
</svg>
Source code
<svg
aria-hidden="true"
class="s16 ic-arrow-down"
>
<use
xlink:href="#arrow-down"
/>
</svg>
</button>
<div
class="js-sources-dropdown dropdown-menu"
>
<li>
<a
class=""
href="http://0.0.0.0:3001/root/release-test/-/archive/v0.3/release-test-v0.3.zip"
>
Download zip
</a>
</li>
<li>
<a
class=""
href="http://0.0.0.0:3001/root/release-test/-/archive/v0.3/release-test-v0.3.tar.gz"
>
Download tar.gz
</a>
</li>
<li>
<a
class=""
href="http://0.0.0.0:3001/root/release-test/-/archive/v0.3/release-test-v0.3.tar.bz2"
>
Download tar.bz2
</a>
</li>
<li>
<a
class=""
href="http://0.0.0.0:3001/root/release-test/-/archive/v0.3/release-test-v0.3.tar"
>
Download tar
</a>
</li>
</div>
</div>
</div>
<div
class="card-text prepend-top-default"
>
<div>
<p
data-sourcepos="1:1-1:21"
dir="auto"
>
A super nice release!
</p>
</div>
</div>
</div>
</div>
`;
......@@ -39,34 +39,18 @@ describe('Release block', () => {
const milestoneListLabel = () => wrapper.find('.js-milestone-list-label');
const editButton = () => wrapper.find('.js-edit-button');
const RealDate = Date;
beforeEach(() => {
// timeago.js calls Date(), so let's mock that case to avoid time-dependent test failures.
const constantDate = new Date('2019-10-25T00:12:00');
/* eslint no-global-assign:off */
global.Date = jest.fn((...props) =>
props.length ? new RealDate(...props) : new RealDate(constantDate),
);
Object.assign(Date, RealDate);
releaseClone = JSON.parse(JSON.stringify(release));
});
afterEach(() => {
wrapper.destroy();
global.Date = RealDate;
});
describe('with default props', () => {
beforeEach(() => factory(release));
it('matches the snapshot', () => {
expect(wrapper.element).toMatchSnapshot();
});
it("renders the block with an id equal to the release's tag name", () => {
expect(wrapper.attributes().id).toBe('v0.3');
});
......
# frozen_string_literal: true
require 'spec_helper'
describe Banzai::Filter::AssetProxyFilter do
......
# frozen_string_literal: true
require 'spec_helper'
describe OmniAuth::Strategies::SAML, type: :strategy do
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册