Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-11-01 12:11:46 +00:00
parent a67852da7f
commit 41876b483a
90 changed files with 361 additions and 317 deletions

View File

@ -162,13 +162,16 @@ Naming/FileName:
- SSE
- JWT
- HLL
- VSCode
- GPG
- OTP
- GID
- AR
- RSpec
- Javascript
- ECDSA
- ED25519
- GitLab
- JavaScript
- VSCode
# default ones:
- CLI
- DSL

View File

@ -2597,76 +2597,6 @@ Rails/IncludeUrlHelper:
- 'spec/lib/banzai/filter/reference_redactor_filter_spec.rb'
- 'spec/lib/banzai/reference_redactor_spec.rb'
# WIP: https://gitlab.com/gitlab-org/gitlab/-/issues/343244
Naming/FileName:
Exclude:
- 'app/controllers/concerns/clientside_preview_csp.rb'
- 'app/controllers/concerns/one_trust_csp.rb'
- 'app/controllers/concerns/static_object_external_storage_csp.rb'
- 'app/models/blob_viewer/csv.rb'
- 'app/views/issues/_issues_calendar.ics.ruby'
- 'ee/app/models/dast/branch.rb'
- 'ee/app/models/sca.rb'
- 'ee/lib/ee/gitlab/usage_data_counters/hll_redis_counter.rb'
- 'ee/lib/elastic/v12p1/application_class_proxy.rb'
- 'ee/lib/elastic/v12p1/application_instance_proxy.rb'
- 'ee/lib/elastic/v12p1/config.rb'
- 'ee/lib/elastic/v12p1/issue_class_proxy.rb'
- 'ee/lib/elastic/v12p1/issue_instance_proxy.rb'
- 'ee/lib/elastic/v12p1/merge_request_class_proxy.rb'
- 'ee/lib/elastic/v12p1/merge_request_instance_proxy.rb'
- 'ee/lib/elastic/v12p1/milestone_class_proxy.rb'
- 'ee/lib/elastic/v12p1/milestone_instance_proxy.rb'
- 'ee/lib/elastic/v12p1/note_class_proxy.rb'
- 'ee/lib/elastic/v12p1/note_instance_proxy.rb'
- 'ee/lib/elastic/v12p1/project_class_proxy.rb'
- 'ee/lib/elastic/v12p1/project_instance_proxy.rb'
- 'ee/lib/elastic/v12p1/project_wiki_class_proxy.rb'
- 'ee/lib/elastic/v12p1/project_wiki_instance_proxy.rb'
- 'ee/lib/elastic/v12p1/repository_class_proxy.rb'
- 'ee/lib/elastic/v12p1/repository_instance_proxy.rb'
- 'ee/lib/elastic/v12p1/routing.rb'
- 'ee/lib/elastic/v12p1/snippet_class_proxy.rb'
- 'ee/lib/elastic/v12p1/snippet_instance_proxy.rb'
- 'ee/lib/gitlab/auth/smartcard/san_extension.rb'
- 'ee/lib/gitlab/cidr.rb'
- 'ee/lib/gitlab/elastic/bool_expr.rb'
- 'ee/lib/gitlab/spdx/catalogue.rb'
- 'ee/lib/gitlab/spdx/catalogue_gateway.rb'
- 'ee/lib/gitlab/spdx/license.rb'
- 'ee/lib/gitlab/status_page/storage/object.rb'
- 'haml_lint/inline_javascript.rb'
- 'lib/api/entities/mr_note.rb'
- 'lib/api/helpers/sse_helpers.rb'
- 'lib/gitlab/ci/pipeline/chain/command.rb'
- 'lib/gitlab/database/migrations/observation.rb'
- 'lib/gitlab/health_checks/metric.rb'
- 'lib/gitlab/health_checks/probes/status.rb'
- 'lib/gitlab/health_checks/result.rb'
- 'lib/gitlab/jwt_token.rb'
- 'lib/gitlab/middleware/release_env.rb'
- 'lib/gitlab/redis/hll.rb'
- 'lib/gitlab/slash_commands/result.rb'
- 'lib/gitlab/template_parser/ast.rb'
- 'lib/gitlab/usage/metrics/instrumentations/redis_hll_metric.rb'
- 'lib/gitlab/usage_data_counters/hll_redis_counter.rb'
- 'lib/gitlab/usage_data_counters/vs_code_extension_activity_unique_counter.rb'
- 'qa/qa/fixtures/auto_devops_rack/config.ru'
- 'qa/qa/resource/user_gpg.rb'
- 'qa/qa/runtime/gpg.rb'
- 'qa/qa/runtime/key/ecdsa.rb'
- 'qa/qa/runtime/key/ed25519.rb'
- 'qa/qa/support/otp.rb'
- 'qa/qa/tools/initialize_gitlab_auth.rb'
- 'rubocop/cop/gitlab/change_timzone.rb'
- 'rubocop/cop/gitlab/keys-first-and-values-first.rb'
- 'rubocop/cop/graphql/gid_expected_type.rb'
- 'rubocop/cop/performance/ar_count_each.rb'
- 'rubocop/cop/performance/ar_exists_and_present_blank.rb'
- 'rubocop/rubocop.rb'
- 'tooling/lib/tooling/images.rb'
- 'tooling/lib/tooling/parallel_rspec_runner.rb'
# TODO issue: https://gitlab.com/gitlab-org/gitlab/-/issues/344279
Style/OpenStructUse:
Exclude:

View File

@ -49,7 +49,7 @@ export const initProjectsField = () => {
{ default: createDefaultClient },
]) => {
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
defaultClient: createDefaultClient(),
});
Vue.use(VueApollo);

