summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-01-11 18:16:38 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-01-11 18:16:38 +0000
commitb330f7f0bfb2035b03e84e5fa751816b6ad9b841 (patch)
tree5dd72fddc7545c3fb6c5bff6b662bea3dea54d79 /app
parenta8281ac43424e4b820286823bdb48f068b21d7d3 (diff)
downloadgitlab-ce-b330f7f0bfb2035b03e84e5fa751816b6ad9b841.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/behaviors/copy_code.js2
-rw-r--r--app/assets/javascripts/clusters_list/constants.js2
-rw-r--r--app/assets/javascripts/content_editor/components/wrappers/frontmatter.vue2
-rw-r--r--app/assets/javascripts/content_editor/extensions/code_block_highlight.js9
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/app.vue24
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/composer_installation.vue4
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/conan_installation.vue3
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/maven_installation.vue14
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/npm_installation.vue4
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/nuget_installation.vue3
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/package_files.vue6
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/pypi_installation.vue5
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql10
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue50
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/extensions/index.js1
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.js39
-rw-r--r--app/controllers/projects/merge_requests_controller.rb4
-rw-r--r--app/helpers/notes_helper.rb2
-rw-r--r--app/models/project.rb1
-rw-r--r--app/models/project_setting.rb10
-rw-r--r--app/services/auth/container_registry_authentication_service.rb10
-rw-r--r--app/services/projects/destroy_service.rb2
-rw-r--r--app/services/projects/fork_service.rb6
-rw-r--r--app/views/notify/_note_email.html.haml6
-rw-r--r--app/views/notify/repository_push_email.html.haml2
-rw-r--r--app/views/projects/diffs/_email_line.html.haml21
-rw-r--r--app/views/projects/diffs/_line.html.haml2
-rw-r--r--app/views/projects/diffs/_text_file.html.haml36
28 files changed, 192 insertions, 88 deletions
diff --git a/app/assets/javascripts/behaviors/copy_code.js b/app/assets/javascripts/behaviors/copy_code.js
index e4dfdeba209..a8863a18068 100644
--- a/app/assets/javascripts/behaviors/copy_code.js
+++ b/app/assets/javascripts/behaviors/copy_code.js
@@ -29,7 +29,7 @@ class CopyCodeButton extends HTMLElement {
}
function addCodeButton() {
- [...document.querySelectorAll('pre.code.js-syntax-highlight')]
+ [...document.querySelectorAll('pre.code.js-syntax-highlight:not(.content-editor-code-block)')]
.filter((el) => el.attr('lang') !== 'mermaid')
.filter((el) => !el.closest('.js-markdown-code'))
.forEach((el) => {
diff --git a/app/assets/javascripts/clusters_list/constants.js b/app/assets/javascripts/clusters_list/constants.js
index b5729fe4d2d..380a5d0aada 100644
--- a/app/assets/javascripts/clusters_list/constants.js
+++ b/app/assets/javascripts/clusters_list/constants.js
@@ -106,7 +106,7 @@ export const I18N_AGENT_MODAL = {
empty_state: {
modalTitle: s__('ClusterAgents|Connect your cluster through the Agent'),
modalBody: s__(
- "ClusterAgents|To install a new agent, first add the agent's configuration file to this repository. %{linkStart}What's the agent's configuration file?%{linkEnd}",
+ "ClusterAgents|To install a new agent, first add the agent's configuration file to this repository. %{linkStart}Learn more about installing GitLab Agent.%{linkEnd}",
),
enableKasText: s__(
"ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it.",
diff --git a/app/assets/javascripts/content_editor/components/wrappers/frontmatter.vue b/app/assets/javascripts/content_editor/components/wrappers/frontmatter.vue
index 97b69afd12e..e8829d00986 100644
--- a/app/assets/javascripts/content_editor/components/wrappers/frontmatter.vue
+++ b/app/assets/javascripts/content_editor/components/wrappers/frontmatter.vue
@@ -20,7 +20,7 @@ export default {
};
</script>
<template>
- <node-view-wrapper class="gl-relative code highlight" as="pre">
+ <node-view-wrapper class="content-editor-code-block gl-relative code highlight" as="pre">
<span
data-testid="frontmatter-label"
class="gl-absolute gl-top-0 gl-right-3"
diff --git a/app/assets/javascripts/content_editor/extensions/code_block_highlight.js b/app/assets/javascripts/content_editor/extensions/code_block_highlight.js
index ea51bee3ba9..9dc17fcd570 100644
--- a/app/assets/javascripts/content_editor/extensions/code_block_highlight.js
+++ b/app/assets/javascripts/content_editor/extensions/code_block_highlight.js
@@ -19,7 +19,14 @@ export default CodeBlockLowlight.extend({
};
},
renderHTML({ HTMLAttributes }) {
- return ['div', ['pre', HTMLAttributes, ['code', {}, 0]]];
+ return [
+ 'pre',
+ {
+ ...HTMLAttributes,
+ class: `content-editor-code-block ${HTMLAttributes.class}`,
+ },
+ ['code', {}, 0],
+ ];
},
}).configure({
lowlight,
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/app.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/app.vue
index 7dd090a7b47..52fea4bebbe 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/app.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/app.vue
@@ -68,15 +68,7 @@ export default {
GlModal: GlModalDirective,
},
mixins: [Tracking.mixin()],
- inject: [
- 'packageId',
- 'projectName',
- 'canDelete',
- 'svgPath',
- 'npmPath',
- 'projectListUrl',
- 'groupListUrl',
- ],
+ inject: ['packageId', 'svgPath', 'projectListUrl', 'groupListUrl'],
trackingActions: {
DELETE_PACKAGE_TRACKING_ACTION,
REQUEST_DELETE_PACKAGE_TRACKING_ACTION,
@@ -99,7 +91,7 @@ export default {
return this.queryVariables;
},
update(data) {
- return data.package;
+ return data.package || {};
},
error(error) {
createFlash({
@@ -111,19 +103,22 @@ export default {
},
},
computed: {
+ projectName() {
+ return this.packageEntity.project?.name;
+ },
queryVariables() {
return {
id: convertToGraphQLId('Packages::Package', this.packageId),
};
},
packageFiles() {
- return this.packageEntity?.packageFiles?.nodes;
+ return this.packageEntity.packageFiles?.nodes;
},
isLoading() {
return this.$apollo.queries.packageEntity.loading;
},
isValidPackage() {
- return this.isLoading || Boolean(this.packageEntity?.name);
+ return this.isLoading || Boolean(this.packageEntity.name);
},
tracking() {
return {
@@ -140,7 +135,7 @@ export default {
return this.packageEntity.packageType === PACKAGE_TYPE_NUGET;
},
showFiles() {
- return this.packageEntity?.packageType !== PACKAGE_TYPE_COMPOSER;
+ return this.packageEntity.packageType !== PACKAGE_TYPE_COMPOSER;
},
},
methods: {
@@ -240,7 +235,7 @@ export default {
<package-title :package-entity="packageEntity">
<template #delete-button>
<gl-button
- v-if="canDelete"
+ v-if="packageEntity.canDestroy"
v-gl-modal="'delete-modal'"
variant="danger"
category="primary"
@@ -264,6 +259,7 @@ export default {
<package-files
v-if="showFiles"
+ :can-delete="packageEntity.canDestroy"
:package-files="packageFiles"
@download-file="track($options.trackingActions.PULL_PACKAGE)"
@delete-file="handleFileDelete"
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/composer_installation.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/composer_installation.vue
index 4ef37a3cbbe..a482c29bf50 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/composer_installation.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/composer_installation.vue
@@ -18,7 +18,7 @@ export default {
GlLink,
GlSprintf,
},
- inject: ['composerConfigRepositoryName', 'composerPath', 'groupListUrl'],
+ inject: ['groupListUrl'],
props: {
packageEntity: {
type: Object,
@@ -28,7 +28,7 @@ export default {
computed: {
composerRegistryInclude() {
// eslint-disable-next-line @gitlab/require-i18n-strings
- return `composer config repositories.${this.composerConfigRepositoryName} '{"type": "composer", "url": "${this.composerPath}"}'`;
+ return `composer config repositories.${this.packageEntity.composerConfigRepositoryUrl} '{"type": "composer", "url": "${this.packageEntity.composerUrl}"}'`;
},
composerPackageInclude() {
// eslint-disable-next-line @gitlab/require-i18n-strings
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/conan_installation.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/conan_installation.vue
index 72e6a26e15f..ba0a3fcf5a1 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/conan_installation.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/conan_installation.vue
@@ -18,7 +18,6 @@ export default {
GlLink,
GlSprintf,
},
- inject: ['conanPath'],
props: {
packageEntity: {
type: Object,
@@ -32,7 +31,7 @@ export default {
},
conanSetupCommand() {
// eslint-disable-next-line @gitlab/require-i18n-strings
- return `conan remote add gitlab ${this.conanPath}`;
+ return `conan remote add gitlab ${this.packageEntity.conanUrl}`;
},
},
i18n: {
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/maven_installation.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/maven_installation.vue
index 9757838ccfb..4510c7a7322 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/maven_installation.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/maven_installation.vue
@@ -24,7 +24,6 @@ export default {
GlLink,
GlSprintf,
},
- inject: ['mavenPath'],
props: {
packageEntity: {
type: Object,
@@ -37,6 +36,9 @@ export default {
};
},
computed: {
+ mavenUrl() {
+ return this.packageEntity.mavenUrl;
+ },
appGroup() {
return this.packageEntity.metadata.appGroup;
},
@@ -62,19 +64,19 @@ export default {
return `<repositories>
<repository>
<id>gitlab-maven</id>
- <url>${this.mavenPath}</url>
+ <url>${this.mavenUrl}</url>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>gitlab-maven</id>
- <url>${this.mavenPath}</url>
+ <url>${this.mavenUrl}</url>
</repository>
<snapshotRepository>
<id>gitlab-maven</id>
- <url>${this.mavenPath}</url>
+ <url>${this.mavenUrl}</url>
</snapshotRepository>
</distributionManagement>`;
},
@@ -87,7 +89,7 @@ export default {
gradleGroovyAddSourceCommand() {
// eslint-disable-next-line @gitlab/require-i18n-strings
return `maven {
- url '${this.mavenPath}'
+ url '${this.mavenUrl}'
}`;
},
@@ -96,7 +98,7 @@ export default {
},
gradleKotlinAddSourceCommand() {
- return `maven("${this.mavenPath}")`;
+ return `maven("${this.mavenUrl}")`;
},
showMaven() {
return this.instructionType === 'maven';
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/npm_installation.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/npm_installation.vue
index 7af9a2ade56..95b09b25678 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/npm_installation.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/npm_installation.vue
@@ -26,7 +26,7 @@ export default {
GlSprintf,
GlFormRadioGroup,
},
- inject: ['npmPath', 'npmProjectPath'],
+ inject: ['npmPath'],
props: {
packageEntity: {
type: Object,
@@ -66,7 +66,7 @@ export default {
npmSetupCommand(type, endpointType) {
const scope = this.packageEntity.name.substring(0, this.packageEntity.name.indexOf('/'));
const npmPathForEndpoint =
- endpointType === INSTANCE_PACKAGE_ENDPOINT_TYPE ? this.npmPath : this.npmProjectPath;
+ endpointType === INSTANCE_PACKAGE_ENDPOINT_TYPE ? this.npmPath : this.packageEntity.npmUrl;
if (type === NPM_PACKAGE_MANAGER) {
return `echo ${scope}:registry=${npmPathForEndpoint}/ >> .npmrc`;
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/nuget_installation.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/nuget_installation.vue
index ca48da70bb4..b2007df142c 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/nuget_installation.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/nuget_installation.vue
@@ -18,7 +18,6 @@ export default {
GlLink,
GlSprintf,
},
- inject: ['nugetPath'],
props: {
packageEntity: {
type: Object,
@@ -30,7 +29,7 @@ export default {
return `nuget install ${this.packageEntity.name} -Source "GitLab"`;
},
nugetSetupCommand() {
- return `nuget source Add -Name "GitLab" -Source "${this.nugetPath}" -UserName <your_username> -Password <your_token>`;
+ return `nuget source Add -Name "GitLab" -Source "${this.packageEntity.nugetUrl}" -UserName <your_username> -Password <your_token>`;
},
},
tracking: {
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_files.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_files.vue
index bf7fe6fb91b..3724e371e01 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_files.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_files.vue
@@ -22,8 +22,12 @@ export default {
FileSha,
},
mixins: [Tracking.mixin()],
- inject: ['canDelete'],
props: {
+ canDelete: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
packageFiles: {
type: Array,
required: false,
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/pypi_installation.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/pypi_installation.vue
index 1c4ef21a2cf..a126d30f1ec 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/pypi_installation.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/pypi_installation.vue
@@ -19,7 +19,6 @@ export default {
GlLink,
GlSprintf,
},
- inject: ['pypiPath', 'pypiSetupPath'],
props: {
packageEntity: {
type: Object,
@@ -29,11 +28,11 @@ export default {
computed: {
pypiPipCommand() {
// eslint-disable-next-line @gitlab/require-i18n-strings
- return `pip install ${this.packageEntity.name} --extra-index-url ${this.pypiPath}`;
+ return `pip install ${this.packageEntity.name} --extra-index-url ${this.packageEntity.pypiUrl}`;
},
pypiSetupCommand() {
return `[gitlab]
-repository = ${this.pypiSetupPath}
+repository = ${this.packageEntity.pypiSetupUrl}
username = __token__
password = <your personal access token>`;
},
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql b/app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql
index 08ea0938a59..c45cbe56e00 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql
+++ b/app/assets/javascripts/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql
@@ -7,9 +7,19 @@ query getPackageDetails($id: ID!) {
createdAt
updatedAt
status
+ canDestroy
+ npmUrl
+ mavenUrl
+ conanUrl
+ nugetUrl
+ pypiUrl
+ pypiSetupUrl
+ composerUrl
+ composerConfigRepositoryUrl
project {
id
path
+ name
}
tags(first: 10) {
nodes {
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue b/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
index 549cf64fb08..7322958e6df 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
@@ -13,6 +13,7 @@ import * as Sentry from '@sentry/browser';
import api from '~/api';
import { sprintf, s__, __ } from '~/locale';
import SmartVirtualList from '~/vue_shared/components/smart_virtual_list.vue';
+import Poll from '~/lib/utils/poll';
import { EXTENSION_ICON_CLASS, EXTENSION_ICONS } from '../../constants';
import StatusIcon from './status_icon.vue';
import Actions from './actions.vue';
@@ -132,19 +133,50 @@ export default {
this.triggerRedisTracking();
},
+ initExtensionPolling() {
+ const poll = new Poll({
+ resource: {
+ fetchData: () => this.fetchCollapsedData(this.$props),
+ },
+ method: 'fetchData',
+ successCallback: (data) => {
+ if (Object.keys(data).length > 0) {
+ poll.stop();
+ this.setCollapsedData(data);
+ }
+ },
+ errorCallback: (e) => {
+ poll.stop();
+
+ this.setCollapsedError(e);
+ },
+ });
+
+ poll.makeRequest();
+ },
loadCollapsedData() {
this.loadingState = LOADING_STATES.collapsedLoading;
- this.fetchCollapsedData(this.$props)
- .then((data) => {
- this.collapsedData = data;
- this.loadingState = null;
- })
- .catch((e) => {
- this.loadingState = LOADING_STATES.collapsedError;
+ if (this.$options.enablePolling) {
+ this.initExtensionPolling();
+ } else {
+ this.fetchCollapsedData(this.$props)
+ .then((data) => {
+ this.setCollapsedData(data);
+ })
+ .catch((e) => {
+ this.setCollapsedError(e);
+ });
+ }
+ },
+ setCollapsedData(data) {
+ this.collapsedData = data;
+ this.loadingState = null;
+ },
+ setCollapsedError(e) {
+ this.loadingState = LOADING_STATES.collapsedError;
- Sentry.captureException(e);
- });
+ Sentry.captureException(e);
},
loadAllData() {
if (this.hasFullData) return;
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/index.js b/app/assets/javascripts/vue_merge_request_widget/components/extensions/index.js
index ec6e6ed2620..8438f3492b2 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/extensions/index.js
+++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/index.js
@@ -13,6 +13,7 @@ export const registerExtension = (extension) => {
props: extension.props,
i18n: extension.i18n,
expandEvent: extension.expandEvent,
+ enablePolling: extension.enablePolling,
computed: {
...Object.keys(extension.computed).reduce(
(acc, computedKey) => ({
diff --git a/app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.js b/app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.js
index d9868101e9d..a564acada02 100644
--- a/app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.js
+++ b/app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.js
@@ -1,10 +1,10 @@
import { __, n__, s__, sprintf } from '~/locale';
import axios from '~/lib/utils/axios_utils';
-import Poll from '~/lib/utils/poll';
import { EXTENSION_ICONS } from '../../constants';
export default {
name: 'WidgetTerraform',
+ enablePolling: true,
i18n: {
label: s__('Terraform|Terraform reports'),
loading: s__('Terraform|Loading Terraform reports...'),
@@ -81,34 +81,17 @@ export default {
},
// Custom methods
fetchPlans() {
- return new Promise((resolve) => {
- const poll = new Poll({
- resource: {
- fetchPlans: () => axios.get(this.terraformReportsPath),
- },
- data: this.terraformReportsPath,
- method: 'fetchPlans',
- successCallback: ({ data }) => {
- if (Object.keys(data).length > 0) {
- poll.stop();
-
- const result = Object.keys(data).map((key) => {
- return data[key];
- });
-
- resolve(result);
- }
- },
- errorCallback: () => {
- const invalidData = { tf_report_error: 'api_error' };
- poll.stop();
- const result = [invalidData];
- resolve(result);
- },
+ return axios
+ .get(this.terraformReportsPath)
+ .then(({ data }) => {
+ return Object.keys(data).map((key) => {
+ return data[key];
+ });
+ })
+ .catch(() => {
+ const invalidData = { tf_report_error: 'api_error' };
+ return [invalidData];
});
-
- poll.makeRequest();
- });
},
createReportRow(report, iconName) {
const addNum = Number(report.create);
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 0b1516f6f45..fb9d1a85656 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -49,10 +49,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:diff_searching_usage_data, @project, default_enabled: :yaml)
end
- before_action do
- push_frontend_feature_flag(:show_relevant_approval_rule_approvers, @project, default_enabled: :yaml)
- end
-
around_action :allow_gitaly_ref_name_caching, only: [:index, :show, :discussions]
after_action :log_merge_request_show, only: [:show]
diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb
index 2dadaa0be0a..1afdb7a0ab9 100644
--- a/app/helpers/notes_helper.rb
+++ b/app/helpers/notes_helper.rb
@@ -48,7 +48,7 @@ module NotesHelper
data[:note_type] = LegacyDiffNote.name
else
data[:note_type] = DiffNote.name
- data[:position] = position.to_json
+ data[:position] = Gitlab::Json.dump(position)
end
data
diff --git a/app/models/project.rb b/app/models/project.rb
index 5c4ffd08304..fa5e84ee83e 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -436,6 +436,7 @@ class Project < ApplicationRecord
prefix: :import, to: :import_state, allow_nil: true
delegate :squash_always?, :squash_never?, :squash_enabled_by_default?, :squash_readonly?, to: :project_setting
delegate :squash_option, :squash_option=, to: :project_setting
+ delegate :mr_default_target_self, :mr_default_target_self=, to: :project_setting
delegate :previous_default_branch, :previous_default_branch=, to: :project_setting
delegate :no_import?, to: :import_state, allow_nil: true
delegate :name, to: :owner, allow_nil: true, prefix: true
diff --git a/app/models/project_setting.rb b/app/models/project_setting.rb
index fc834286876..4e37174e604 100644
--- a/app/models/project_setting.rb
+++ b/app/models/project_setting.rb
@@ -22,6 +22,16 @@ class ProjectSetting < ApplicationRecord
def squash_readonly?
%w[always never].include?(squash_option)
end
+
+ validate :validates_mr_default_target_self
+
+ private
+
+ def validates_mr_default_target_self
+ if mr_default_target_self_changed? && !project.forked?
+ errors.add :mr_default_target_self, _('This setting is allowed for forked projects only')
+ end
+ end
end
ProjectSetting.prepend_mod
diff --git a/app/services/auth/container_registry_authentication_service.rb b/app/services/auth/container_registry_authentication_service.rb
index 1d5acff162e..a92a2c8aef5 100644
--- a/app/services/auth/container_registry_authentication_service.rb
+++ b/app/services/auth/container_registry_authentication_service.rb
@@ -124,7 +124,8 @@ module Auth
type: type,
name: path.to_s,
actions: authorized_actions,
- migration_eligible: self.class.migration_eligible(project: requested_project)
+ migration_eligible: self.class.migration_eligible(project: requested_project),
+ cdn_redirect: cdn_redirect
}.compact
end
@@ -150,6 +151,13 @@ module Auth
false
end
+ # This is used to determine whether blob download requests using a given JWT token should be redirected to Google
+ # Cloud CDN or not. The intent is to enable a percentage of time rollout for this new feature on the Container
+ # Registry side. See https://gitlab.com/gitlab-org/gitlab/-/issues/349417 for more details.
+ def cdn_redirect
+ Feature.enabled?(:container_registry_cdn_redirect) || nil
+ end
+
##
# Because we do not have two way communication with registry yet,
# we create a container repository image resource when push to the
diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb
index 936c2da1e71..5c4a0e947de 100644
--- a/app/services/projects/destroy_service.rb
+++ b/app/services/projects/destroy_service.rb
@@ -41,6 +41,8 @@ module Projects
true
rescue StandardError => error
+ context = Gitlab::ApplicationContext.current.merge(project_id: project.id)
+ Gitlab::ErrorTracking.track_exception(error, **context)
attempt_rollback(project, error.message)
false
rescue Exception => error # rubocop:disable Lint/RescueException
diff --git a/app/services/projects/fork_service.rb b/app/services/projects/fork_service.rb
index 74b7d18f401..3e8d6563709 100644
--- a/app/services/projects/fork_service.rb
+++ b/app/services/projects/fork_service.rb
@@ -69,6 +69,8 @@ module Projects
new_params[:avatar] = @project.avatar
end
+ new_params[:mr_default_target_self] = target_mr_default_target_self unless target_mr_default_target_self.nil?
+
new_params.merge!(@project.object_pool_params)
new_params
@@ -127,5 +129,9 @@ module Projects
Gitlab::VisibilityLevel.closest_allowed_level(target_level)
end
+
+ def target_mr_default_target_self
+ @target_mr_default_target_self ||= params[:mr_default_target_self]
+ end
end
end
diff --git a/app/views/notify/_note_email.html.haml b/app/views/notify/_note_email.html.haml
index ae9c8554e73..ad0c873bf56 100644
--- a/app/views/notify/_note_email.html.haml
+++ b/app/views/notify/_note_email.html.haml
@@ -26,12 +26,10 @@
= stylesheet_link_tag 'mailers/highlighted_diff_email'
%table
- = render partial: "projects/diffs/line",
+ = render partial: "projects/diffs/email_line",
collection: discussion.truncated_diff_lines(diff_limit: diff_limit),
as: :line,
- locals: { diff_file: discussion.diff_file,
- plain: true,
- email: true }
+ locals: { diff_file: discussion.diff_file }
%div{ style: note_style }
= markdown(note.note, pipeline: :email, author: note.author, current_user: @recipient, issuable_reference_expansion_enabled: true)
diff --git a/app/views/notify/repository_push_email.html.haml b/app/views/notify/repository_push_email.html.haml
index 5c5520f4cb8..93806e6de8e 100644
--- a/app/views/notify/repository_push_email.html.haml
+++ b/app/views/notify/repository_push_email.html.haml
@@ -74,7 +74,7 @@
- blob = diff_file.blob
- if blob && blob.readable_text?
%table.code.white
- = render partial: "projects/diffs/line", collection: diff_file.highlighted_diff_lines, as: :line, locals: { diff_file: diff_file, plain: true, email: true }
+ = render partial: "projects/diffs/email_line", collection: diff_file.highlighted_diff_lines, as: :line, locals: { diff_file: diff_file }
- else
No preview for this file type
%br
diff --git a/app/views/projects/diffs/_email_line.html.haml b/app/views/projects/diffs/_email_line.html.haml
new file mode 100644
index 00000000000..dfff143196c
--- /dev/null
+++ b/app/views/projects/diffs/_email_line.html.haml
@@ -0,0 +1,21 @@
+-# This template is used when rendering diffs in email notifications
+-# Called inside: app/views/notify/repository_push_email.html.haml
+-# app/views/notify/_note_email.html.haml
+
+%tr.line_holder{ class: line.type }
+ - case line.type
+ - when 'match'
+ = diff_match_line line.old_pos, line.new_pos, text: line.text
+ - when 'old-nonewline', 'new-nonewline'
+ %td.old_line.diff-line-num
+ %td.new_line.diff-line-num
+ %td.line_content.match= line.text
+ - else
+ %td.old_line.diff-line-num{ class: line.type, data: { linenumber: line.old_pos } }
+ = diff_link_number(line.type, "new", line.old_pos)
+
+ %td.new_line.diff-line-num{ class: line.type, data: { linenumber: line.new_pos } }
+ = diff_link_number(line.type, "old", line.new_pos)
+
+ %td.line_content{ class: line.type }<
+ %pre= line.rich_text
diff --git a/app/views/projects/diffs/_line.html.haml b/app/views/projects/diffs/_line.html.haml
index de7f9eba158..330e2f564c9 100644
--- a/app/views/projects/diffs/_line.html.haml
+++ b/app/views/projects/diffs/_line.html.haml
@@ -1,3 +1,5 @@
+-# This file is deprecated in favour of inline rendering:
+-# https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57237
- plain = local_assigns.fetch(:plain, false)
- discussions = local_assigns.fetch(:discussions, nil)
- line_code = diff_file.line_code(line)
diff --git a/app/views/projects/diffs/_text_file.html.haml b/app/views/projects/diffs/_text_file.html.haml
index bf946b0ce73..6e7e0244721 100644
--- a/app/views/projects/diffs/_text_file.html.haml
+++ b/app/views/projects/diffs/_text_file.html.haml
@@ -4,10 +4,38 @@
%a.show-suppressed-diff.cursor-pointer.js-show-suppressed-diff= _("Changes suppressed. Click to show.")
%table.text-file.diff-wrap-lines.code.code-commit.js-syntax-highlight.commit-diff{ data: diff_view_data, class: too_big ? 'hide' : '' }
- = render partial: "projects/diffs/line",
- collection: diff_file.highlighted_diff_lines,
- as: :line,
- locals: { diff_file: diff_file, discussions: @grouped_diff_discussions }
+ - if Feature.enabled?(:inline_haml_diff_line_rendering, @project, default_enabled: :yaml)
+ - diff_file.highlighted_diff_lines.each do |line|
+ - line_code = diff_file.line_code(line)
+
+ %tr.line_holder{ class: line.type, id: line_code }
+ - case line.type
+ - when 'match'
+ = diff_match_line line.old_pos, line.new_pos, text: line.text
+ - when 'old-nonewline', 'new-nonewline'
+ %td.old_line.diff-line-num
+ %td.new_line.diff-line-num
+ %td.line_content.match= line.text
+ - else
+ %td.old_line.diff-line-num{ class: "#{line.type} js-avatar-container", data: { linenumber: line.old_pos } }
+ = add_diff_note_button(line_code, diff_file.position(line), line.type)
+ %a{ href: "##{line_code}", data: { linenumber: diff_link_number(line.type, "new", line.old_pos) } }
+
+ %td.new_line.diff-line-num{ class: line.type, data: { linenumber: line.new_pos } }
+ %a{ href: "##{line_code}", data: { linenumber: diff_link_number(line.type, "old", line.new_pos) } }
+
+ %td.line_content{ class: line.type }<
+ = diff_line_content(line.rich_text)
+
+ - if line.discussable? && @grouped_diff_discussions.present? && @grouped_diff_discussions[line_code]
+ - line_discussions = @grouped_diff_discussions[line_code]
+ = render "discussions/diff_discussion", discussions: line_discussions, expanded: line_discussions.any?(&:expanded?)
+
+ - else
+ = render partial: "projects/diffs/line",
+ collection: diff_file.highlighted_diff_lines,
+ as: :line,
+ locals: { diff_file: diff_file, discussions: @grouped_diff_discussions }
- if !diff_file.new_file? && !diff_file.deleted_file? && diff_file.highlighted_diff_lines.any?
- last_line = diff_file.highlighted_diff_lines.last