Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-03-15 12:07:33 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-03-15 12:07:33 +0300
commit389d5aa505a916b0506b7b73dcc3be342d724976 (patch)
treed53490630b9aac2eb397d9816db91030afad832a /app
parentf632ee795fd542d7ae2753d157725bd39d33e32d (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue6
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipelines_filtered_search.vue6
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_branch_name_token.vue7
-rw-r--r--app/assets/javascripts/pipelines/pipelines_index.js2
-rw-r--r--app/assets/javascripts/reports/constants.js1
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/extensions/test_report/constants.js39
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/extensions/test_report/index.js82
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/extensions/test_report/utils.js55
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue16
-rw-r--r--app/controllers/projects/ci/secure_files_controller.rb8
-rw-r--r--app/helpers/ci/pipelines_helper.rb1
-rw-r--r--app/policies/project_policy.rb2
-rw-r--r--app/services/ci/destroy_secure_file_service.rb11
-rw-r--r--app/services/projects/destroy_service.rb4
15 files changed, 43 insertions, 199 deletions
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue
index 5a94d144031..db9dc74863d 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue
@@ -98,6 +98,11 @@ export default {
type: String,
required: true,
},
+ defaultBranchName: {
+ type: String,
+ required: false,
+ default: null,
+ },
params: {
type: Object,
required: true,
@@ -347,6 +352,7 @@ export default {
<pipelines-filtered-search
class="gl-display-flex gl-flex-grow-1 gl-mr-4"
:project-id="projectId"
+ :default-branch-name="defaultBranchName"
:params="validatedParams"
@filterPipelines="filterPipelines"
/>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_filtered_search.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_filtered_search.vue
index 2dfdaa0ea28..4d28545a035 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_filtered_search.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_filtered_search.vue
@@ -24,6 +24,11 @@ export default {
type: String,
required: true,
},
+ defaultBranchName: {
+ type: String,
+ required: false,
+ default: null,
+ },
params: {
type: Object,
required: true,
@@ -57,6 +62,7 @@ export default {
token: PipelineBranchNameToken,
operators: OPERATOR_IS_ONLY,
projectId: this.projectId,
+ defaultBranchName: this.defaultBranchName,
disabled: this.selectedTypes.includes(this.$options.tagType),
},
{
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_branch_name_token.vue b/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_branch_name_token.vue
index 5409e68cdc4..1db2898b72a 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_branch_name_token.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_branch_name_token.vue
@@ -35,6 +35,13 @@ export default {
Api.branches(this.config.projectId, searchterm)
.then(({ data }) => {
this.branches = data.map((branch) => branch.name);
+ if (!searchterm && this.config.defaultBranchName) {
+ // Shift the default branch to the top of the list
+ this.branches = this.branches.filter(
+ (branch) => branch !== this.config.defaultBranchName,
+ );
+ this.branches.unshift(this.config.defaultBranchName);
+ }
this.loading = false;
})
.catch((err) => {
diff --git a/app/assets/javascripts/pipelines/pipelines_index.js b/app/assets/javascripts/pipelines/pipelines_index.js
index 2b1f5419953..f4d9a44a754 100644
--- a/app/assets/javascripts/pipelines/pipelines_index.js
+++ b/app/assets/javascripts/pipelines/pipelines_index.js
@@ -36,6 +36,7 @@ export const initPipelinesIndex = (selector = '#pipelines-list-vue') => {
ciLintPath,
resetCachePath,
projectId,
+ defaultBranchName,
params,
ciRunnerSettingsPath,
anyRunnersAvailable,
@@ -75,6 +76,7 @@ export const initPipelinesIndex = (selector = '#pipelines-list-vue') => {
ciLintPath,
resetCachePath,
projectId,
+ defaultBranchName,
params: JSON.parse(params),
ciRunnerSettingsPath,
anyRunnersAvailable: parseBoolean(anyRunnersAvailable),
diff --git a/app/assets/javascripts/reports/constants.js b/app/assets/javascripts/reports/constants.js
index 53273aeff33..bad6fa1e7b9 100644
--- a/app/assets/javascripts/reports/constants.js
+++ b/app/assets/javascripts/reports/constants.js
@@ -18,6 +18,7 @@ export const ICON_WARNING = 'warning';
export const ICON_SUCCESS = 'success';
export const ICON_NOTFOUND = 'notfound';
export const ICON_PENDING = 'pending';
+export const ICON_FAILED = 'failed';
export const status = {
LOADING,
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 e5a6514624d..684386883c8 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
@@ -86,7 +86,7 @@ export default {
);
},
statusIconName() {
- if (this.hasFetchError) return EXTENSION_ICONS.failed;
+ if (this.hasFetchError) return EXTENSION_ICONS.error;
if (this.isLoadingSummary) return null;
return this.statusIcon(this.collapsedData);
diff --git a/app/assets/javascripts/vue_merge_request_widget/extensions/test_report/constants.js b/app/assets/javascripts/vue_merge_request_widget/extensions/test_report/constants.js
deleted file mode 100644
index cd5cfb6837c..00000000000
--- a/app/assets/javascripts/vue_merge_request_widget/extensions/test_report/constants.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import { __, n__, s__, sprintf } from '~/locale';
-
-const digitText = (bold = false) => (bold ? '%{strong_start}%d%{strong_end}' : '%d');
-const noText = (bold = false) => (bold ? '%{strong_start}no%{strong_end}' : 'no');
-
-export const TESTS_FAILED_STATUS = 'failed';
-export const ERROR_STATUS = 'error';
-
-export const i18n = {
- label: s__('Reports|Test summary'),
- loading: s__('Reports|Test summary results are loading'),
- error: s__('Reports|Test summary failed to load results'),
- fullReport: s__('Reports|Full report'),
-
- noChanges: (bold) => s__(`Reports|${noText(bold)} changed test results`),
- resultsString: (combinedString, resolvedString) =>
- sprintf(s__('Reports|%{combinedString} and %{resolvedString}'), {
- combinedString,
- resolvedString,
- }),
-
- summaryText: (name, resultsString) =>
- sprintf(__('%{name}: %{resultsString}'), { name, resultsString }),
-
- failedClause: (failed, bold) =>
- n__(`${digitText(bold)} failed`, `${digitText(bold)} failed`, failed),
- erroredClause: (errored, bold) =>
- n__(`${digitText(bold)} error`, `${digitText(bold)} errors`, errored),
- resolvedClause: (resolved, bold) =>
- n__(`${digitText(bold)} fixed test result`, `${digitText(bold)} fixed test results`, resolved),
- totalClause: (total, bold) =>
- n__(`${digitText(bold)} total test`, `${digitText(bold)} total tests`, total),
-
- reportError: s__('Reports|An error occurred while loading report'),
- reportErrorWithName: (name) =>
- sprintf(s__('Reports|An error occurred while loading %{name} results'), { name }),
- headReportParsingError: s__('Reports|Head report parsing error:'),
- baseReportParsingError: s__('Reports|Base report parsing error:'),
-};
diff --git a/app/assets/javascripts/vue_merge_request_widget/extensions/test_report/index.js b/app/assets/javascripts/vue_merge_request_widget/extensions/test_report/index.js
deleted file mode 100644
index 65d9257903f..00000000000
--- a/app/assets/javascripts/vue_merge_request_widget/extensions/test_report/index.js
+++ /dev/null
@@ -1,82 +0,0 @@
-import { uniqueId } from 'lodash';
-import axios from '~/lib/utils/axios_utils';
-import { EXTENSION_ICONS } from '../../constants';
-import { summaryTextBuilder, reportTextBuilder, reportSubTextBuilder } from './utils';
-import { i18n, TESTS_FAILED_STATUS, ERROR_STATUS } from './constants';
-
-export default {
- name: 'WidgetTestSummary',
- enablePolling: true,
- i18n,
- expandEvent: 'i_testing_summary_widget_total',
- props: ['testResultsPath', 'headBlobPath', 'pipeline'],
- computed: {
- summary(data) {
- if (data.parsingInProgress) {
- return this.$options.i18n.loading;
- }
- if (data.hasSuiteError) {
- return this.$options.i18n.error;
- }
- return summaryTextBuilder(this.$options.i18n.label, data.summary);
- },
- statusIcon(data) {
- if (data.parsingInProgress) {
- return null;
- }
- if (data.status === TESTS_FAILED_STATUS) {
- return EXTENSION_ICONS.warning;
- }
- if (data.hasSuiteError) {
- return EXTENSION_ICONS.failed;
- }
- return EXTENSION_ICONS.success;
- },
- tertiaryButtons() {
- return [
- {
- text: this.$options.i18n.fullReport,
- href: `${this.pipeline.path}/test_report`,
- target: '_blank',
- },
- ];
- },
- },
- methods: {
- fetchCollapsedData() {
- return axios.get(this.testResultsPath).then(({ data = {}, status }) => {
- return {
- data: {
- hasSuiteError: data.suites?.some((suite) => suite.status === ERROR_STATUS),
- parsingInProgress: status === 204,
- ...data,
- },
- };
- });
- },
- fetchFullData() {
- return Promise.resolve(this.prepareReports());
- },
- suiteIcon(suite) {
- if (suite.status === ERROR_STATUS) {
- return EXTENSION_ICONS.error;
- }
- if (suite.status === TESTS_FAILED_STATUS) {
- return EXTENSION_ICONS.failed;
- }
- return EXTENSION_ICONS.success;
- },
- prepareReports() {
- return this.collapsedData.suites.map((suite) => {
- return {
- id: uniqueId('suite-'),
- text: reportTextBuilder(suite),
- subtext: reportSubTextBuilder(suite),
- icon: {
- name: this.suiteIcon(suite),
- },
- };
- });
- },
- },
-};
diff --git a/app/assets/javascripts/vue_merge_request_widget/extensions/test_report/utils.js b/app/assets/javascripts/vue_merge_request_widget/extensions/test_report/utils.js
deleted file mode 100644
index a74ed20362f..00000000000
--- a/app/assets/javascripts/vue_merge_request_widget/extensions/test_report/utils.js
+++ /dev/null
@@ -1,55 +0,0 @@
-import { i18n } from './constants';
-
-const textBuilder = (results, boldNumbers = false) => {
- const { failed, errored, resolved, total } = results;
-
- const failedOrErrored = (failed || 0) + (errored || 0);
- const failedString = failed ? i18n.failedClause(failed, boldNumbers) : null;
- const erroredString = errored ? i18n.erroredClause(errored, boldNumbers) : null;
- const combinedString =
- failed && errored ? `${failedString}, ${erroredString}` : failedString || erroredString;
- const resolvedString = resolved ? i18n.resolvedClause(resolved, boldNumbers) : null;
- const totalString = total ? i18n.totalClause(total, boldNumbers) : null;
-
- let resultsString = i18n.noChanges(boldNumbers);
-
- if (failedOrErrored) {
- if (resolved) {
- resultsString = i18n.resultsString(combinedString, resolvedString);
- } else {
- resultsString = combinedString;
- }
- } else if (resolved) {
- resultsString = resolvedString;
- }
-
- return `${resultsString}, ${totalString}`;
-};
-
-export const summaryTextBuilder = (name = '', results = {}) => {
- const resultsString = textBuilder(results, true);
- return i18n.summaryText(name, resultsString);
-};
-
-export const reportTextBuilder = ({ name = '', summary = {}, status }) => {
- if (!name) {
- return i18n.reportError;
- }
- if (status === 'error') {
- return i18n.reportErrorWithName(name);
- }
-
- const resultsString = textBuilder(summary);
- return i18n.summaryText(name, resultsString);
-};
-
-export const reportSubTextBuilder = ({ suite_errors }) => {
- const errors = [];
- if (suite_errors?.head) {
- errors.push(`${i18n.headReportParsingError} ${suite_errors.head}`);
- }
- if (suite_errors?.base) {
- errors.push(`${i18n.baseReportParsingError} ${suite_errors.base}`);
- }
- return errors.join('<br />');
-};
diff --git a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
index bb25fa15626..cd4d9398899 100644
--- a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
@@ -46,7 +46,6 @@ import mergeRequestQueryVariablesMixin from './mixins/merge_request_query_variab
import getStateQuery from './queries/get_state.query.graphql';
import terraformExtension from './extensions/terraform';
import accessibilityExtension from './extensions/accessibility';
-import testReportExtension from './extensions/test_report';
export default {
// False positive i18n lint: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/25
@@ -191,9 +190,6 @@ export default {
shouldRenderTerraformPlans() {
return Boolean(this.mr?.terraformReportsPath);
},
- shouldRenderTestReport() {
- return Boolean(this.mr?.testResultsPath);
- },
mergeError() {
let { mergeError } = this.mr;
@@ -250,11 +246,6 @@ export default {
this.registerAccessibilityExtension();
}
},
- shouldRenderTestReport(newVal) {
- if (newVal) {
- this.registerTestReportExtension();
- }
- },
},
mounted() {
MRWidgetService.fetchInitialData()
@@ -500,11 +491,6 @@ export default {
registerExtension(accessibilityExtension);
}
},
- registerTestReportExtension() {
- if (this.shouldRenderTestReport && this.shouldShowExtension) {
- registerExtension(testReportExtension);
- }
- },
},
};
</script>
@@ -577,7 +563,7 @@ export default {
/>
<grouped-test-reports-app
- v-if="mr.testResultsPath && !shouldShowExtension"
+ v-if="mr.testResultsPath"
class="js-reports-container"
:endpoint="mr.testResultsPath"
:head-blob-path="mr.headBlobPath"
diff --git a/app/controllers/projects/ci/secure_files_controller.rb b/app/controllers/projects/ci/secure_files_controller.rb
index 4b6a6b19454..5141d0188b0 100644
--- a/app/controllers/projects/ci/secure_files_controller.rb
+++ b/app/controllers/projects/ci/secure_files_controller.rb
@@ -1,16 +1,10 @@
# frozen_string_literal: true
class Projects::Ci::SecureFilesController < Projects::ApplicationController
- before_action :check_can_collaborate!
+ before_action :authorize_read_secure_files!
feature_category :pipeline_authoring
def show
end
-
- private
-
- def check_can_collaborate!
- render_404 unless can_collaborate_with_project?(project)
- end
end
diff --git a/app/helpers/ci/pipelines_helper.rb b/app/helpers/ci/pipelines_helper.rb
index d742842b8b6..8d2f83409be 100644
--- a/app/helpers/ci/pipelines_helper.rb
+++ b/app/helpers/ci/pipelines_helper.rb
@@ -84,6 +84,7 @@ module Ci
data = {
endpoint: list_url,
project_id: project.id,
+ default_branch_name: project.default_branch,
params: params.to_json,
artifacts_endpoint: downloadable_artifacts_project_pipeline_path(project, artifacts_endpoint_placeholder, format: :json),
artifacts_endpoint_placeholder: artifacts_endpoint_placeholder,
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index 069096e5bc0..e7b63d5e17f 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -413,6 +413,7 @@ class ProjectPolicy < BasePolicy
enable :admin_feature_flag
enable :admin_feature_flags_user_lists
enable :update_escalation_status
+ enable :read_secure_files
end
rule { can?(:developer_access) & user_confirmed? }.policy do
@@ -462,6 +463,7 @@ class ProjectPolicy < BasePolicy
enable :register_project_runners
enable :update_runners_registration_token
enable :admin_project_google_cloud
+ enable :admin_secure_files
end
rule { public_project & metrics_dashboard_allowed }.policy do
diff --git a/app/services/ci/destroy_secure_file_service.rb b/app/services/ci/destroy_secure_file_service.rb
new file mode 100644
index 00000000000..7145ace7f31
--- /dev/null
+++ b/app/services/ci/destroy_secure_file_service.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module Ci
+ class DestroySecureFileService < BaseService
+ def execute(secure_file)
+ raise Gitlab::Access::AccessDeniedError unless can?(current_user, :admin_secure_files, secure_file.project)
+
+ secure_file.destroy!
+ end
+ end
+end
diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb
index adbc26420c7..a73244c6971 100644
--- a/app/services/projects/destroy_service.rb
+++ b/app/services/projects/destroy_service.rb
@@ -200,6 +200,10 @@ module Projects
::Ci::DestroyPipelineService.new(project, current_user).execute(pipeline)
end
+ project.secure_files.find_each(batch_size: BATCH_SIZE) do |secure_file| # rubocop: disable CodeReuse/ActiveRecord
+ ::Ci::DestroySecureFileService.new(project, current_user).execute(secure_file)
+ end
+
deleted_count = ::CommitStatus.for_project(project).delete_all
Gitlab::AppLogger.info(