View File

@ -15,7 +15,7 @@ import {
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
defaultClient: createDefaultClient(),
});
const initApp = (el, component, userPropKey, props = {}) => {

View File

@ -38,7 +38,6 @@ export default () => {
return defaultDataIdFromObject(object);
},
},
assumeImmutableResults: true,
},
),
});

View File

@ -59,6 +59,5 @@ export default new VueApollo({
cacheConfig: {
fragmentMatcher,
},
assumeImmutableResults: true,
}),
});

View File

@ -6,7 +6,7 @@ import UsageTrendsApp from './components/app.vue';
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
defaultClient: createDefaultClient(),
});
export default () => {

View File

@ -6,7 +6,7 @@ import createDefaultClient from '~/lib/graphql';
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
defaultClient: createDefaultClient(),
});
export default (containerId = 'js-artifacts-settings-app') => {

View File

@ -17,6 +17,5 @@ export const gqlClient = createDefaultClient(
fragmentMatcher,
},
assumeImmutableResults: true,
},
);

View File

@ -8,12 +8,7 @@ import { parseBoolean } from '~/lib/utils/common_utils';
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(
{},
{
assumeImmutableResults: true,
},
),
defaultClient: createDefaultClient(),
});
export default (params = {}) => {

View File

@ -8,9 +8,7 @@ import CiLint from './components/ci_lint.vue';
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(resolvers, {
assumeImmutableResults: true,
}),
defaultClient: createDefaultClient(resolvers),
});
export default (containerId = '#js-ci-lint') => {

View File

@ -12,12 +12,7 @@ export default () => {
return null;
}
const defaultClient = createDefaultClient(
{},
{
assumeImmutableResults: true,
},
);
const defaultClient = createDefaultClient();
const { agentName, projectPath } = el.dataset;
return new Vue({

View File

@ -8,7 +8,7 @@ export default (Vue, VueApollo) => {
return null;
}
const defaultClient = createDefaultClient({}, { assumeImmutableResults: true });
const defaultClient = createDefaultClient();
const {
emptyStateImage,

View File

@ -88,7 +88,6 @@ const defaultClient = createDefaultClient(
fragmentMatcher,
},
typeDefs,
assumeImmutableResults: true,
},
);

View File

@ -8,7 +8,7 @@ Vue.use(Translate);
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
defaultClient: createDefaultClient(),
});
export default () => {

View File

@ -2,16 +2,12 @@ import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
import environmentApp from './queries/environmentApp.query.graphql';
import { resolvers } from './resolvers';
import typedefs from './typedefs.graphql';
import typeDefs from './typedefs.graphql';
export const apolloProvider = (endpoint) => {
const defaultClient = createDefaultClient(
resolvers(endpoint),
{
assumeImmutableResults: true,
},
typedefs,
);
const defaultClient = createDefaultClient(resolvers(endpoint), {
typeDefs,
});
const { cache } = defaultClient;
cache.writeQuery({

View File

@ -9,7 +9,7 @@ Vue.use(Translate);
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
defaultClient: createDefaultClient(),
});
export default (el) => {

View File

@ -20,12 +20,7 @@ export default () => {
} = domEl.dataset;
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(
{},
{
assumeImmutableResults: true,
},
),
defaultClient: createDefaultClient(),
});
// eslint-disable-next-line no-new

View File

@ -376,8 +376,4 @@ export function createResolvers({ endpoints, sourceUrl, GroupsManager = SourceGr
}
export const createApolloClient = ({ sourceUrl, endpoints }) =>
createDefaultClient(
createResolvers({ sourceUrl, endpoints }),
{ assumeImmutableResults: true },
typeDefs,
);
createDefaultClient(createResolvers({ sourceUrl, endpoints }), { typeDefs });

View File

@ -24,7 +24,7 @@ export default () => {
} = domEl.dataset;
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
defaultClient: createDefaultClient(),
});
return new Vue({

View File

@ -10,12 +10,7 @@ export default function initIssuableSuggestions() {
const issueTitle = document.getElementById('issue_title');
const { projectPath } = el.dataset;
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(
{},
{
assumeImmutableResults: true,
},
),
defaultClient: createDefaultClient(),
});
return new Vue({

View File

@ -24,7 +24,7 @@ export function mountJiraIssuesListApp() {
}
Vue.use(VueApollo);
const defaultClient = createDefaultClient({}, { assumeImmutableResults: true });
const defaultClient = createDefaultClient();
const apolloProvider = new VueApollo({
defaultClient,
});
@ -103,7 +103,7 @@ export function mountIssuesListApp() {
},
};
const defaultClient = createDefaultClient(resolvers, { assumeImmutableResults: true });
const defaultClient = createDefaultClient(resolvers);
const apolloProvider = new VueApollo({
defaultClient,
});

View File

@ -14,12 +14,7 @@ export default async function initJiraConnectBranches() {
const { initialBranchName, successStateSvgPath } = el.dataset;
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(
{},
{
assumeImmutableResults: true,
},
),
defaultClient: createDefaultClient(),
});
return new Vue({

View File

@ -6,7 +6,7 @@ import App from './components/jira_import_app.vue';
Vue.use(VueApollo);
const defaultClient = createDefaultClient({}, { assumeImmutableResults: true });
const defaultClient = createDefaultClient();
const apolloProvider = new VueApollo({
defaultClient,

View File

@ -9,12 +9,7 @@ Vue.use(VueApollo);
Vue.use(GlToast);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(
{},
{
assumeImmutableResults: true,
},
),
defaultClient: createDefaultClient(),
});
export default (containerId = 'js-jobs-table') => {

View File

@ -48,7 +48,6 @@ export const stripWhitespaceFromQuery = (url, path) => {
export default (resolvers = {}, config = {}) => {
const {
assumeImmutableResults,
baseUrl,
batchMax = 10,
cacheConfig,
@ -161,10 +160,10 @@ export default (resolvers = {}, config = {}) => {
link: appLink,
cache: new InMemoryCache({
...cacheConfig,
freezeResults: assumeImmutableResults,
freezeResults: true,
}),
resolvers,
assumeImmutableResults,
assumeImmutableResults: true,
defaultOptions: {
query: {
fetchPolicy,

View File

@ -48,12 +48,7 @@ export default (elements) => {
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(
{},
{
assumeImmutableResults: true,
},
),
defaultClient: createDefaultClient(),
});
const listenerAddedAttr = 'data-mr-listener-added';

View File

@ -5,10 +5,5 @@ import createDefaultClient from '~/lib/graphql';
Vue.use(VueApollo);
export const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(
{},
{
assumeImmutableResults: true,
},
),
defaultClient: createDefaultClient(),
});

View File

@ -17,7 +17,6 @@ export const apolloProvider = new VueApollo({
cacheConfig: {
fragmentMatcher,
},
assumeImmutableResults: true,
},
),
});

View File

@ -5,10 +5,5 @@ import createDefaultClient from '~/lib/graphql';
Vue.use(VueApollo);
export const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(
{},
{
assumeImmutableResults: true,
},
),
defaultClient: createDefaultClient(),
});

View File

@ -5,10 +5,5 @@ import createDefaultClient from '~/lib/graphql';
Vue.use(VueApollo);
export const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(
{},
{
assumeImmutableResults: true,
},
),
defaultClient: createDefaultClient(),
});

View File

@ -14,7 +14,7 @@ import '~/sourcegraph/load';
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
defaultClient: createDefaultClient(),
});
const viewBlobEl = document.querySelector('#js-view-blob-app');

