From 7928b47c8e06c1ac3f63d321a73dd527aea4e4c3 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Tue, 4 Oct 2022 12:08:25 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- .../components/access_token_table_app.vue | 17 ++- .../components/ui/pipeline_editor_empty_state.vue | 48 ++++-- app/assets/javascripts/pipeline_editor/index.js | 3 + .../pipeline_editor/pipeline_editor_app.vue | 4 +- .../branch_rules/components/view/constants.js | 35 +++++ .../branch_rules/components/view/index.vue | 165 +++++++++++++++++++-- .../branch_rules/components/view/protection.vue | 2 +- .../components/view/protection_row.vue | 4 + .../settings/branch_rules/mount_branch_rules.js | 10 +- .../queries/branch_rules_details.query.graphql | 50 +++++++ .../settings/repository/branch_rules/app.vue | 5 +- .../branch_rules/components/branch_rule.vue | 37 +++-- .../repository/branch_rules/mount_branch_rules.js | 12 +- app/assets/stylesheets/_page_specific_files.scss | 1 - app/assets/stylesheets/page_bundles/incidents.scss | 73 +++++++++ .../stylesheets/page_bundles/prometheus.scss | 116 +++++++++++++++ app/assets/stylesheets/pages/issuable.scss | 100 ------------- app/assets/stylesheets/pages/prometheus.scss | 114 -------------- app/helpers/ci/pipeline_editor_helper.rb | 12 +- app/helpers/ci/pipelines_helper.rb | 3 +- app/models/project.rb | 9 ++ app/models/user.rb | 1 + app/models/users/phone_number_validation.rb | 41 +++++ app/models/wiki.rb | 10 +- app/models/wiki_page.rb | 4 +- app/uploaders/object_storage/cdn/google_cdn.rb | 2 +- app/views/clusters/clusters/_health.html.haml | 2 + app/views/projects/blob/_blob.html.haml | 2 +- app/views/projects/branch_rules/_show.html.haml | 2 +- app/views/projects/environments/metrics.html.haml | 2 + app/views/projects/incidents/show.html.haml | 1 + app/views/projects/issues/show.html.haml | 1 + .../mirrors/_authentication_method.html.haml | 10 +- app/views/projects/pipelines/_info.html.haml | 2 + .../projects/settings/branch_rules/index.html.haml | 4 +- 35 files changed, 612 insertions(+), 292 deletions(-) create mode 100644 app/assets/javascripts/projects/settings/branch_rules/components/view/constants.js create mode 100644 app/assets/javascripts/projects/settings/branch_rules/queries/branch_rules_details.query.graphql create mode 100644 app/assets/stylesheets/page_bundles/incidents.scss create mode 100644 app/assets/stylesheets/page_bundles/prometheus.scss delete mode 100644 app/assets/stylesheets/pages/prometheus.scss create mode 100644 app/models/users/phone_number_validation.rb (limited to 'app') diff --git a/app/assets/javascripts/access_tokens/components/access_token_table_app.vue b/app/assets/javascripts/access_tokens/components/access_token_table_app.vue index 76709296c89..cd64579a360 100644 --- a/app/assets/javascripts/access_tokens/components/access_token_table_app.vue +++ b/app/assets/javascripts/access_tokens/components/access_token_table_app.vue @@ -55,7 +55,22 @@ export default { }, computed: { filteredFields() { - return this.showRole ? FIELDS : FIELDS.filter((field) => field.key !== 'role'); + const ignoredFields = []; + + // Show 'action' column only when there are no active tokens or when some of them have a revokePath + const showAction = + this.activeAccessTokens.length === 0 || + this.activeAccessTokens.some((token) => token.revokePath); + + if (!showAction) { + ignoredFields.push('action'); + } + + if (!this.showRole) { + ignoredFields.push('role'); + } + + return FIELDS.filter(({ key }) => !ignoredFields.includes(key)); }, header() { return sprintf(this.$options.i18n.header, { diff --git a/app/assets/javascripts/pipeline_editor/components/ui/pipeline_editor_empty_state.vue b/app/assets/javascripts/pipeline_editor/components/ui/pipeline_editor_empty_state.vue index 3e87088e77e..7d2b9cd3d42 100644 --- a/app/assets/javascripts/pipeline_editor/components/ui/pipeline_editor_empty_state.vue +++ b/app/assets/javascripts/pipeline_editor/components/ui/pipeline_editor_empty_state.vue @@ -15,11 +15,20 @@ export default { 'Create a new %{codeStart}.gitlab-ci.yml%{codeEnd} file at the root of the repository to get started.', ), btnText: __('Configure pipeline'), + externalCiNote: __("This project's pipeline configuration is located outside this repository"), + externalCiInstructions: __( + 'To edit the pipeline configuration, you must go to the project or external site that hosts the file.', + ), }, inject: { emptyStateIllustrationPath: { default: '', }, + usesExternalConfig: { + default: false, + type: Boolean, + required: false, + }, }, methods: { createEmptyConfigFile() { @@ -33,22 +42,31 @@ export default {
-

{{ $options.i18n.title }}

-

- - - -

- - {{ $options.i18n.btnText }} - +

{{ $options.i18n.externalCiNote }}

+

{{ $options.i18n.externalCiInstructions }}

+
+
+

{{ $options.i18n.title }}

+

+ + + +

+ + {{ $options.i18n.btnText }} + +
diff --git a/app/assets/javascripts/pipeline_editor/index.js b/app/assets/javascripts/pipeline_editor/index.js index 13dad0b2459..6d91c339833 100644 --- a/app/assets/javascripts/pipeline_editor/index.js +++ b/app/assets/javascripts/pipeline_editor/index.js @@ -2,6 +2,7 @@ import Vue from 'vue'; import VueApollo from 'vue-apollo'; import createDefaultClient from '~/lib/graphql'; +import { parseBoolean } from '~/lib/utils/common_utils'; import { EDITOR_APP_STATUS_LOADING } from './constants'; import { CODE_SNIPPET_SOURCE_SETTINGS } from './components/code_snippet_alert/constants'; import getCurrentBranch from './graphql/queries/client/current_branch.query.graphql'; @@ -42,6 +43,7 @@ export const initPipelineEditor = (selector = '#js-pipeline-editor') => { projectNamespace, simulatePipelineHelpPagePath, totalBranches, + usesExternalConfig, validateTabIllustrationPath, ymlHelpPagePath, } = el.dataset; @@ -133,6 +135,7 @@ export const initPipelineEditor = (selector = '#js-pipeline-editor') => { projectNamespace, simulatePipelineHelpPagePath, totalBranches: parseInt(totalBranches, 10), + usesExternalConfig: parseBoolean(usesExternalConfig), validateTabIllustrationPath, ymlHelpPagePath, }, diff --git a/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue b/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue index 548769eb214..ff848a973e3 100644 --- a/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue +++ b/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue @@ -40,7 +40,7 @@ export default { PipelineEditorHome, PipelineEditorMessages, }, - inject: ['ciConfigPath', 'newMergeRequestPath', 'projectFullPath'], + inject: ['ciConfigPath', 'newMergeRequestPath', 'projectFullPath', 'usesExternalConfig'], data() { return { ciConfigData: {}, @@ -397,7 +397,7 @@ export default {
diff --git a/app/assets/javascripts/projects/settings/branch_rules/components/view/constants.js b/app/assets/javascripts/projects/settings/branch_rules/components/view/constants.js new file mode 100644 index 00000000000..1fd87b9897c --- /dev/null +++ b/app/assets/javascripts/projects/settings/branch_rules/components/view/constants.js @@ -0,0 +1,35 @@ +import { s__ } from '~/locale'; + +export const I18N = { + manageProtectionsLinkTitle: s__('BranchRules|Manage in Protected Branches'), + targetBranch: s__('BranchRules|Target Branch'), + branchNameOrPattern: s__('BranchRules|Branch name or pattern'), + branch: s__('BranchRules|Target Branch'), + allBranches: s__('BranchRules|All branches'), + protectBranchTitle: s__('BranchRules|Protect branch'), + protectBranchDescription: s__( + 'BranchRules|Keep stable branches secure and force developers to use merge requests. %{linkStart}What are protected branches?%{linkEnd}', + ), + wildcardsHelpText: s__( + 'BranchRules|%{linkStart}Wildcards%{linkEnd} such as *-stable or production/ are supported', + ), + forcePushTitle: s__('BranchRules|Force push'), + allowForcePushDescription: s__( + 'BranchRules|All users with push access are allowed to force push.', + ), + disallowForcePushDescription: s__('BranchRules|Force push is not allowed.'), + approvalsTitle: s__('BranchRules|Approvals'), + statusChecksTitle: s__('BranchRules|Status checks'), + allowedToPushHeader: s__('BranchRules|Allowed to push (%{total})'), + allowedToMergeHeader: s__('BranchRules|Allowed to merge (%{total})'), + noData: s__('BranchRules|No data to display'), +}; + +export const BRANCH_PARAM_NAME = 'branch'; + +export const ALL_BRANCHES_WILDCARD = '*'; + +export const WILDCARDS_HELP_PATH = + 'user/project/protected_branches#configure-multiple-protected-branches-by-using-a-wildcard'; + +export const PROTECTED_BRANCHES_HELP_PATH = 'user/project/protected_branches'; diff --git a/app/assets/javascripts/projects/settings/branch_rules/components/view/index.vue b/app/assets/javascripts/projects/settings/branch_rules/components/view/index.vue index 58938b6bf96..6534ff883a6 100644 --- a/app/assets/javascripts/projects/settings/branch_rules/components/view/index.vue +++ b/app/assets/javascripts/projects/settings/branch_rules/components/view/index.vue @@ -1,33 +1,172 @@ diff --git a/app/assets/javascripts/projects/settings/branch_rules/components/view/protection.vue b/app/assets/javascripts/projects/settings/branch_rules/components/view/protection.vue index ec70ab88870..8434b7bfce5 100644 --- a/app/assets/javascripts/projects/settings/branch_rules/components/view/protection.vue +++ b/app/assets/javascripts/projects/settings/branch_rules/components/view/protection.vue @@ -58,7 +58,7 @@ export default { diff --git a/app/assets/javascripts/projects/settings/branch_rules/components/view/protection_row.vue b/app/assets/javascripts/projects/settings/branch_rules/components/view/protection_row.vue index 56be0198574..2509c2538b2 100644 --- a/app/assets/javascripts/projects/settings/branch_rules/components/view/protection_row.vue +++ b/app/assets/javascripts/projects/settings/branch_rules/components/view/protection_row.vue @@ -45,6 +45,9 @@ export default { this.users.length - this.$options.MAX_VISIBLE_AVATARS, ); }, + commaSeparateList() { + return this.accessLevels.length > 1; + }, }, }; @@ -80,6 +83,7 @@ export default {
+ , {{ item.accessLevelDescription }}
diff --git a/app/assets/javascripts/projects/settings/branch_rules/mount_branch_rules.js b/app/assets/javascripts/projects/settings/branch_rules/mount_branch_rules.js index 10de5f12757..39164063d05 100644 --- a/app/assets/javascripts/projects/settings/branch_rules/mount_branch_rules.js +++ b/app/assets/javascripts/projects/settings/branch_rules/mount_branch_rules.js @@ -1,7 +1,7 @@ import Vue from 'vue'; import VueApollo from 'vue-apollo'; import createDefaultClient from '~/lib/graphql'; -import RuleEdit from './components/edit/index.vue'; +import View from './components/view/index.vue'; export default function mountBranchRules(el) { if (!el) { @@ -14,13 +14,17 @@ export default function mountBranchRules(el) { defaultClient: createDefaultClient(), }); - const { projectPath } = el.dataset; + const { projectPath, protectedBranchesPath } = el.dataset; return new Vue({ el, apolloProvider, + provide: { + projectPath, + protectedBranchesPath, + }, render(h) { - return h(RuleEdit, { props: { projectPath } }); + return h(View); }, }); } diff --git a/app/assets/javascripts/projects/settings/branch_rules/queries/branch_rules_details.query.graphql b/app/assets/javascripts/projects/settings/branch_rules/queries/branch_rules_details.query.graphql new file mode 100644 index 00000000000..3ac165498a1 --- /dev/null +++ b/app/assets/javascripts/projects/settings/branch_rules/queries/branch_rules_details.query.graphql @@ -0,0 +1,50 @@ +query getBranchRulesDetails($projectPath: ID!) { + project(fullPath: $projectPath) { + id + branchRules { + nodes { + name + branchProtection { + allowForcePush + codeOwnerApprovalRequired + mergeAccessLevels { + edges { + node { + accessLevel + accessLevelDescription + group { + id + avatarUrl + } + user { + id + name + avatarUrl + webUrl + } + } + } + } + pushAccessLevels { + edges { + node { + accessLevel + accessLevelDescription + group { + id + avatarUrl + } + user { + id + name + avatarUrl + webUrl + } + } + } + } + } + } + } + } +} diff --git a/app/assets/javascripts/projects/settings/repository/branch_rules/app.vue b/app/assets/javascripts/projects/settings/repository/branch_rules/app.vue index 65e0c87e3f3..94793a535cc 100644 --- a/app/assets/javascripts/projects/settings/repository/branch_rules/app.vue +++ b/app/assets/javascripts/projects/settings/repository/branch_rules/app.vue @@ -35,10 +35,9 @@ export default { }, }, }, - props: { + inject: { projectPath: { - type: String, - required: true, + default: '', }, }, data() { diff --git a/app/assets/javascripts/projects/settings/repository/branch_rules/components/branch_rule.vue b/app/assets/javascripts/projects/settings/repository/branch_rules/components/branch_rule.vue index 68750318029..2b88f8561d7 100644 --- a/app/assets/javascripts/projects/settings/repository/branch_rules/components/branch_rule.vue +++ b/app/assets/javascripts/projects/settings/repository/branch_rules/components/branch_rule.vue @@ -1,10 +1,11 @@ diff --git a/app/assets/javascripts/projects/settings/repository/branch_rules/mount_branch_rules.js b/app/assets/javascripts/projects/settings/repository/branch_rules/mount_branch_rules.js index 35322e2e466..042be089e09 100644 --- a/app/assets/javascripts/projects/settings/repository/branch_rules/mount_branch_rules.js +++ b/app/assets/javascripts/projects/settings/repository/branch_rules/mount_branch_rules.js @@ -12,17 +12,17 @@ const apolloProvider = new VueApollo({ export default function mountBranchRules(el) { if (!el) return null; - const { projectPath } = el.dataset; + const { projectPath, branchRulesPath } = el.dataset; return new Vue({ el, apolloProvider, + provide: { + projectPath, + branchRulesPath, + }, render(createElement) { - return createElement(BranchRulesApp, { - props: { - projectPath, - }, - }); + return createElement(BranchRulesApp); }, }); } diff --git a/app/assets/stylesheets/_page_specific_files.scss b/app/assets/stylesheets/_page_specific_files.scss index 147d7a92d57..68fe701c7e1 100644 --- a/app/assets/stylesheets/_page_specific_files.scss +++ b/app/assets/stylesheets/_page_specific_files.scss @@ -17,7 +17,6 @@ @import './pages/pipelines'; @import './pages/profile'; @import './pages/projects'; -@import './pages/prometheus'; @import './pages/registry'; @import './pages/search'; @import './pages/service_desk'; diff --git a/app/assets/stylesheets/page_bundles/incidents.scss b/app/assets/stylesheets/page_bundles/incidents.scss new file mode 100644 index 00000000000..de246fa14b9 --- /dev/null +++ b/app/assets/stylesheets/page_bundles/incidents.scss @@ -0,0 +1,73 @@ +@import 'mixins_and_variables_and_functions'; + +.issuable-discussion.incident-timeline-events { + .main-notes-list::before { + content: none; + } + + .timeline-event-note { + p { + margin-bottom: 0; + font-size: 0.875rem; + } + } +} + +/** + * We have a very specific design proposal where we cannot + * use `vertical-line` mixin as it is and have to use + * custom styles, see https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81284#note_904867444 + */ +.timeline-entry-vertical-line { + &::before, + &::after { + content: ''; + border-left: 2px solid $gray-50; + position: absolute; + left: 20px; + height: calc(100% + #{$gl-spacing-scale-5}); + top: -#{$gl-spacing-scale-5}; + } + + &:first-child::before { + content: none; + } + + &:first-child { + &::after { + top: $gl-spacing-scale-5; + height: calc(100% + #{$gl-spacing-scale-5}); + } + } + + &:last-child, + &.create-timeline-event { + &::before { + top: - #{$gl-spacing-scale-5} !important; // Override default positioning + @include gl-h-8; + } + + &::after { + content: none; + } + } +} + +.timeline-entry:not(:last-child) { + .timeline-event-border { + @include gl-pb-5; + @include gl-border-gray-50; + @include gl-border-1; + @include gl-border-b-solid; + } +} + +.timeline-group:last-child { + .timeline-entry:last-child, + .create-timeline-event { + .timeline-event-bottom-border { + @include gl-border-b; + @include gl-pt-5; + } + } +} diff --git a/app/assets/stylesheets/page_bundles/prometheus.scss b/app/assets/stylesheets/page_bundles/prometheus.scss new file mode 100644 index 00000000000..055036d757d --- /dev/null +++ b/app/assets/stylesheets/page_bundles/prometheus.scss @@ -0,0 +1,116 @@ +@import 'mixins_and_variables_and_functions'; + +.prometheus-graphs { + .dropdown-buttons { + > div { + margin-left: auto; + } + } + + .col-form-label { + line-height: 1; + padding-top: 0; + } + + .form-group { + margin-bottom: map-get($spacing-scale, 3); + } + + .variables-section { + input { + @include media-breakpoint-up(sm) { + width: 160px; + } + } + } + + .links-section { + .gl-hover-text-blue-600-children:hover { + * { + @include gl-text-blue-600; + } + } + } +} + +.draggable { + &.draggable-enabled { + .draggable-panel { + border: $gray-100 1px solid; + border-radius: $border-radius-default; + margin: -1px; + cursor: grab; + } + + .prometheus-graph { + // Make dragging easier by disabling use of chart + pointer-events: none; + } + } + + &.sortable-chosen .draggable-panel { + background: $white; + box-shadow: 0 0 4px $gray-300; + } + + .draggable-remove { + z-index: 1; + + .draggable-remove-link { + cursor: pointer; + color: $gray-400; + background-color: $white; + } + } +} + +.prometheus-graphs-header { + .monitor-environment-dropdown-menu, + .monitor-dashboard-dropdown-menu { + &.show { + display: flex; + flex-direction: column; + overflow: hidden; + } + + .no-matches-message { + padding: $gl-padding-8 $gl-padding-12; + } + } + + .show-last-dropdown { + // same as in .dropdown-menu-toggle + // see app/assets/stylesheets/framework/dropdowns.scss + width: 160px; + } +} + +.prometheus-panel { + margin-top: 20px; +} + +.prometheus-graph-group { + display: flex; + flex-wrap: wrap; +} + +.prometheus-graph { + padding: $gl-padding-8; +} + +.alert-current-setting { + max-width: 240px; + + .badge.badge-danger { + color: $red-500; + background-color: $red-100; + } +} + +.prometheus-panel-builder { + .preview-date-time-picker { + // same as in .dropdown-menu-toggle + // see app/assets/stylesheets/framework/dropdowns.scss + width: 160px; + } +} diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index e77e30c532e..6070311dcb6 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -856,24 +856,6 @@ } } -.issuable-todo-btn { - .gl-spinner { - display: none; - } - - &.is-loading { - .gl-spinner { - display: inline-block; - } - - &.sidebar-collapsed-icon { - .issuable-todo-inner { - display: none; - } - } - } -} - /* * Following overrides are done to prevent * legacy dropdown styles from influencing @@ -932,85 +914,3 @@ } } } - -.icon-overlap-and-shadow { - filter: - drop-shadow(0 1px 0.5px #fff) - drop-shadow(1px 0 0.5px #fff) - drop-shadow(0 -1px 0.5px #fff) - drop-shadow(-1px 0 0.5px #fff); - margin-right: -7px; - z-index: 1; -} - -.issuable-discussion.incident-timeline-events { - .main-notes-list::before { - content: none; - } - - .timeline-event-note { - p { - margin-bottom: 0; - font-size: 0.875rem; - } - } -} - -/** - * We have a very specific design proposal where we cannot - * use `vertical-line` mixin as it is and have to use - * custom styles, see https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81284#note_904867444 - */ -.timeline-entry-vertical-line { - &::before, - &::after { - content: ''; - border-left: 2px solid $gray-50; - position: absolute; - left: 20px; - height: calc(100% + #{$gl-spacing-scale-5}); - top: -#{$gl-spacing-scale-5}; - } - - &:first-child::before { - content: none; - } - - &:first-child { - &::after { - top: $gl-spacing-scale-5; - height: calc(100% + #{$gl-spacing-scale-5}); - } - } - - &:last-child, - &.create-timeline-event { - &::before { - top: - #{$gl-spacing-scale-5} !important; // Override default positioning - @include gl-h-8; - } - - &::after { - content: none; - } - } -} - -.timeline-entry:not(:last-child) { - .timeline-event-border { - @include gl-pb-5; - @include gl-border-gray-50; - @include gl-border-1; - @include gl-border-b-solid; - } -} - -.timeline-group:last-child { - .timeline-entry:last-child, - .create-timeline-event { - .timeline-event-bottom-border { - @include gl-border-b; - @include gl-pt-5; - } - } -} diff --git a/app/assets/stylesheets/pages/prometheus.scss b/app/assets/stylesheets/pages/prometheus.scss deleted file mode 100644 index 71cbd7d9613..00000000000 --- a/app/assets/stylesheets/pages/prometheus.scss +++ /dev/null @@ -1,114 +0,0 @@ -.prometheus-graphs { - .dropdown-buttons { - > div { - margin-left: auto; - } - } - - .col-form-label { - line-height: 1; - padding-top: 0; - } - - .form-group { - margin-bottom: map-get($spacing-scale, 3); - } - - .variables-section { - input { - @include media-breakpoint-up(sm) { - width: 160px; - } - } - } - - .links-section { - .gl-hover-text-blue-600-children:hover { - * { - @include gl-text-blue-600; - } - } - } -} - -.draggable { - &.draggable-enabled { - .draggable-panel { - border: $gray-100 1px solid; - border-radius: $border-radius-default; - margin: -1px; - cursor: grab; - } - - .prometheus-graph { - // Make dragging easier by disabling use of chart - pointer-events: none; - } - } - - &.sortable-chosen .draggable-panel { - background: $white; - box-shadow: 0 0 4px $gray-300; - } - - .draggable-remove { - z-index: 1; - - .draggable-remove-link { - cursor: pointer; - color: $gray-400; - background-color: $white; - } - } -} - -.prometheus-graphs-header { - .monitor-environment-dropdown-menu, - .monitor-dashboard-dropdown-menu { - &.show { - display: flex; - flex-direction: column; - overflow: hidden; - } - - .no-matches-message { - padding: $gl-padding-8 $gl-padding-12; - } - } - - .show-last-dropdown { - // same as in .dropdown-menu-toggle - // see app/assets/stylesheets/framework/dropdowns.scss - width: 160px; - } -} - -.prometheus-panel { - margin-top: 20px; -} - -.prometheus-graph-group { - display: flex; - flex-wrap: wrap; -} - -.prometheus-graph { - padding: $gl-padding-8; -} - -.alert-current-setting { - max-width: 240px; - - .badge.badge-danger { - color: $red-500; - background-color: $red-100; - } -} - -.prometheus-panel-builder { - .preview-date-time-picker { - // same as in .dropdown-menu-toggle - // see app/assets/stylesheets/framework/dropdowns.scss - width: 160px; - } -} diff --git a/app/helpers/ci/pipeline_editor_helper.rb b/app/helpers/ci/pipeline_editor_helper.rb index d00301678dd..99a92ba9b59 100644 --- a/app/helpers/ci/pipeline_editor_helper.rb +++ b/app/helpers/ci/pipeline_editor_helper.rb @@ -11,7 +11,6 @@ module Ci def js_pipeline_editor_data(project) initial_branch = params[:branch_name] latest_commit = project.repository.commit(initial_branch) || project.commit - commit_sha = latest_commit ? latest_commit.sha : '' total_branches = project.repository_exists? ? project.repository.branch_count : 0 { @@ -27,17 +26,26 @@ module Ci "lint-unavailable-help-page-path" => help_page_path('ci/pipeline_editor/index', anchor: 'configuration-validation-currently-not-available-message'), "needs-help-page-path" => help_page_path('ci/yaml/index', anchor: 'needs'), "new-merge-request-path" => namespace_project_new_merge_request_path, - "pipeline_etag" => latest_commit ? graphql_etag_pipeline_sha_path(commit_sha) : '', + "pipeline_etag" => latest_commit ? graphql_etag_pipeline_sha_path(latest_commit.sha) : '', "pipeline-page-path" => project_pipelines_path(project), "project-path" => project.path, "project-full-path" => project.full_path, "project-namespace" => project.namespace.full_path, "simulate-pipeline-help-page-path" => help_page_path('ci/pipeline_editor/index', anchor: 'simulate-a-cicd-pipeline'), "total-branches" => total_branches, + "uses-external-config" => uses_external_config?(project) ? 'true' : 'false', "validate-tab-illustration-path" => image_path('illustrations/project-run-CICD-pipelines-sm.svg'), "yml-help-page-path" => help_page_path('ci/yaml/index') } end + + private + + def uses_external_config?(project) + ci_config_source = Gitlab::Ci::ProjectConfig.new(project: project, sha: nil).source + + [:external_project_source, :remote_source].include?(ci_config_source) + end end end diff --git a/app/helpers/ci/pipelines_helper.rb b/app/helpers/ci/pipelines_helper.rb index a67771116b9..c93c8dd8d76 100644 --- a/app/helpers/ci/pipelines_helper.rb +++ b/app/helpers/ci/pipelines_helper.rb @@ -69,7 +69,8 @@ module Ci end def has_pipeline_badges?(pipeline) - pipeline.child? || + pipeline.schedule? || + pipeline.child? || pipeline.latest? || pipeline.merge_train_pipeline? || pipeline.has_yaml_errors? || diff --git a/app/models/project.rb b/app/models/project.rb index aca61f645da..3d026351b4f 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -477,6 +477,7 @@ class Project < ApplicationRecord delegate :default_git_depth, :default_git_depth=, to: :ci_cd_settings, prefix: :ci, allow_nil: true delegate :forward_deployment_enabled, :forward_deployment_enabled=, to: :ci_cd_settings, prefix: :ci, allow_nil: true delegate :job_token_scope_enabled, :job_token_scope_enabled=, to: :ci_cd_settings, prefix: :ci, allow_nil: true + delegate :inbound_job_token_scope_enabled, :inbound_job_token_scope_enabled=, to: :ci_cd_settings, prefix: :ci, allow_nil: true delegate :keep_latest_artifact, :keep_latest_artifact=, to: :ci_cd_settings, allow_nil: true delegate :opt_in_jwt, :opt_in_jwt=, to: :ci_cd_settings, prefix: :ci, allow_nil: true delegate :allow_fork_pipelines_to_run_in_parent_project, :allow_fork_pipelines_to_run_in_parent_project=, to: :ci_cd_settings, prefix: :ci, allow_nil: true @@ -2720,6 +2721,7 @@ class Project < ApplicationRecord ci_config_path.blank? || ci_config_path == Gitlab::FileDetector::PATTERNS[:gitlab_ci] end + # DO NOT USE. This method will be deprecated soon def uses_external_project_ci_config? !!(ci_config_path =~ %r{@.+/.+}) end @@ -2844,6 +2846,7 @@ class Project < ApplicationRecord repository.gitlab_ci_yml_for(sha, ci_config_path_or_default) end + # DO NOT USE. This method will be deprecated soon def ci_config_external_project Project.find_by_full_path(ci_config_path.split('@', 2).last) end @@ -2892,6 +2895,12 @@ class Project < ApplicationRecord ci_cd_settings.job_token_scope_enabled? end + def ci_inbound_job_token_scope_enabled? + return false unless ci_cd_settings + + ci_cd_settings.inbound_job_token_scope_enabled? + end + def restrict_user_defined_variables? return false unless ci_cd_settings diff --git a/app/models/user.rb b/app/models/user.rb index 9fa9419cd37..d64a52ff7b9 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -235,6 +235,7 @@ class User < ApplicationRecord has_one :user_highest_role has_one :user_canonical_email has_one :credit_card_validation, class_name: '::Users::CreditCardValidation' + has_one :phone_number_validation, class_name: '::Users::PhoneNumberValidation' has_one :atlassian_identity, class_name: 'Atlassian::Identity' has_one :banned_user, class_name: '::Users::BannedUser' diff --git a/app/models/users/phone_number_validation.rb b/app/models/users/phone_number_validation.rb new file mode 100644 index 00000000000..f6123c01fd0 --- /dev/null +++ b/app/models/users/phone_number_validation.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module Users + class PhoneNumberValidation < ApplicationRecord + self.primary_key = :user_id + self.table_name = 'user_phone_number_validations' + + belongs_to :user, foreign_key: :user_id + belongs_to :banned_user, class_name: '::Users::BannedUser', foreign_key: :user_id + + validates :country, + presence: true, + length: { maximum: 3 } + + validates :international_dial_code, + presence: true, + numericality: { + only_integer: true, + greater_than_or_equal_to: 1, + less_than_or_equal_to: 999 + } + + validates :phone_number, + presence: true, + format: { + with: /\A\d+\Z/, + message: -> (object, data) { _('can contain only digits') } + }, + length: { maximum: 12 } + + validates :telesign_reference_xid, + length: { maximum: 255 } + + def self.related_to_banned_user?(international_dial_code, phone_number) + joins(:banned_user).where( + international_dial_code: international_dial_code, + phone_number: phone_number + ).exists? + end + end +end diff --git a/app/models/wiki.rb b/app/models/wiki.rb index fac79a8194a..afdac86d9c7 100644 --- a/app/models/wiki.rb +++ b/app/models/wiki.rb @@ -229,7 +229,7 @@ class Wiki find_page(SIDEBAR, version) end - def find_file(name, version = 'HEAD', load_content: true) + def find_file(name, version = default_branch, load_content: true) data_limit = load_content ? -1 : 0 blobs = repository.blobs_at([[version, name]], blob_size_limit: data_limit) @@ -423,7 +423,7 @@ class Wiki escaped_title = Regexp.escape(sluggified_title(title)) regex = Regexp.new("^#{escaped_title}\.#{ALLOWED_EXTENSIONS_REGEX}$", 'i') - repository.ls_files('HEAD').any? { |s| s =~ regex } + repository.ls_files(default_branch).any? { |s| s =~ regex } end def raise_duplicate_page_error! @@ -473,11 +473,11 @@ class Wiki end def check_page_historical(path, commit) - repository.last_commit_for_path('HEAD', path).id != commit.id + repository.last_commit_for_path(default_branch, path)&.id != commit&.id end def find_page_with_repository_rpcs(title, version, load_content: true) - version = version.presence || 'HEAD' + version = version.presence || default_branch path = find_matched_file(title, version) return if path.blank? @@ -493,7 +493,7 @@ class Wiki path: sluggified_title(path), raw_data: blob.data, name: canonicalize_filename(path), - historical: version == 'HEAD' ? false : check_page_historical(path, commit), + historical: version == default_branch ? false : check_page_historical(path, commit), version: Gitlab::Git::WikiPageVersion.new(commit, format) ) WikiPage.new(self, page) diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 63c60f5a89e..5cdd1fdadcb 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -138,7 +138,7 @@ class WikiPage default_per_page = Kaminari.config.default_per_page offset = [options[:page].to_i - 1, 0].max * options.fetch(:per_page, default_per_page) - wiki.repository.commits('HEAD', + wiki.repository.commits(wiki.default_branch, path: page.path, limit: options.fetch(:limit, default_per_page), offset: offset) @@ -147,7 +147,7 @@ class WikiPage def count_versions return [] unless persisted? - wiki.wiki.count_page_versions(page.path) + wiki.repository.count_commits(ref: wiki.default_branch, path: page.path) end def last_version diff --git a/app/uploaders/object_storage/cdn/google_cdn.rb b/app/uploaders/object_storage/cdn/google_cdn.rb index ea7683f131c..d34ed8ac897 100644 --- a/app/uploaders/object_storage/cdn/google_cdn.rb +++ b/app/uploaders/object_storage/cdn/google_cdn.rb @@ -41,7 +41,7 @@ module ObjectStorage private def config_valid? - [key_name, decoded_key, cdn_url].all?(&:present?) + [key_name, decoded_key, cdn_url].all?(&:present?) && cdn_url.start_with?('https://') end def key_name diff --git a/app/views/clusters/clusters/_health.html.haml b/app/views/clusters/clusters/_health.html.haml index 75609465eb3..50facdf91a2 100644 --- a/app/views/clusters/clusters/_health.html.haml +++ b/app/views/clusters/clusters/_health.html.haml @@ -1,3 +1,5 @@ +- add_page_specific_style 'page_bundles/prometheus' + %section.settings.no-animate.expanded.cluster-health-graphs.qa-cluster-health-section#cluster-health - if @cluster&.integration_prometheus_available? #prometheus-graphs{ data: @cluster.health_data(clusterable) } diff --git a/app/views/projects/blob/_blob.html.haml b/app/views/projects/blob/_blob.html.haml index 4139be053f8..9fd542e0cfb 100644 --- a/app/views/projects/blob/_blob.html.haml +++ b/app/views/projects/blob/_blob.html.haml @@ -10,7 +10,7 @@ %ul.blob-commit-info = render 'projects/commits/commit', commit: @last_commit, project: @project, ref: @ref - = render_if_exists 'projects/blob/owners', blob: blob + #js-code-owners{ data: { blob_path: blob.path, project_path: @project.full_path, branch: @ref } } = render "projects/blob/auxiliary_viewer", blob: blob #blob-content-holder.blob-content-holder diff --git a/app/views/projects/branch_rules/_show.html.haml b/app/views/projects/branch_rules/_show.html.haml index 46665fdb450..27525b441ab 100644 --- a/app/views/projects/branch_rules/_show.html.haml +++ b/app/views/projects/branch_rules/_show.html.haml @@ -9,4 +9,4 @@ = _('Define rules for who can push, merge, and the required approvals for each branch.') .settings-content.gl-pr-0 - #js-branch-rules{ data: { project_path: @project.full_path } } + #js-branch-rules{ data: { project_path: @project.full_path, branch_rules_path: project_settings_repository_branch_rules_path(@project) } } diff --git a/app/views/projects/environments/metrics.html.haml b/app/views/projects/environments/metrics.html.haml index cd7339edd1a..31041d124e4 100644 --- a/app/views/projects/environments/metrics.html.haml +++ b/app/views/projects/environments/metrics.html.haml @@ -1,3 +1,5 @@ +- add_page_specific_style 'page_bundles/prometheus' + - page_title _("Metrics Dashboard"), @environment.name .prometheus-container diff --git a/app/views/projects/incidents/show.html.haml b/app/views/projects/incidents/show.html.haml index 5043f94bd5c..7a1e7f503f8 100644 --- a/app/views/projects/incidents/show.html.haml +++ b/app/views/projects/incidents/show.html.haml @@ -2,6 +2,7 @@ - add_to_breadcrumbs _("Incidents"), project_incidents_path(@project) - breadcrumb_title @issue.to_reference - page_title "#{@issue.title} (#{@issue.to_reference})", _("Incidents") +- add_page_specific_style 'page_bundles/incidents' - add_page_specific_style 'page_bundles/issues_show' = render 'projects/issuable/show', issuable: @issue diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml index 06c422fc4d6..76b725d140c 100644 --- a/app/views/projects/issues/show.html.haml +++ b/app/views/projects/issues/show.html.haml @@ -2,6 +2,7 @@ - add_to_breadcrumbs _("Issues"), project_issues_path(@project) - breadcrumb_title @issue.to_reference - page_title "#{@issue.title} (#{@issue.to_reference})", _("Issues") +- add_page_specific_style 'page_bundles/incidents' - add_page_specific_style 'page_bundles/issues_show' - add_page_specific_style 'page_bundles/work_items' diff --git a/app/views/projects/mirrors/_authentication_method.html.haml b/app/views/projects/mirrors/_authentication_method.html.haml index 28b433b2514..4b549aaf1cd 100644 --- a/app/views/projects/mirrors/_authentication_method.html.haml +++ b/app/views/projects/mirrors/_authentication_method.html.haml @@ -3,12 +3,10 @@ .form-group = f.label :auth_method, _('Authentication method'), class: 'label-bold' - .select-wrapper - = f.select :auth_method, - options_for_select(auth_options, mirror.auth_method), - {}, { class: "form-control gl-form-select select-control js-mirror-auth-type qa-authentication-method" } - = sprite_icon('chevron-down', css_class: "gl-icon gl-absolute gl-top-3 gl-right-3 gl-text-gray-200") - = f.hidden_field :auth_method, value: "password", class: "js-hidden-mirror-auth-type" + = f.select :auth_method, + options_for_select(auth_options, mirror.auth_method), + {}, { class: "custom-select gl-form-select js-mirror-auth-type qa-authentication-method" } + = f.hidden_field :auth_method, value: "password", class: "js-hidden-mirror-auth-type" .form-group .well-password-auth.collapse.js-well-password-auth diff --git a/app/views/projects/pipelines/_info.html.haml b/app/views/projects/pipelines/_info.html.haml index 5db898067db..2e403358e2e 100644 --- a/app/views/projects/pipelines/_info.html.haml +++ b/app/views/projects/pipelines/_info.html.haml @@ -22,6 +22,8 @@ .well-segment.qa-pipeline-badges .icon-container = sprite_icon('flag', css_class: 'gl-top-0!') + - if @pipeline.schedule? + = gl_badge_tag _('Scheduled'), { variant: :info, size: :sm }, { class: 'js-pipeline-url-scheduled', title: _('This pipeline was triggered by a schedule.') } - if @pipeline.child? - text = sprintf(s_('Pipelines|Child pipeline (%{link_start}parent%{link_end})'), { link_start: "", link_end: ""}).html_safe = gl_badge_tag text, { variant: :info, size: :sm }, { class: 'js-pipeline-child has-tooltip', title: s_("Pipelines|This is a child pipeline within the parent pipeline") } diff --git a/app/views/projects/settings/branch_rules/index.html.haml b/app/views/projects/settings/branch_rules/index.html.haml index 84c060701bb..ab692a23e44 100644 --- a/app/views/projects/settings/branch_rules/index.html.haml +++ b/app/views/projects/settings/branch_rules/index.html.haml @@ -1,6 +1,6 @@ - add_to_breadcrumbs _('Repository Settings'), project_settings_repository_path(@project) - page_title s_('BranchRules|Branch rules details') -%h3= s_('BranchRules|Branch rules details') +%h3.gl-mb-5= s_('BranchRules|Branch rules details') -#js-branch-rules{ data: { project_path: @project.full_path } } +#js-branch-rules{ data: { project_path: @project.full_path, protected_branches_path: project_settings_repository_path(@project, anchor: 'js-protected-branches-settings') } } -- cgit v1.2.1