diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-01-21 21:09:11 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-01-21 21:09:11 +0300 |
commit | 37a492326e7cde47928ee72abcc284ff9cf8f254 (patch) | |
tree | 832417ddab170745bca91ec158b70973ba0700af /app | |
parent | 81884c35b86035f89364db482e4fff91718bb63a (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
26 files changed, 192 insertions, 164 deletions
diff --git a/app/assets/javascripts/merge_request/components/status_box.vue b/app/assets/javascripts/merge_request/components/status_box.vue index fd99802caff..b2754dd4ad6 100644 --- a/app/assets/javascripts/merge_request/components/status_box.vue +++ b/app/assets/javascripts/merge_request/components/status_box.vue @@ -5,12 +5,14 @@ import mrEventHub from '../eventhub'; const CLASSES = { opened: 'status-box-open', + locked: 'status-box-open', closed: 'status-box-mr-closed', merged: 'status-box-mr-merged', }; const STATUS = { opened: [__('Open'), 'issue-open-m'], + locked: [__('Open'), 'issue-open-m'], closed: [__('Closed'), 'close'], merged: [__('Merged'), 'git-merge'], }; diff --git a/app/assets/javascripts/monitoring/components/charts/single_stat.vue b/app/assets/javascripts/monitoring/components/charts/single_stat.vue index a8ab41ebf26..4cf583fed18 100644 --- a/app/assets/javascripts/monitoring/components/charts/single_stat.vue +++ b/app/assets/javascripts/monitoring/components/charts/single_stat.vue @@ -45,12 +45,18 @@ export default { } if (this.graphData?.maxValue) { - formatter = getFormatter(SUPPORTED_FORMATS.percent); - return formatter(this.queryResult / Number(this.graphData.maxValue), defaultPrecision); + formatter = getFormatter(SUPPORTED_FORMATS.number); + return formatter( + (this.queryResult / Number(this.graphData.maxValue)) * 100, + defaultPrecision, + ); } formatter = getFormatter(SUPPORTED_FORMATS.number); - return `${formatter(this.queryResult, defaultPrecision)}${this.queryInfo.unit ?? ''}`; + return `${formatter(this.queryResult, defaultPrecision)}`; + }, + unit() { + return this.graphData?.maxValue ? '%' : this.queryInfo.unit; }, graphTitle() { return this.queryInfo.label; @@ -60,6 +66,6 @@ export default { </script> <template> <div> - <gl-single-stat :value="statValue" :title="graphTitle" variant="success" /> + <gl-single-stat :value="statValue" :title="graphTitle" :unit="unit" variant="success" /> </div> </template> diff --git a/app/assets/javascripts/pages/projects/commit/pipelines/index.js b/app/assets/javascripts/pages/projects/commit/pipelines/index.js index eaf340f2725..f542014c5b9 100644 --- a/app/assets/javascripts/pages/projects/commit/pipelines/index.js +++ b/app/assets/javascripts/pages/projects/commit/pipelines/index.js @@ -1,5 +1,7 @@ import { initCommitBoxInfo } from '~/projects/commit_box/info'; import initPipelines from '~/commit/pipelines/pipelines_bundle'; +import initCommitActions from '~/projects/commit'; initCommitBoxInfo(); initPipelines(); +initCommitActions(); diff --git a/app/assets/javascripts/pages/projects/commit/show/index.js b/app/assets/javascripts/pages/projects/commit/show/index.js index 5cfdb125e4f..5a3b486fd40 100644 --- a/app/assets/javascripts/pages/projects/commit/show/index.js +++ b/app/assets/javascripts/pages/projects/commit/show/index.js @@ -14,8 +14,7 @@ import flash from '~/flash'; import { __ } from '~/locale'; import loadAwardsHandler from '~/awards_handler'; import { initCommitBoxInfo } from '~/projects/commit_box/info'; -import initRevertCommitTrigger from '~/projects/commit/init_revert_commit_trigger'; -import initRevertCommitModal from '~/projects/commit/init_revert_commit_modal'; +import initCommitActions from '~/projects/commit'; const hasPerfBar = document.querySelector('.with-performance-bar'); const performanceHeight = hasPerfBar ? 35 : 0; @@ -47,5 +46,4 @@ if (filesContainer.length) { new Diff(); } loadAwardsHandler(); -initRevertCommitModal(); -initRevertCommitTrigger(); +initCommitActions(); diff --git a/app/assets/javascripts/pipelines/pipeline_details_bundle.js b/app/assets/javascripts/pipelines/pipeline_details_bundle.js index 133608b9801..1c6f0b3f036 100644 --- a/app/assets/javascripts/pipelines/pipeline_details_bundle.js +++ b/app/assets/javascripts/pipelines/pipeline_details_bundle.js @@ -136,10 +136,13 @@ export default async function () { createTestDetails(); createDagApp(); + const canShowNewPipelineDetails = + gon.features.graphqlPipelineDetails || gon.features.graphqlPipelineDetailsUsers; + const { dataset } = document.querySelector(SELECTORS.PIPELINE_DETAILS); let mediator; - if (!gon.features.graphqlPipelineHeader || !gon.features.graphqlPipelineDetails) { + if (!gon.features.graphqlPipelineHeader || !canShowNewPipelineDetails) { try { const { default: PipelinesMediator } = await import( /* webpackChunkName: 'PipelinesMediator' */ './pipeline_details_mediator' @@ -151,7 +154,7 @@ export default async function () { } } - if (gon.features.graphqlPipelineDetails) { + if (canShowNewPipelineDetails) { try { const { createPipelinesDetailApp } = await import( /* webpackChunkName: 'createPipelinesDetailApp' */ './pipeline_details_graph' diff --git a/app/assets/javascripts/projects/commit/components/branches_dropdown.vue b/app/assets/javascripts/projects/commit/components/branches_dropdown.vue index 3ecc3f1d1d3..36da4128450 100644 --- a/app/assets/javascripts/projects/commit/components/branches_dropdown.vue +++ b/app/assets/javascripts/projects/commit/components/branches_dropdown.vue @@ -68,6 +68,7 @@ export default { autocomplete="off" :debounce="250" :placeholder="$options.i18n.searchPlaceholder" + data-testid="dropdown-search-box" @input="searchTermChanged" /> <gl-dropdown-item diff --git a/app/assets/javascripts/projects/commit/components/form_trigger.vue b/app/assets/javascripts/projects/commit/components/form_trigger.vue index e92854c1ac3..3561b5c2473 100644 --- a/app/assets/javascripts/projects/commit/components/form_trigger.vue +++ b/app/assets/javascripts/projects/commit/components/form_trigger.vue @@ -10,6 +10,9 @@ export default { displayText: { default: '', }, + testId: { + default: '', + }, }, props: { openModal: { @@ -26,7 +29,7 @@ export default { </script> <template> - <gl-link data-is-link="true" data-testid="revert-commit-link" @click="showModal"> + <gl-link data-is-link="true" :data-testid="testId" @click="showModal"> {{ displayText }} </gl-link> </template> diff --git a/app/assets/javascripts/projects/commit/constants.js b/app/assets/javascripts/projects/commit/constants.js index 233f43d56b9..b47c744e5fb 100644 --- a/app/assets/javascripts/projects/commit/constants.js +++ b/app/assets/javascripts/projects/commit/constants.js @@ -2,6 +2,10 @@ import { s__, __ } from '~/locale'; export const OPEN_REVERT_MODAL = 'openRevertModal'; export const REVERT_MODAL_ID = 'revert-commit-modal'; +export const REVERT_LINK_TEST_ID = 'revert-commit-link'; +export const OPEN_CHERRY_PICK_MODAL = 'openCherryPickModal'; +export const CHERRY_PICK_MODAL_ID = 'cherry-pick-commit-modal'; +export const CHERRY_PICK_LINK_TEST_ID = 'cherry-pick-commit-link'; export const I18N_MODAL = { startMergeRequest: s__('ChangeTypeAction|Start a %{newMergeRequest} with these changes'), @@ -20,6 +24,11 @@ export const I18N_REVERT_MODAL = { actionPrimaryText: s__('ChangeTypeAction|Revert'), }; +export const I18N_CHERRY_PICK_MODAL = { + branchLabel: s__('ChangeTypeAction|Pick into branch'), + actionPrimaryText: s__('ChangeTypeAction|Cherry-pick'), +}; + export const PREPENDED_MODAL_TEXT = s__( 'ChangeTypeAction|This will create a new commit in order to revert the existing changes.', ); diff --git a/app/assets/javascripts/projects/commit/index.js b/app/assets/javascripts/projects/commit/index.js new file mode 100644 index 00000000000..d5d7e62ce32 --- /dev/null +++ b/app/assets/javascripts/projects/commit/index.js @@ -0,0 +1,11 @@ +import initRevertCommitTrigger from './init_revert_commit_trigger'; +import initRevertCommitModal from './init_revert_commit_modal'; +import initCherryPickCommitTrigger from './init_cherry_pick_commit_trigger'; +import initCherryPickCommitModal from './init_cherry_pick_commit_modal'; + +export default () => { + initRevertCommitModal(); + initRevertCommitTrigger(); + initCherryPickCommitModal(); + initCherryPickCommitTrigger(); +}; diff --git a/app/assets/javascripts/projects/commit/init_cherry_pick_commit_modal.js b/app/assets/javascripts/projects/commit/init_cherry_pick_commit_modal.js new file mode 100644 index 00000000000..0bac569e5b7 --- /dev/null +++ b/app/assets/javascripts/projects/commit/init_cherry_pick_commit_modal.js @@ -0,0 +1,51 @@ +import Vue from 'vue'; +import CommitFormModal from './components/form_modal.vue'; +import { parseBoolean } from '~/lib/utils/common_utils'; +import createStore from './store'; +import { + I18N_MODAL, + I18N_CHERRY_PICK_MODAL, + OPEN_CHERRY_PICK_MODAL, + CHERRY_PICK_MODAL_ID, +} from './constants'; + +export default function initInviteMembersModal() { + const el = document.querySelector('.js-cherry-pick-commit-modal'); + if (!el) { + return false; + } + + const { + title, + endpoint, + branch, + pushCode, + branchCollaboration, + existingBranch, + branchesEndpoint, + } = el.dataset; + + const store = createStore({ + endpoint, + branchesEndpoint, + branch, + pushCode: parseBoolean(pushCode), + branchCollaboration: parseBoolean(branchCollaboration), + defaultBranch: branch, + modalTitle: title, + existingBranch, + }); + + return new Vue({ + el, + store, + render: (createElement) => + createElement(CommitFormModal, { + props: { + i18n: { ...I18N_CHERRY_PICK_MODAL, ...I18N_MODAL }, + openModal: OPEN_CHERRY_PICK_MODAL, + modalId: CHERRY_PICK_MODAL_ID, + }, + }), + }); +} diff --git a/app/assets/javascripts/projects/commit/init_cherry_pick_commit_trigger.js b/app/assets/javascripts/projects/commit/init_cherry_pick_commit_trigger.js new file mode 100644 index 00000000000..942451dc96a --- /dev/null +++ b/app/assets/javascripts/projects/commit/init_cherry_pick_commit_trigger.js @@ -0,0 +1,20 @@ +import Vue from 'vue'; +import CommitFormTrigger from './components/form_trigger.vue'; +import { OPEN_CHERRY_PICK_MODAL, CHERRY_PICK_LINK_TEST_ID } from './constants'; + +export default function initInviteMembersTrigger() { + const el = document.querySelector('.js-cherry-pick-commit-trigger'); + + if (!el) { + return false; + } + + const { displayText } = el.dataset; + + return new Vue({ + el, + provide: { displayText, testId: CHERRY_PICK_LINK_TEST_ID }, + render: (createElement) => + createElement(CommitFormTrigger, { props: { openModal: OPEN_CHERRY_PICK_MODAL } }), + }); +} diff --git a/app/assets/javascripts/projects/commit/init_revert_commit_trigger.js b/app/assets/javascripts/projects/commit/init_revert_commit_trigger.js index 0bb57f22663..dc5168524ca 100644 --- a/app/assets/javascripts/projects/commit/init_revert_commit_trigger.js +++ b/app/assets/javascripts/projects/commit/init_revert_commit_trigger.js @@ -1,6 +1,6 @@ import Vue from 'vue'; -import RevertCommitTrigger from './components/form_trigger.vue'; -import { OPEN_REVERT_MODAL } from './constants'; +import CommitFormTrigger from './components/form_trigger.vue'; +import { OPEN_REVERT_MODAL, REVERT_LINK_TEST_ID } from './constants'; export default function initInviteMembersTrigger() { const el = document.querySelector('.js-revert-commit-trigger'); @@ -13,8 +13,8 @@ export default function initInviteMembersTrigger() { return new Vue({ el, - provide: { displayText }, + provide: { displayText, testId: REVERT_LINK_TEST_ID }, render: (createElement) => - createElement(RevertCommitTrigger, { props: { openModal: OPEN_REVERT_MODAL } }), + createElement(CommitFormTrigger, { props: { openModal: OPEN_REVERT_MODAL } }), }); } diff --git a/app/assets/javascripts/vue_merge_request_widget/components/terraform/terraform_plan.vue b/app/assets/javascripts/vue_merge_request_widget/components/terraform/terraform_plan.vue index b74e036d9d9..5f65d1fa49a 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/terraform/terraform_plan.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/terraform/terraform_plan.vue @@ -15,6 +15,16 @@ export default { type: Object, }, }, + i18n: { + changes: s__( + 'Terraform|Reported Resource Changes: %{addNum} to add, %{changeNum} to change, %{deleteNum} to delete', + ), + generationErrored: s__('Terraform|Generating the report caused an error.'), + namedReportFailed: s__('Terraform|The report %{name} failed to generate.'), + namedReportGenerated: s__('Terraform|The report %{name} was generated in your pipelines.'), + reportFailed: s__('Terraform|A report failed to generate.'), + reportGenerated: s__('Terraform|A report was generated in your pipelines.'), + }, computed: { addNum() { return Number(this.plan.create); @@ -30,23 +40,21 @@ export default { }, reportChangeText() { if (this.validPlanValues) { - return s__( - 'Terraform|Reported Resource Changes: %{addNum} to add, %{changeNum} to change, %{deleteNum} to delete', - ); + return this.$options.i18n.changes; } - return s__('Terraform|Generating the report caused an error.'); + return this.$options.i18n.generationErrored; }, reportHeaderText() { if (this.validPlanValues) { return this.plan.job_name - ? s__('Terraform|The Terraform report %{name} was generated in your pipelines.') - : s__('Terraform|A Terraform report was generated in your pipelines.'); + ? this.$options.i18n.namedReportGenerated + : this.$options.i18n.reportGenerated; } return this.plan.job_name - ? s__('Terraform|The Terraform report %{name} failed to generate.') - : s__('Terraform|A Terraform report failed to generate.'); + ? this.$options.i18n.namedReportFailed + : this.$options.i18n.reportFailed; }, validPlanValues() { return this.addNum + this.changeNum + this.deleteNum >= 0; diff --git a/app/assets/javascripts/vue_shared/components/gfm_autocomplete/utils.js b/app/assets/javascripts/vue_shared/components/gfm_autocomplete/utils.js index 809932b0f29..44c3fc34ba6 100644 --- a/app/assets/javascripts/vue_shared/components/gfm_autocomplete/utils.js +++ b/app/assets/javascripts/vue_shared/components/gfm_autocomplete/utils.js @@ -84,7 +84,7 @@ export const tributeConfig = { value.type === groupType ? last(value.name.split(' / ')) : `${value.name}${value.username}`, menuItemLimit: memberLimit, menuItemTemplate: ({ original }) => { - const commonClasses = 'gl-avatar gl-avatar-s24 gl-flex-shrink-0'; + const commonClasses = 'gl-avatar gl-avatar-s32 gl-flex-shrink-0'; const noAvatarClasses = `${commonClasses} gl-rounded-small gl-display-flex gl-align-items-center gl-justify-content-center`; @@ -111,7 +111,7 @@ export const tributeConfig = { return ` <div class="gl-display-flex gl-align-items-center"> ${avatar} - <div class="gl-font-sm gl-line-height-normal gl-ml-3"> + <div class="gl-line-height-normal gl-ml-4"> <div>${escape(displayName)}${count}</div> <div class="gl-text-gray-700">${escape(parentGroupOrUsername)}</div> </div> diff --git a/app/assets/javascripts/vue_shared/security_reports/security_reports_app.vue b/app/assets/javascripts/vue_shared/security_reports/security_reports_app.vue index a6c7b59aa71..b6b32167ed6 100644 --- a/app/assets/javascripts/vue_shared/security_reports/security_reports_app.vue +++ b/app/assets/javascripts/vue_shared/security_reports/security_reports_app.vue @@ -1,13 +1,10 @@ <script> import { mapActions, mapGetters } from 'vuex'; -import { GlLink, GlSprintf } from '@gitlab/ui'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import ReportSection from '~/reports/components/report_section.vue'; -import { LOADING, ERROR, SLOT_SUCCESS, SLOT_LOADING, SLOT_ERROR } from '~/reports/constants'; +import { ERROR, SLOT_SUCCESS, SLOT_LOADING, SLOT_ERROR } from '~/reports/constants'; import { s__ } from '~/locale'; -import { normalizeHeaders, parseIntPagination } from '~/lib/utils/common_utils'; import createFlash from '~/flash'; -import Api from '~/api'; import HelpIcon from './components/help_icon.vue'; import SecurityReportDownloadDropdown from './components/security_report_download_dropdown.vue'; import SecuritySummary from './components/security_summary.vue'; @@ -24,8 +21,6 @@ import { extractSecurityReportArtifacts } from './utils'; export default { store, components: { - GlLink, - GlSprintf, ReportSection, HelpIcon, SecurityReportDownloadDropdown, @@ -101,9 +96,6 @@ export default { ), }; }, - skip() { - return !this.canShowDownloads; - }, update(data) { return extractSecurityReportArtifacts(this.$options.reportTypes, data); }, @@ -124,9 +116,6 @@ export default { }, computed: { ...mapGetters(['groupedSummaryText', 'summaryStatus']), - canShowDownloads() { - return this.glFeatures.coreSecurityMrWidgetDownloads; - }, hasSecurityReports() { return this.availableSecurityReports.length > 0; }, @@ -139,23 +128,6 @@ export default { isLoadingReportArtifacts() { return this.$apollo.queries.reportArtifacts.loading; }, - shouldShowDownloadGuidance() { - return !this.canShowDownloads && this.summaryStatus !== LOADING; - }, - scansHaveRunMessage() { - return this.canShowDownloads - ? this.$options.i18n.scansHaveRun - : this.$options.i18n.scansHaveRunWithDownloadGuidance; - }, - }, - created() { - if (!this.canShowDownloads) { - this.checkAvailableSecurityReports(this.$options.reportTypes) - .then((availableSecurityReports) => { - this.onCheckingAvailableSecurityReports(Array.from(availableSecurityReports)); - }) - .catch(this.showError); - } }, methods: { ...mapActions(MODULE_SAST, { @@ -166,36 +138,6 @@ export default { setSecretDetectionDiffEndpoint: 'setDiffEndpoint', fetchSecretDetectionDiff: 'fetchDiff', }), - async checkAvailableSecurityReports(reportTypes) { - const reportTypesSet = new Set(reportTypes); - const availableReportTypes = new Set(); - - let page = 1; - while (page) { - // eslint-disable-next-line no-await-in-loop - const { data: jobs, headers } = await Api.pipelineJobs(this.projectId, this.pipelineId, { - per_page: 100, - page, - }); - - jobs.forEach(({ artifacts = [] }) => { - artifacts.forEach(({ file_type }) => { - if (reportTypesSet.has(file_type)) { - availableReportTypes.add(file_type); - } - }); - }); - - // If we've found artifacts for all the report types, stop looking! - if (availableReportTypes.size === reportTypesSet.size) { - return availableReportTypes; - } - - page = parseIntPagination(normalizeHeaders(headers)).nextPage; - } - - return availableReportTypes; - }, fetchCounts() { if (!this.glFeatures.coreSecurityMrWidgetCounts) { return; @@ -213,11 +155,6 @@ export default { this.canShowCounts = true; } }, - activatePipelinesTab() { - if (window.mrTabs) { - window.mrTabs.tabShown('pipelines'); - } - }, onCheckingAvailableSecurityReports(availableSecurityReports) { this.availableSecurityReports = availableSecurityReports; this.fetchCounts(); @@ -236,12 +173,6 @@ export default { 'SecurityReports|Failed to get security report information. Please reload the page or try again later.', ), scansHaveRun: s__('SecurityReports|Security scans have run'), - scansHaveRunWithDownloadGuidance: s__( - 'SecurityReports|Security scans have run. Go to the %{linkStart}pipelines tab%{linkEnd} to download the security reports', - ), - downloadFromPipelineTab: s__( - 'SecurityReports|Go to the %{linkStart}pipelines tab%{linkEnd} to download the security reports', - ), }, summarySlots: [SLOT_SUCCESS, SLOT_LOADING, SLOT_ERROR], }; @@ -265,22 +196,7 @@ export default { </span> </template> - <template v-if="shouldShowDownloadGuidance" #sub-heading> - <span class="gl-font-sm"> - <gl-sprintf :message="$options.i18n.downloadFromPipelineTab"> - <template #link="{ content }"> - <gl-link - class="gl-font-sm" - data-testid="show-pipelines" - @click="activatePipelinesTab" - >{{ content }}</gl-link - > - </template> - </gl-sprintf> - </span> - </template> - - <template v-if="canShowDownloads" #action-buttons> + <template #action-buttons> <security-report-download-dropdown :artifacts="reportArtifacts" :loading="isLoadingReportArtifacts" @@ -298,13 +214,7 @@ export default { data-testid="security-mr-widget" > <template #error> - <gl-sprintf :message="scansHaveRunMessage"> - <template #link="{ content }"> - <gl-link data-testid="show-pipelines" @click="activatePipelinesTab">{{ - content - }}</gl-link> - </template> - </gl-sprintf> + {{ $options.i18n.scansHaveRun }} <help-icon :help-path="securityReportsDocsPath" @@ -312,7 +222,7 @@ export default { /> </template> - <template v-if="canShowDownloads" #action-buttons> + <template #action-buttons> <security-report-download-dropdown :artifacts="reportArtifacts" :loading="isLoadingReportArtifacts" diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index d452a5e02e2..27402573c42 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -38,7 +38,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo push_frontend_feature_flag(:default_merge_ref_for_diffs, @project) push_frontend_feature_flag(:core_security_mr_widget, @project, default_enabled: true) push_frontend_feature_flag(:core_security_mr_widget_counts, @project) - push_frontend_feature_flag(:core_security_mr_widget_downloads, @project, default_enabled: true) push_frontend_feature_flag(:remove_resolve_note, @project, default_enabled: true) push_frontend_feature_flag(:diffs_gradual_load, @project, default_enabled: true) push_frontend_feature_flag(:codequality_mr_diff, @project) diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index e44c00e501e..f8fa22ac859 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -16,7 +16,8 @@ class Projects::PipelinesController < Projects::ApplicationController push_frontend_feature_flag(:pipelines_security_report_summary, project) push_frontend_feature_flag(:new_pipeline_form, project, default_enabled: true) push_frontend_feature_flag(:graphql_pipeline_header, project, type: :development, default_enabled: false) - push_frontend_feature_flag(:graphql_pipeline_details, project, type: :development, default_enabled: false) + push_frontend_feature_flag(:graphql_pipeline_details, project, type: :development, default_enabled: :yaml) + push_frontend_feature_flag(:graphql_pipeline_details_users, current_user, type: :development, default_enabled: :yaml) push_frontend_feature_flag(:new_pipeline_form_prefilled_vars, project, type: :development, default_enabled: true) end before_action :ensure_pipeline, only: [:show] diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index e6e2b5b128b..2eb959856a5 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -110,20 +110,16 @@ module CommitsHelper end end - def revert_commit_link(commit, continue_to_path, btn_class: nil, pajamas: false) + def revert_commit_link return unless current_user - action = 'revert' - - if pajamas && can_collaborate_with_project?(@project) - tag(:div, data: { display_text: action.capitalize }, class: "js-revert-commit-trigger") - else - commit_action_link(action, commit, continue_to_path, btn_class: btn_class, has_tooltip: false) - end + tag(:div, data: { display_text: 'Revert' }, class: "js-revert-commit-trigger") end - def cherry_pick_commit_link(commit, continue_to_path, btn_class: nil, has_tooltip: true) - commit_action_link('cherry-pick', commit, continue_to_path, btn_class: btn_class, has_tooltip: has_tooltip) + def cherry_pick_commit_link + return unless current_user + + tag(:div, data: { display_text: 'Cherry-pick' }, class: "js-cherry-pick-commit-trigger") end def commit_signature_badge_classes(additional_classes) @@ -143,7 +139,7 @@ module CommitsHelper def commit_person_link(commit, options = {}) user = commit.public_send(options[:source]) # rubocop:disable GitlabSecurity/PublicSend - source_name = clean(commit.public_send(:"#{options[:source]}_name")) # rubocop:disable GitlabSecurity/PublicSend + source_name = clean(commit.public_send(:"#{options[:source]}_name")) # rubocop:disable GitlabSecurity/PublicSend source_email = clean(commit.public_send(:"#{options[:source]}_email")) # rubocop:disable GitlabSecurity/PublicSend person_name = user.try(:name) || source_name @@ -166,28 +162,6 @@ module CommitsHelper end end - def commit_action_link(action, commit, continue_to_path, btn_class: nil, has_tooltip: true) - return unless current_user - - tooltip = "#{action.capitalize} this #{commit.change_type_title(current_user)} in a new merge request" if has_tooltip - btn_class = "btn btn-#{btn_class}" unless btn_class.nil? - - if can_collaborate_with_project?(@project) - link_to action.capitalize, "#modal-#{action}-commit", 'data-toggle' => 'modal', 'data-container' => 'body', title: (tooltip if has_tooltip), class: "#{btn_class} #{'has-tooltip' if has_tooltip}" - elsif can?(current_user, :fork_project, @project) - continue_params = { - to: continue_to_path, - notice: "#{edit_in_new_fork_notice} Try to #{action} this commit again.", - notice_now: edit_in_new_fork_notice_now - } - fork_path = project_forks_path(@project, - namespace_key: current_user.namespace.id, - continue: continue_params) - - link_to action.capitalize, fork_path, class: btn_class, method: :post, 'data-toggle' => 'tooltip', 'data-container' => 'body', title: (tooltip if has_tooltip) - end - end - def view_file_button(commit_sha, diff_new_path, project, replaced: false) path = project_blob_path(project, tree_join(commit_sha, diff_new_path)) title = replaced ? _('View replaced file @ ') : _('View file @ ') diff --git a/app/models/pages/lookup_path.rb b/app/models/pages/lookup_path.rb index 84928468ad1..b7e27f460a8 100644 --- a/app/models/pages/lookup_path.rb +++ b/app/models/pages/lookup_path.rb @@ -4,6 +4,8 @@ module Pages class LookupPath include Gitlab::Utils::StrongMemoize + LegacyStorageDisabledError = Class.new(::StandardError) + def initialize(project, trim_prefix: nil, domain: nil) @project = project @domain = domain @@ -24,7 +26,7 @@ module Pages end def source - zip_source || file_source + zip_source || legacy_source end def prefix @@ -64,11 +66,17 @@ module Pages } end - def file_source + def legacy_source + raise LegacyStorageDisabledError unless Feature.enabled?(:pages_serve_from_legacy_storage, default_enabled: true) + { type: 'file', path: File.join(project.full_path, 'public/') } + rescue LegacyStorageDisabledError => e + Gitlab::ErrorTracking.track_exception(e) + + nil end end end diff --git a/app/models/pages/virtual_domain.rb b/app/models/pages/virtual_domain.rb index 7e42b8e6ae2..90cb8253b52 100644 --- a/app/models/pages/virtual_domain.rb +++ b/app/models/pages/virtual_domain.rb @@ -17,9 +17,16 @@ module Pages end def lookup_paths - projects.map do |project| + paths = projects.map do |project| project.pages_lookup_path(trim_prefix: trim_prefix, domain: domain) - end.sort_by(&:prefix).reverse + end + + # TODO: remove in https://gitlab.com/gitlab-org/gitlab/-/issues/297524 + # source can only be nil if pages_serve_from_legacy_storage FF is disabled + # we can remove this filtering once we remove legacy storage + paths = paths.select(&:source) + + paths.sort_by(&:prefix).reverse end private diff --git a/app/views/projects/commit/_change.html.haml b/app/views/projects/commit/_change.html.haml index 69b20fbc6d0..3c5f291b157 100644 --- a/app/views/projects/commit/_change.html.haml +++ b/app/views/projects/commit/_change.html.haml @@ -22,4 +22,14 @@ - label = s_('ChangeTypeAction|Cherry-pick') - branch_label = s_('ChangeTypeActionLabel|Pick into branch') - title = commit.merged_merge_request(current_user) ? _('Cherry-pick this merge request') : _('Cherry-pick this commit') - = render "projects/commit/commit_modal", title: title, type: type, commit: commit, branch_label: branch_label, description: description, label: label + + - if defined?(pajamas) + .js-cherry-pick-commit-modal{ data: { title: title, + endpoint: cherry_pick_namespace_project_commit_path(commit, namespace_id: @project.namespace.full_path, project_id: @project), + branch: @project.default_branch, + push_code: can?(current_user, :push_code, @project).to_s, + branch_collaboration: @project.branch_allows_collaboration?(current_user, selected_branch).to_s, + existing_branch: ERB::Util.html_escape(selected_branch), + branches_endpoint: project_branches_path(@project) } } + - else + = render "projects/commit/commit_modal", title: title, type: type, commit: commit, branch_label: branch_label, description: description, label: label diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml index e8d524daced..a5cfbaa7bad 100644 --- a/app/views/projects/commit/_commit_box.html.haml +++ b/app/views/projects/commit/_commit_box.html.haml @@ -37,10 +37,10 @@ #{ _('Browse Files') } - if can_collaborate && !@commit.has_been_reverted?(current_user) %li.clearfix - = revert_commit_link(@commit, project_commit_path(@project, @commit.id), pajamas: true) + = revert_commit_link - if can_collaborate %li.clearfix - = cherry_pick_commit_link(@commit, project_commit_path(@project, @commit.id), has_tooltip: false) + = cherry_pick_commit_link - if can?(current_user, :push_code, @project) %li.clearfix = link_to s_('CreateTag|Tag'), new_project_tag_path(@project, ref: @commit) diff --git a/app/views/projects/commit/pipelines.html.haml b/app/views/projects/commit/pipelines.html.haml index 0dbd6e53212..b4c59c73e3b 100644 --- a/app/views/projects/commit/pipelines.html.haml +++ b/app/views/projects/commit/pipelines.html.haml @@ -4,3 +4,7 @@ = render 'commit_box' = render 'ci_menu' = render 'projects/commit/pipelines_list', endpoint: pipelines_project_commit_path(@project, @commit.id) + +- if can_collaborate_with_project?(@project) + = render "projects/commit/change", type: 'revert', commit: @commit, pajamas: true + = render "projects/commit/change", type: 'cherry-pick', commit: @commit, pajamas: true diff --git a/app/views/projects/commit/show.html.haml b/app/views/projects/commit/show.html.haml index e7b2e757ce4..5e3bc270d5f 100644 --- a/app/views/projects/commit/show.html.haml +++ b/app/views/projects/commit/show.html.haml @@ -18,4 +18,4 @@ = render "shared/notes/notes_with_form", :autocomplete => true - if can_collaborate_with_project?(@project) = render "projects/commit/change", type: 'revert', commit: @commit, pajamas: true - = render "projects/commit/change", type: 'cherry-pick', commit: @commit, title: @commit.title + = render "projects/commit/change", type: 'cherry-pick', commit: @commit, pajamas: true diff --git a/app/views/projects/pipelines/show.html.haml b/app/views/projects/pipelines/show.html.haml index b3ad210aa47..b431ef202b3 100644 --- a/app/views/projects/pipelines/show.html.haml +++ b/app/views/projects/pipelines/show.html.haml @@ -6,7 +6,7 @@ - add_page_specific_style 'page_bundles/reports' - add_page_specific_style 'page_bundles/ci_status' -- if Feature.enabled?(:graphql_pipeline_details, @project) +- if Feature.enabled?(:graphql_pipeline_details, @project, default_enabled: :yaml) || Feature.enabled?(:graphql_pipeline_details_users, @current_user, default_enabled: :yaml) - add_page_startup_graphql_call('pipelines/get_pipeline_details', { projectPath: @project.full_path, iid: @pipeline.iid }) .js-pipeline-container{ data: { controller_action: "#{controller.action_name}" } } diff --git a/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb b/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb index 7c86b194574..b4afe53d4bc 100644 --- a/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb +++ b/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb @@ -25,6 +25,7 @@ module ContainerExpirationPolicies return unless container_repository log_extra_metadata_on_done(:container_repository_id, container_repository.id) + log_extra_metadata_on_done(:project_id, project.id) unless allowed_to_run?(container_repository) container_repository.cleanup_unscheduled! @@ -78,7 +79,7 @@ module ContainerExpirationPolicies end def project - container_repository&.project + container_repository.project end def container_repository |