View File

@ -28,7 +28,7 @@ export default function initMergeRequestShow() {
const el = document.querySelector('.js-mr-status-box');
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
defaultClient: createDefaultClient(),
});
// eslint-disable-next-line no-new
new Vue({

View File

@ -9,12 +9,7 @@ export function initInstallRunner(componentId = 'js-install-runner') {
const installRunnerEl = document.getElementById(componentId);
if (installRunnerEl) {
const defaultClient = createDefaultClient(
{},
{
assumeImmutableResults: true,
},
);
const defaultClient = createDefaultClient();
const apolloProvider = new VueApollo({
defaultClient,

View File

@ -61,7 +61,6 @@ export const initPipelineEditor = (selector = '#js-pipeline-editor') => {
defaultClient: createDefaultClient(resolvers, {
typeDefs,
useGet: true,
assumeImmutableResults: true,
}),
});
const { cache } = apolloProvider.clients.defaultClient;

View File

@ -5,7 +5,6 @@ export const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(
{},
{
assumeImmutableResults: true,
useGet: true,
},
),

View File

@ -5,12 +5,7 @@ import createDefaultClient from '~/lib/graphql';
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(
{},
{
assumeImmutableResults: true,
},
),
defaultClient: createDefaultClient(),
});
export const initCommitPipelineMiniGraph = async (selector = '.js-commit-pipeline-mini-graph') => {

View File

@ -50,7 +50,7 @@ export function initNewProjectUrlSelect() {
new Vue({
el,
apolloProvider: new VueApollo({
defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
defaultClient: createDefaultClient(),
}),
provide: {
namespaceFullPath: el.dataset.namespaceFullPath,

View File

@ -7,7 +7,7 @@ import ProjectPipelinesCharts from './components/app.vue';
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
defaultClient: createDefaultClient(),
});
const mountPipelineChartsApp = (el) => {

View File

@ -25,7 +25,7 @@ export default (containerId = 'js-project-storage-count-app') => {
} = el.dataset;
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
defaultClient: createDefaultClient(),
});
return new Vue({

View File

@ -6,7 +6,7 @@ import TerraformNotification from './components/terraform_notification.vue';
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient({}, { assumeImmtableResults: true }),
defaultClient: createDefaultClient(),
});
export default () => {

View File

@ -9,7 +9,6 @@ export const apolloProvider = new VueApollo({
{},
{
batchMax: 1,
assumeImmutableResults: true,
},
),
});

View File

@ -24,7 +24,6 @@ export default () => {
// the purpose of making separate requests. So we explicitly
// disable batching on this page.
batchMax: 1,
assumeImmutableResults: true,
},
),
});

View File

@ -6,12 +6,7 @@ import ReleaseShowApp from './components/app_show.vue';
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(
{},
{
assumeImmutableResults: true,
},
),
defaultClient: createDefaultClient(),
});
export default () => {

View File

@ -64,7 +64,6 @@ const defaultClient = createDefaultClient(
/* eslint-enable @gitlab/require-i18n-strings */
},
},
assumeImmutableResults: true,
},
);

View File

