diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-03-15 12:07:33 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-03-15 12:07:33 +0300 |
commit | 389d5aa505a916b0506b7b73dcc3be342d724976 (patch) | |
tree | d53490630b9aac2eb397d9816db91030afad832a /app | |
parent | f632ee795fd542d7ae2753d157725bd39d33e32d (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
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( |