@ -19,12 +19,7 @@ export const initAdminRunners = (selector = '#js-admin-runners') => {
const { activeRunnersCount, registrationToken, runnerInstallHelpPage } = el.dataset;
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(
{},
{
assumeImmutableResults: true,
},
),
defaultClient: createDefaultClient(),
});
return new Vue({

View File

@ -23,12 +23,7 @@ export const initGroupRunners = (selector = '#js-group-runners') => {
} = el.dataset;
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(
{},
{
assumeImmutableResults: true,
},
),
defaultClient: createDefaultClient(),
});
return new Vue({

View File

@ -15,12 +15,7 @@ export const initRunnerDetail = (selector = '#js-runner-details') => {
const { runnerId } = el.dataset;
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(
{},
{
assumeImmutableResults: true,
},
),
defaultClient: createDefaultClient(),
});
return new Vue({

View File

@ -14,7 +14,7 @@ export const initSecurityConfiguration = (el) => {
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
defaultClient: createDefaultClient(),
});
const {

View File

@ -25,7 +25,6 @@ export const defaultClient = createDefaultClient(resolvers, {
cacheConfig: {
fragmentMatcher,
},
assumeImmutableResults: true,
});
export const apolloProvider = new VueApollo({

View File

@ -18,7 +18,6 @@ export default function appFactory(el, Component) {
{},
{
batchMax: 1,
assumeImmutableResults: true,
},
),
});

View File

@ -22,7 +22,6 @@ const createApolloProvider = (appData) => {
},
{
typeDefs,
assumeImmutableResults: true,
},
);

View File

@ -22,7 +22,6 @@ export default () => {
return object.id || defaultDataIdFromObject(object);
},
},
assumeImmutableResults: true,
});
const { emptyStateImage, projectPath, accessTokensPath, terraformApiUrl, username } = el.dataset;

View File

@ -6,7 +6,7 @@ import TokenAccess from './components/token_access.vue';
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
defaultClient: createDefaultClient(),
});
export const initTokenAccess = (containerId = 'js-ci-token-access-app') => {

View File

@ -13,12 +13,7 @@ Vue.use(Translate);
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(
{},
{
assumeImmutableResults: true,
},
),
defaultClient: createDefaultClient(),
});
export default () => {

View File

@ -38,7 +38,6 @@ export default (selector) => {
return defaultDataIdFromObject(object);
},
},
assumeImmutableResults: true,
}),
});

View File

@ -82,7 +82,7 @@ export default {
});
this.$root.$on('clicked::link', (e) => {
window.location = e.target.href;
window.location = e.currentTarget.href;
});
},

View File

@ -5,5 +5,5 @@ import createDefaultClient from '~/lib/graphql';
Vue.use(VueApollo);
export default new VueApollo({
defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
defaultClient: createDefaultClient(),
});

View File

@ -4,6 +4,7 @@ import { IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
import createDefaultClient from '~/lib/graphql';
import workItemQuery from './work_item.query.graphql';
import introspectionQueryResultData from './fragmentTypes.json';
import typeDefs from './typedefs.graphql';
const fragmentMatcher = new IntrospectionFragmentMatcher({
introspectionQueryResultData,
@ -18,7 +19,7 @@ export function createApolloProvider() {
cacheConfig: {
fragmentMatcher,
},
assumeImmutableResults: true,
typeDefs,
},
);

View File

@ -1943,7 +1943,7 @@ body.gl-dark {
.gl-display-none {
display: none;
}
@media (min-width: 36rem) {
@media (min-width: 576px) {
.gl-sm-display-block {
display: block;
}

View File

@ -1621,7 +1621,7 @@ svg.s16 {
.gl-display-none {
display: none;
}
@media (min-width: 36rem) {
@media (min-width: 576px) {
.gl-sm-display-block {
display: block;
}

View File

@ -776,7 +776,7 @@ svg {
.gl-mb-5 {
margin-bottom: 1rem;
}
@media (min-width: 36rem) {
@media (min-width: 576px) {
.gl-sm-mt-0 {
margin-top: 0;
}

View File

@ -1,3 +1,3 @@
= sprite_icon('history', css_class: 'gl-mr-1 gl-vertical-align-text-bottom')
= succeed '.' do
= _("To find the state of this project's repository at the time of any of these versions, check out %{link_start}the tags%{link_end}.").html_safe % { link_start: "<a href='#{project_tags_path(viewer.project)}'>".html_safe, link_end: "</a>".html_safe }
= _("To find the state of this project's repository at the time of any of these versions, check out %{link_start}the tags%{link_end}").html_safe % { link_start: "<a href='#{project_tags_path(viewer.project)}'>".html_safe, link_end: "</a>".html_safe }

View File

@ -1,4 +1,4 @@
= sprite_icon('information-o', css_class: 'gl-vertical-align-middle! gl-mr-2')
= succeed '.' do
- link_to_wiki = link_to(_("the wiki"), wiki_path(viewer.project.wiki))
= _("To learn more about this project, read %{link_to_wiki}.").html_safe % { link_to_wiki: link_to_wiki }
= _("To learn more about this project, read %{link_to_wiki}").html_safe % { link_to_wiki: link_to_wiki }

View File

@ -39,4 +39,5 @@ ActiveSupport::Inflector.inflections do |inflect|
inflect.acronym 'EE'
inflect.acronym 'JH'
inflect.acronym 'CSP'
inflect.acronym 'VSCode'
end

View File

@ -0,0 +1,26 @@
# frozen_string_literal: true
class BackfillUserNamespace < Gitlab::Database::Migration[1.0]
MIGRATION = 'BackfillUserNamespace'
INTERVAL = 2.minutes
BATCH_SIZE = 1_000
SUB_BATCH_SIZE = 200
DOWNTIME = false
def up
queue_batched_background_migration(
MIGRATION,
:namespaces,
:id,
job_interval: INTERVAL,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
end
def down
Gitlab::Database::BackgroundMigration::BatchedMigration
.for_configuration(MIGRATION, :namespaces, :id, [])
.delete_all
end
end

View File

@ -0,0 +1 @@
3aaf2a4fa834331768e2acc10f67b8d456e70aca9784787e40b55dade7b6f64c

View File

@ -103,7 +103,6 @@ Default client accepts two parameters: `resolvers` and `config`.
- `config` parameter takes an object of configuration settings:
- `cacheConfig` field accepts an optional object of settings to [customize Apollo cache](https://www.apollographql.com/docs/react/caching/cache-configuration/#configuring-the-cache)
- `baseUrl` allows us to pass a URL for GraphQL endpoint different from our main endpoint (for example, `${gon.relative_url_root}/api/graphql`)
- `assumeImmutableResults` (set to `false` by default) - this setting, when set to `true`, assumes that every single operation on updating Apollo Cache is immutable. It also sets `freezeResults` to `true`, so any attempt on mutating Apollo Cache throws a console warning in development environment. Please ensure you're following the immutability pattern on cache update operations before setting this option to `true`.
- `fetchPolicy` determines how you want your component to interact with the Apollo cache. Defaults to "cache-first".
### Multiple client queries for the same object
@ -179,7 +178,7 @@ with a **new and updated** object.
To facilitate the process of updating the cache and returning the new object we
use the library [Immer](https://immerjs.github.io/immer/).
When possible, follow these conventions:
Please, follow these conventions:
- The updated cache is named `data`.
- The original cache data is named `sourceData`.
@ -204,11 +203,6 @@ client.writeQuery({
As shown in the code example by using `produce`, we can perform any kind of direct manipulation of the
`draftState`. Besides, `immer` guarantees that a new state which includes the changes to `draftState` is generated.
Finally, to verify whether the immutable cache update is working properly, we need to change
`assumeImmutableResults` to `true` in the default client configuration. See [Apollo Client](#apollo-client) for more information.
If everything is working properly `assumeImmutableResults` should remain set to `true`.
## Usage in Vue
To use Vue Apollo, import the [Vue Apollo](https://github.com/vuejs/vue-apollo) plugin as well

View File

@ -153,7 +153,7 @@ module API
requires setting[:name], type: setting[:type], desc: setting[:desc]
end
end
post "#{path}/#{integration_slug.underscore}/trigger" do
post "#{path}/#{integration_slug.underscore}/trigger", urgency: :low do
project = find_project(params[:id])
# This is not accurate, but done to prevent leakage of the project names

View File

@ -4,15 +4,7 @@ module ErrorTracking
module Collector
class SentryRequestParser
def self.parse(request)
# Request body can be "" or "gzip".
# If later then body was compressed with Zlib.gzip
encoding = request.headers['Content-Encoding']
body = if encoding == 'gzip'
Zlib.gunzip(request.body.read)
else
request.body.read
end
body = request.body.read
# Request body contains 3 json objects merged together in one StringIO.
# We need to separate and parse them into array of hash objects.

View File

@ -0,0 +1,38 @@
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
# Backfills the `namespaces.type` column, replacing any
# instances of `NULL` with `User`
class BackfillUserNamespace
include Gitlab::Database::DynamicModelHelpers
def perform(start_id, end_id, batch_table, batch_column, sub_batch_size, pause_ms)
parent_batch_relation = relation_scoped_to_range(batch_table, batch_column, start_id, end_id)
parent_batch_relation.each_batch(column: batch_column, of: sub_batch_size, order_hint: :type) do |sub_batch|
batch_metrics.time_operation(:update_all) do
sub_batch.update_all(type: 'User')
end
pause_ms = 0 if pause_ms < 0
sleep(pause_ms * 0.001)
end
end
def batch_metrics
@batch_metrics ||= Gitlab::Database::BackgroundMigration::BatchMetrics.new
end
private
def connection
ActiveRecord::Base.connection
end
def relation_scoped_to_range(source_table, source_key_column, start_id, stop_id)
define_batchable_model(source_table)
.where(source_key_column => start_id..stop_id)
.where(type: nil)
end
end
end
end

View File

@ -11,7 +11,8 @@ class Gitlab::Ci::Build::AutoRetry
ci_quota_exceeded: 0,
no_matching_runner: 0,
missing_dependency_failure: 0,
forward_deployment_failure: 0
forward_deployment_failure: 0,
environment_creation_failure: 0
}.freeze
def initialize(build)

View File

@ -27,10 +27,10 @@ module Gitlab
end
def compressed_et_request?(env)
env['REQUEST_METHOD'] == 'POST' &&
env['HTTP_CONTENT_ENCODING'] == 'gzip' &&
env['CONTENT_TYPE'] == 'application/json' &&
env['PATH_INFO'].start_with?((File.join(relative_url, COLLECTOR_PATH)))
post_request?(env) &&
gzip_encoding?(env) &&
match_content_type?(env) &&
match_path?(env)
end
def too_large
@ -44,6 +44,23 @@ module Gitlab
def extract(input)
Zlib::GzipReader.new(input).read(MAXIMUM_BODY_SIZE + 1)
end
def post_request?(env)
env['REQUEST_METHOD'] == 'POST'
end
def gzip_encoding?(env)
env['HTTP_CONTENT_ENCODING'] == 'gzip'
end
def match_content_type?(env)
env['CONTENT_TYPE'] == 'application/json' ||
env['CONTENT_TYPE'] == 'application/x-sentry-envelope'
end
def match_path?(env)
env['PATH_INFO'].start_with?((File.join(relative_url, COLLECTOR_PATH)))
end
end
end
end

View File

@ -35813,7 +35813,7 @@ msgstr ""
msgid "To ensure no loss of personal content, this account should only be used for matters related to %{group_name}."
msgstr ""
msgid "To find the state of this project's repository at the time of any of these versions, check out %{link_start}the tags%{link_end}."
msgid "To find the state of this project's repository at the time of any of these versions, check out %{link_start}the tags%{link_end}"
msgstr ""
msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
@ -35849,7 +35849,7 @@ msgstr ""
msgid "To keep this project going, create a new merge request"
msgstr ""
msgid "To learn more about this project, read %{link_to_wiki}."
msgid "To learn more about this project, read %{link_to_wiki}"
msgstr ""
msgid "To move or copy an entire GitLab project from another GitLab installation to this one, navigate to the original project's settings page, generate an export file, and upload it here."

View File

@ -55,9 +55,9 @@
"@babel/preset-env": "^7.10.1",
"@gitlab/at.js": "1.5.7",
"@gitlab/favicon-overlay": "2.0.0",
"@gitlab/svgs": "1.218.0",
"@gitlab/svgs": "1.219.0",
"@gitlab/tributejs": "1.0.0",
"@gitlab/ui": "32.21.0",
"@gitlab/ui": "32.28.0",
"@gitlab/visual-review-tools": "1.6.1",
"@rails/actioncable": "6.1.4-1",
"@rails/ujs": "6.1.4-1",

View File

@ -1,4 +1,4 @@
# rubocop:disable Naming/FileName
# rubocop:todo Naming/FileName
# frozen_string_literal: true
module QA

View File

@ -1,4 +1,4 @@
# rubocop:disable Naming/FileName
# rubocop:todo Naming/FileName
# frozen_string_literal: true
module QA

View File

@ -4,10 +4,10 @@ exports[`Registry Breadcrumb when is not rootRoute renders 1`] = `
<div
class="gl-breadcrumbs"
>
<ol
class="breadcrumb gl-breadcrumb-list"
>
<li
class="breadcrumb-item gl-breadcrumb-item"
>
@ -15,24 +15,28 @@ exports[`Registry Breadcrumb when is not rootRoute renders 1`] = `
class=""
href="/"
target="_self"
/>
</li>
<span
class="gl-breadcrumb-separator"
data-testid="separator"
>
<svg
aria-hidden="true"
class="gl-icon s8"
data-testid="angle-right-icon"
role="img"
>
<use
href="#angle-right"
/>
</svg>
</span>
<span>
</span>
<span
class="gl-breadcrumb-separator"
data-testid="separator"
>
<svg
aria-hidden="true"
class="gl-icon s8"
data-testid="angle-right-icon"
role="img"
>
<use
href="#angle-right"
/>
</svg>
</span>
</a>
</li>
<li
class="breadcrumb-item gl-breadcrumb-item"
>
@ -40,10 +44,14 @@ exports[`Registry Breadcrumb when is not rootRoute renders 1`] = `
class=""
href="#"
target="_self"
/>
>
<span>
</span>
<!---->
</a>
</li>
<!---->
</ol>
</div>
`;
@ -52,10 +60,10 @@ exports[`Registry Breadcrumb when is rootRoute renders 1`] = `
<div
class="gl-breadcrumbs"
>
<ol
class="breadcrumb gl-breadcrumb-list"
>
<li
class="breadcrumb-item gl-breadcrumb-item"
>
@ -63,10 +71,14 @@ exports[`Registry Breadcrumb when is rootRoute renders 1`] = `
class=""
href="/"
target="_self"
/>
>
<span>
</span>
<!---->
</a>
</li>
<!---->
</ol>
</div>
`;

View File

@ -33,12 +33,5 @@ RSpec.describe ErrorTracking::Collector::SentryRequestParser do
context 'plain text sentry request' do
it_behaves_like 'valid parser'
end
context 'gzip encoded sentry request' do
let(:headers) { { 'Content-Encoding' => 'gzip' } }
let(:body) { Zlib.gzip(raw_event) }
it_behaves_like 'valid parser'
end
end
end

View File

@ -0,0 +1,39 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::BackfillUserNamespace, :migration, schema: 20210930211936 do
let(:migration) { described_class.new }
let(:namespaces_table) { table(:namespaces) }
let(:table_name) { 'namespaces' }
let(:batch_column) { :id }
let(:sub_batch_size) { 100 }
let(:pause_ms) { 0 }
subject(:perform_migration) { migration.perform(1, 10, table_name, batch_column, sub_batch_size, pause_ms) }
before do
namespaces_table.create!(id: 1, name: 'test1', path: 'test1', type: nil)
namespaces_table.create!(id: 2, name: 'test2', path: 'test2', type: 'User')
namespaces_table.create!(id: 3, name: 'test3', path: 'test3', type: 'Group')
namespaces_table.create!(id: 4, name: 'test4', path: 'test4', type: nil)
namespaces_table.create!(id: 11, name: 'test11', path: 'test11', type: nil)
end
it 'backfills `type` for the selected records', :aggregate_failures do
queries = ActiveRecord::QueryRecorder.new do
perform_migration
end
expect(queries.count).to eq(3)
expect(namespaces_table.where(type: 'User').count).to eq 3
expect(namespaces_table.where(type: 'User').pluck(:id)).to match_array([1, 2, 4])
end
it 'tracks timings of queries' do
expect(migration.batch_metrics.timings).to be_empty
expect { perform_migration }.to change { migration.batch_metrics.timings }
end
end

View File

@ -26,6 +26,7 @@ RSpec.describe Gitlab::Ci::Build::AutoRetry do
"no matching runner" | 0 | { max: 2 } | :no_matching_runner | false
"missing dependencies" | 0 | { max: 2 } | :missing_dependency_failure | false
"forward deployment failure" | 0 | { max: 2 } | :forward_deployment_failure | false
"environment creation failure" | 0 | { max: 2 } | :environment_creation_failure | false
end
with_them do

View File

@ -0,0 +1,29 @@
# frozen_string_literal: true
require 'spec_helper'
require_migration!
RSpec.describe BackfillUserNamespace do
let_it_be(:migration) { described_class::MIGRATION }
describe '#up' do
it 'schedules background jobs for each batch of namespaces' do
migrate!
expect(migration).to have_scheduled_batched_migration(
table_name: :namespaces,
column_name: :id,
interval: described_class::INTERVAL
)
end
end
describe '#down' do
it 'deletes all batched migration records' do
migrate!
schema_migrate_down!
expect(migration).not_to have_scheduled_batched_migration
end
end
end

View File

@ -96,6 +96,20 @@ RSpec.describe API::ErrorTracking::Collector do
end
end
context 'gzip body' do
let(:headers) do
{
'X-Sentry-Auth' => "Sentry sentry_key=#{client_key.public_key}",
'HTTP_CONTENT_ENCODING' => 'gzip',
'CONTENT_TYPE' => 'application/x-sentry-envelope'
}
end
let(:params) { ActiveSupport::Gzip.compress(raw_event) }
it_behaves_like 'successful request'
end
it_behaves_like 'successful request'
end
@ -131,7 +145,7 @@ RSpec.describe API::ErrorTracking::Collector do
}
end
let(:raw_event) { ActiveSupport::Gzip.compress(fixture_file('error_tracking/parsed_event.json')) }
let(:params) { ActiveSupport::Gzip.compress(raw_event) }
it_behaves_like 'successful request'
end

View File

@ -28,11 +28,15 @@ module ProjectForksHelper
unless params[:target_project] || params[:using_service]
target_level = [project.visibility_level, namespace.visibility_level].min
visibility_level = Gitlab::VisibilityLevel.closest_allowed_level(target_level)
# Builds and MRs can't have higher visibility level than repository access level.
builds_access_level = [project.builds_access_level, project.repository_access_level].min
params[:target_project] =
create(:project,
(:repository if create_repository),
visibility_level: visibility_level, creator: user, namespace: namespace)
visibility_level: visibility_level,
builds_access_level: builds_access_level,
creator: user, namespace: namespace)
end
service = Projects::ForkService.new(project, user, params)

View File

@ -374,6 +374,10 @@ func configureRoutes(u *upstream) {
// Geo API routes
u.route("", "^/api/v4/geo_nodes", defaultUpstream),
u.route("", "^/api/v4/geo_replication", defaultUpstream),
u.route("", "^/api/v4/geo/proxy_git_ssh", defaultUpstream),
// Internal API routes
u.route("", "^/api/v4/internal", defaultUpstream),
// Don't define a catch-all route. If a route does not match, then we know
// the request should be proxied.

View File

@ -0,0 +1,47 @@
package upstream
import (
"testing"
)
func TestProjectNotExistingGitHttpPullWithGeoProxy(t *testing.T) {
testCases := []testCase{
{"secondary info/refs", "/group/project.git/info/refs", "Local Rails server received request to path /group/project.git/info/refs"},
{"primary info/refs", "/-/push_from_secondary/2/group/project.git/info/refs", "Geo primary received request to path /-/push_from_secondary/2/group/project.git/info/refs"},
{"primary upload-pack", "/-/push_from_secondary/2/group/project.git/git-upload-pack", "Geo primary received request to path /-/push_from_secondary/2/group/project.git/git-upload-pack"},
}
runTestCasesWithGeoProxyEnabled(t, testCases)
}
func TestProjectNotExistingGitHttpPushWithGeoProxy(t *testing.T) {
testCases := []testCase{
{"secondary info/refs", "/group/project.git/info/refs", "Local Rails server received request to path /group/project.git/info/refs"},
{"primary info/refs", "/-/push_from_secondary/2/group/project.git/info/refs", "Geo primary received request to path /-/push_from_secondary/2/group/project.git/info/refs"},
{"primary receive-pack", "/-/push_from_secondary/2/group/project.git/git-receive-pack", "Geo primary received request to path /-/push_from_secondary/2/group/project.git/git-receive-pack"},
}
runTestCasesWithGeoProxyEnabled(t, testCases)
}
func TestProjectNotExistingGitSSHPullWithGeoProxy(t *testing.T) {
testCases := []testCase{
{"GitLab Shell call to authorized-keys", "/api/v4/internal/authorized_keys", "Local Rails server received request to path /api/v4/internal/authorized_keys"},
{"GitLab Shell call to allowed", "/api/v4/internal/allowed", "Local Rails server received request to path /api/v4/internal/allowed"},
{"GitLab Shell call to info/refs", "/api/v4/geo/proxy_git_ssh/info_refs_receive_pack", "Local Rails server received request to path /api/v4/geo/proxy_git_ssh/info_refs_receive_pack"},
{"GitLab Shell call to receive_pack", "/api/v4/geo/proxy_git_ssh/receive_pack", "Local Rails server received request to path /api/v4/geo/proxy_git_ssh/receive_pack"},
}
runTestCasesWithGeoProxyEnabled(t, testCases)
}
func TestProjectNotExistingGitSSHPushWithGeoProxy(t *testing.T) {
testCases := []testCase{
{"GitLab Shell call to authorized-keys", "/api/v4/internal/authorized_keys", "Local Rails server received request to path /api/v4/internal/authorized_keys"},
{"GitLab Shell call to allowed", "/api/v4/internal/allowed", "Local Rails server received request to path /api/v4/internal/allowed"},
{"GitLab Shell call to info/refs", "/api/v4/geo/proxy_git_ssh/info_refs_upload_pack", "Local Rails server received request to path /api/v4/geo/proxy_git_ssh/info_refs_upload_pack"},
{"GitLab Shell call to receive_pack", "/api/v4/geo/proxy_git_ssh/upload_pack", "Local Rails server received request to path /api/v4/geo/proxy_git_ssh/upload_pack"},
}
runTestCasesWithGeoProxyEnabled(t, testCases)
}

View File

@ -88,16 +88,6 @@ func TestGeoProxyFeatureDisabledOnGeoSecondarySite(t *testing.T) {
}
func TestGeoProxyFeatureEnabledOnGeoSecondarySite(t *testing.T) {
remoteServer, rsDeferredClose := startRemoteServer("Geo primary")
defer rsDeferredClose()
geoProxyEndpointResponseBody := fmt.Sprintf(`{"geo_proxy_url":"%v"}`, remoteServer.URL)
railsServer, deferredClose := startRailsServer("Local Rails server", &geoProxyEndpointResponseBody)
defer deferredClose()
ws, wsDeferredClose, _ := startWorkhorseServer(railsServer.URL, true)
defer wsDeferredClose()
testCases := []testCase{
{"push from secondary is forwarded", "/-/push_from_secondary/foo/bar.git/info/refs", "Geo primary received request to path /-/push_from_secondary/foo/bar.git/info/refs"},
{"LFS files are served locally", "/group/project.git/gitlab-lfs/objects/37446575700829a11278ad3a550f244f45d5ae4fe1552778fa4f041f9eaeecf6", "Local Rails server received request to path /group/project.git/gitlab-lfs/objects/37446575700829a11278ad3a550f244f45d5ae4fe1552778fa4f041f9eaeecf6"},
@ -106,7 +96,7 @@ func TestGeoProxyFeatureEnabledOnGeoSecondarySite(t *testing.T) {
{"unknown route is forwarded", "/anything", "Geo primary received request to path /anything"},
}
runTestCases(t, ws, testCases)
runTestCasesWithGeoProxyEnabled(t, testCases)
}
// This test can be removed when the environment variable `GEO_SECONDARY_PROXY` is removed
@ -227,6 +217,20 @@ func runTestCases(t *testing.T, ws *httptest.Server, testCases []testCase) {
}
}
func runTestCasesWithGeoProxyEnabled(t *testing.T, testCases []testCase) {
remoteServer, rsDeferredClose := startRemoteServer("Geo primary")
defer rsDeferredClose()
geoProxyEndpointResponseBody := fmt.Sprintf(`{"geo_proxy_url":"%v"}`, remoteServer.URL)
railsServer, deferredClose := startRailsServer("Local Rails server", &geoProxyEndpointResponseBody)
defer deferredClose()
ws, wsDeferredClose, _ := startWorkhorseServer(railsServer.URL, true)
defer wsDeferredClose()
runTestCases(t, ws, testCases)
}
func newUpstreamConfig(authBackend string) *config.Config {
return &config.Config{
Version: "123",
@ -284,9 +288,13 @@ func startWorkhorseServer(railsServerURL string, enableGeoProxyFeature bool) (*h
}
cfg := newUpstreamConfig(railsServerURL)
upstreamHandler := newUpstream(*cfg, logrus.StandardLogger(), myConfigureRoutes)
ws := httptest.NewServer(upstreamHandler)
// Secret should be configured before the first Geo API poll happens on server start
// to prevent race conditions where the first API call happens without a secret path
testhelper.ConfigureSecret()
ws := httptest.NewServer(upstreamHandler)
waitForNextApiPoll := func() {}
if enableGeoProxyFeature {

View File

@ -904,20 +904,20 @@
stylelint-declaration-strict-value "1.7.7"
stylelint-scss "3.18.0"
"@gitlab/svgs@1.218.0":
version "1.218.0"
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.218.0.tgz#0715e2ef50b5cb83813e1a5e29d5919a96685734"
integrity sha512-eckixyumeWogykEUZfP4pGjoRdhdWQIFwSTM0ks5tQqza+BikcL2xvxzicJs69T1IiCKwYtEpR1c3T/hSx39Mg==
"@gitlab/svgs@1.219.0":
version "1.219.0"
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.219.0.tgz#82735876b98bd3a46f42b4a424b45086ed48e7ac"
integrity sha512-UOy0+6A6PTbjNHLFBc70ATYztsiQfWHPORgPGnzugYJz2F7ewMr4p6R8d9avFqMNtVB5mIHSnbrsr0pp0XVMGA==
"@gitlab/tributejs@1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@gitlab/tributejs/-/tributejs-1.0.0.tgz#672befa222aeffc83e7d799b0500a7a4418e59b8"
integrity sha512-nmKw1+hB6MHvlmPz63yPwVs1qQkycHwsKgxpEbzmky16Y6mL4EJMk3w1b8QlOAF/AIAzjCERPhe/R4MJiohbZw==
"@gitlab/ui@32.21.0":
version "32.21.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-32.21.0.tgz#d4a5e9b369aa91a9512fb742d1cd5f23f1653a7c"
integrity sha512-ssobbMDscsJa/mWqAne6xOAsNy3pQNOahzn4oLyVmmNPiMRZNcS4mEda28MwexntlkzEkOxWHjmkoa4YI0JQqQ==
"@gitlab/ui@32.28.0":
version "32.28.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-32.28.0.tgz#afa0e1dee66ec438126b2706e0860e2c622fc867"
integrity sha512-DudY+jPIxjGymyB2KgdexmxV+sbjCy3or7LzviiI0jb5jCIiqNoZ4F4G+P0T+Z1FbLBgEXjgUaEZw09edka/lg==
dependencies:
"@babel/standalone" "^7.0.0"
bootstrap-vue "2.20.1"