diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ef28900bc08..ae0f98192bf 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,6 +10,7 @@ stages: - review - qa - post-qa + - pre-merge - pages - notify - release-environments diff --git a/.gitlab/ci/pre-merge.gitlab-ci.yml b/.gitlab/ci/pre-merge.gitlab-ci.yml new file mode 100644 index 00000000000..e675472088a --- /dev/null +++ b/.gitlab/ci/pre-merge.gitlab-ci.yml @@ -0,0 +1,14 @@ +pre-merge-checks: + extends: + - .pre-merge:rules:pre-merge-checks + - .fast-no-clone-job + variables: + # We use > instead of | because we want the files to be space-separated. + FILES_TO_DOWNLOAD: > + scripts/utils.sh + scripts/pipeline/merge-train-checks.rb + image: ${GITLAB_DEPENDENCY_PROXY_ADDRESS}ruby:${RUBY_VERSION}-alpine3.16 + stage: pre-merge + script: + - install_gitlab_gem + - chmod u+x scripts/pipeline/merge-train-checks.rb && scripts/pipeline/merge-train-checks.rb diff --git a/.gitlab/ci/reports.gitlab-ci.yml b/.gitlab/ci/reports.gitlab-ci.yml index 6e1d749118c..f9bc5143836 100644 --- a/.gitlab/ci/reports.gitlab-ci.yml +++ b/.gitlab/ci/reports.gitlab-ci.yml @@ -144,7 +144,7 @@ xray_scan: - .reports:rules:x-ray stage: lint needs: [] - image: registry.gitlab.com/gitlab-org/code-creation/repository-x-ray:rc + image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/code-creation/repository-x-ray:rc variables: OUTPUT_DIR: reports allow_failure: true diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml index 03934f4ce51..6f2211db283 100644 --- a/.gitlab/ci/rules.gitlab-ci.yml +++ b/.gitlab/ci/rules.gitlab-ci.yml @@ -152,6 +152,9 @@ .if-dot-com-gitlab-org-merge-request: &if-dot-com-gitlab-org-merge-request if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE == "gitlab-org" && ($CI_MERGE_REQUEST_EVENT_TYPE == "merged_result" || $CI_MERGE_REQUEST_EVENT_TYPE == "detached")' +.if-dot-com-gitlab-org-and-subgroups-merge-train: &if-dot-com-gitlab-org-and-subgroups-merge-train + if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE =~ /^gitlab-org/ && $CI_MERGE_REQUEST_EVENT_TYPE == "merge_train"' + .if-dot-com-gitlab-org-ee-tag: &if-dot-com-gitlab-org-ee-tag if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_PATH == "gitlab-org/gitlab" && $CI_COMMIT_TAG =~ /^v?[\d]+\.[\d]+\.[\d]+[\d\w-]*-ee$/' @@ -943,7 +946,7 @@ rules: - if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_PATH == "gitlab-org/gitlab" && $CI_COMMIT_TAG =~ /^v\d+\.\d+\.0-ee$/ && $CI_PIPELINE_SOURCE == "push"' # In case gdk base tag is updated via backport mr, make sure we retag it with stable prefix as well - - if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_PATH == "gitlab-org/gitlab" && $CI_MERGE_REQUEST_IID && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^[\d-]+-stable-ee$/' + - if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_PATH == "gitlab-org/gitlab" && ($CI_MERGE_REQUEST_EVENT_TYPE == "merged_result" || $CI_MERGE_REQUEST_EVENT_TYPE == "detached") && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^[\d-]+-stable-ee$/' changes: - qa/gdk/Dockerfile.gdk @@ -3321,3 +3324,10 @@ changes: *ci-patterns when: manual allow_failure: true + +########################## +# Pre-merge checks rules # +########################## +.pre-merge:rules:pre-merge-checks: + rules: + - <<: *if-dot-com-gitlab-org-and-subgroups-merge-train diff --git a/.gitlab/ci/setup.gitlab-ci.yml b/.gitlab/ci/setup.gitlab-ci.yml index 30c2e23c1ad..f15b59c5217 100644 --- a/.gitlab/ci/setup.gitlab-ci.yml +++ b/.gitlab/ci/setup.gitlab-ci.yml @@ -73,7 +73,6 @@ set-pipeline-name: - apk add --no-cache --update curl # Not present in ruby-alpine, so we add it manually - !reference [".fast-no-clone-job", before_script] script: - - source scripts/utils.sh - install_gitlab_gem - chmod u+x scripts/pipeline/set_pipeline_name.rb && scripts/pipeline/set_pipeline_name.rb allow_failure: diff --git a/.gitlab/ci/test-on-cng/main.gitlab-ci.yml b/.gitlab/ci/test-on-cng/main.gitlab-ci.yml index 0c07556322c..48934476425 100644 --- a/.gitlab/ci/test-on-cng/main.gitlab-ci.yml +++ b/.gitlab/ci/test-on-cng/main.gitlab-ci.yml @@ -18,7 +18,7 @@ workflow: fi .cng-base: - image: registry.gitlab.com/gitlab-org/gitlab-build-images/${BUILD_OS}-${OS_VERSION}-ruby-${RUBY_VERSION}:bundler-${BUNDLER_VERSION}-git-2.36-lfs-2.9-chrome-${CHROME_VERSION}-docker-${DOCKER_VERSION}-kubectl-1.23-helm-3.14-kind-0.20 + image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images/${BUILD_OS}-${OS_VERSION}-ruby-${RUBY_VERSION}:bundler-${BUNDLER_VERSION}-git-2.36-lfs-2.9-chrome-${CHROME_VERSION}-docker-${DOCKER_VERSION}-kubectl-1.23-helm-3.14-kind-0.20 stage: test extends: .qa-cache needs: [build-cng] diff --git a/.rubocop_todo/layout/space_inside_parens.yml b/.rubocop_todo/layout/space_inside_parens.yml index 869488975ee..96cb5e4da19 100644 --- a/.rubocop_todo/layout/space_inside_parens.yml +++ b/.rubocop_todo/layout/space_inside_parens.yml @@ -13,7 +13,6 @@ Layout/SpaceInsideParens: - 'spec/helpers/gitlab_script_tag_helper_spec.rb' - 'spec/helpers/tab_helper_spec.rb' - 'spec/initializers/carrierwave_s3_encryption_headers_patch_spec.rb' - - 'spec/initializers/rdoc_segfault_patch_spec.rb' - 'spec/lib/api/entities/snippet_spec.rb' - 'spec/lib/banzai/filter/references/alert_reference_filter_spec.rb' - 'spec/lib/banzai/filter/references/feature_flag_reference_filter_spec.rb' diff --git a/.rubocop_todo/rspec/before_all_role_assignment.yml b/.rubocop_todo/rspec/before_all_role_assignment.yml index bc0b986fb69..22672916fcf 100644 --- a/.rubocop_todo/rspec/before_all_role_assignment.yml +++ b/.rubocop_todo/rspec/before_all_role_assignment.yml @@ -731,6 +731,7 @@ RSpec/BeforeAllRoleAssignment: - 'spec/controllers/groups/group_members_controller_spec.rb' - 'spec/controllers/groups/imports_controller_spec.rb' - 'spec/controllers/groups/labels_controller_spec.rb' + - 'spec/controllers/groups/milestones_controller_spec.rb' - 'spec/controllers/groups/settings/applications_controller_spec.rb' - 'spec/controllers/groups/settings/ci_cd_controller_spec.rb' - 'spec/controllers/groups/settings/integrations_controller_spec.rb' diff --git a/.rubocop_todo/rspec/feature_category.yml b/.rubocop_todo/rspec/feature_category.yml index 3f166567ede..3481b919e7f 100644 --- a/.rubocop_todo/rspec/feature_category.yml +++ b/.rubocop_todo/rspec/feature_category.yml @@ -2456,7 +2456,6 @@ RSpec/FeatureCategory: - 'spec/initializers/rack_multipart_patch_spec.rb' - 'spec/initializers/rails_asset_host_spec.rb' - 'spec/initializers/rails_yaml_safe_load_spec.rb' - - 'spec/initializers/rdoc_segfault_patch_spec.rb' - 'spec/initializers/remove_active_job_execute_callback_spec.rb' - 'spec/initializers/rest-client-hostname_override_spec.rb' - 'spec/initializers/sawyer_patch_spec.rb' diff --git a/.rubocop_todo/style/class_and_module_children.yml b/.rubocop_todo/style/class_and_module_children.yml index 810beef953d..c1b84b52112 100644 --- a/.rubocop_todo/style/class_and_module_children.yml +++ b/.rubocop_todo/style/class_and_module_children.yml @@ -333,7 +333,6 @@ Style/ClassAndModuleChildren: - 'config/initializers/omniauth.rb' - 'config/initializers/postgres_cte_as_materialized.rb' - 'config/initializers/postgresql_cte.rb' - - 'config/initializers/rdoc_segfault_patch.rb' - 'config/initializers/zz_metrics.rb' - 'ee/app/controllers/admin/audit_log_reports_controller.rb' - 'ee/app/controllers/admin/audit_logs_controller.rb' diff --git a/Gemfile.checksum b/Gemfile.checksum index fc67d9eaf39..6cf605d36ae 100644 --- a/Gemfile.checksum +++ b/Gemfile.checksum @@ -349,7 +349,7 @@ {"name":"kubeclient","version":"4.11.0","platform":"ruby","checksum":"4985fcd749fb8c364a668a8350a49821647f03aa52d9ee6cbc582beb8e883fcc"}, {"name":"language_server-protocol","version":"3.17.0.3","platform":"ruby","checksum":"3d5c58c02f44a20d972957a9febe386d7e7468ab3900ce6bd2b563dd910c6b3f"}, {"name":"launchy","version":"2.5.0","platform":"ruby","checksum":"954243c4255920982ce682f89a42e76372dba94770bf09c23a523e204bdebef5"}, -{"name":"lefthook","version":"1.6.8","platform":"ruby","checksum":"248181e8374ce9ef306a45fdbd3f64c076aaa4845cad6c126be4414b9c71c623"}, +{"name":"lefthook","version":"1.6.14","platform":"ruby","checksum":"78b51e17e9729c4ae0d9f9dfa0c67c7d9fa3f6651deb71419b4b4116f2367ce5"}, {"name":"letter_opener","version":"1.7.0","platform":"ruby","checksum":"095bc0d58e006e5b43ea7d219e64ecf2de8d1f7d9dafc432040a845cf59b4725"}, {"name":"letter_opener_web","version":"2.0.0","platform":"ruby","checksum":"33860ad41e1785d75456500e8ca8bba8ed71ee6eaf08a98d06bbab67c5577b6f"}, {"name":"libyajl2","version":"2.1.0","platform":"ruby","checksum":"aa5df6c725776fc050c8418450de0f7c129cb7200b811907c4c0b3b5c0aea0ef"}, diff --git a/Gemfile.lock b/Gemfile.lock index 76bc07f55d8..494e40217aa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1023,7 +1023,7 @@ GEM language_server-protocol (3.17.0.3) launchy (2.5.0) addressable (~> 2.7) - lefthook (1.6.8) + lefthook (1.6.14) letter_opener (1.7.0) launchy (~> 2.2) letter_opener_web (2.0.0) diff --git a/app/assets/javascripts/boards/components/board_card.vue b/app/assets/javascripts/boards/components/board_card.vue index ef1dd3a8bc0..73958b2cb99 100644 --- a/app/assets/javascripts/boards/components/board_card.vue +++ b/app/assets/javascripts/boards/components/board_card.vue @@ -71,13 +71,7 @@ export default { return !this.isDisabled; }, cardStyle() { - return this.isColorful && this.item.color ? { borderColor: this.item.color } : ''; - }, - isColorful() { - return gon?.features?.epicColorHighlight; - }, - colorClass() { - return this.isColorful ? 'gl-pl-4 gl-border-l-solid gl-border-4' : ''; + return this.item.color ? { borderColor: this.item.color } : ''; }, formattedItem() { return { @@ -147,7 +141,7 @@ export default { 'is-active gl-bg-blue-50': isActive, 'gl-cursor-not-allowed gl-bg-gray-10': item.isLoading, }, - colorClass, + 'gl-pl-4 gl-border-l-solid gl-border-4', ]" :index="index" :data-item-id="item.id" diff --git a/app/assets/javascripts/boards/components/board_list.vue b/app/assets/javascripts/boards/components/board_list.vue index 1739522c941..7eda83d8707 100644 --- a/app/assets/javascripts/boards/components/board_list.vue +++ b/app/assets/javascripts/boards/components/board_list.vue @@ -412,7 +412,6 @@ export default { boardId: this.boardId, itemToMove, }), - withColor: this.isEpicBoard && this.glFeatures.epicColorHighlight, }, update: (cache, { data: { issuableMoveList } }) => this.updateCacheAfterMovingItem({ @@ -505,7 +504,6 @@ export default { itemToMove: item, }), positionInList, - withColor: this.isEpicBoard && this.glFeatures.epicColorHighlight, }, optimisticResponse: { issuableMoveList: { @@ -558,7 +556,6 @@ export default { mutation: listIssuablesQueries[this.issuableType].createMutation, variables: { input: this.isEpicBoard ? input : { ...input, moveAfterId: this.boardListItems[0]?.id }, - withColor: this.isEpicBoard && this.glFeatures.epicColorHighlight, }, update: (cache, { data: { createIssuable } }) => { issuable = createIssuable.issuable; diff --git a/app/assets/javascripts/environments/environment_details/components/kubernetes/kubernetes_overview.vue b/app/assets/javascripts/environments/environment_details/components/kubernetes/kubernetes_overview.vue index a3ba24e329b..79469c931d1 100644 --- a/app/assets/javascripts/environments/environment_details/components/kubernetes/kubernetes_overview.vue +++ b/app/assets/javascripts/environments/environment_details/components/kubernetes/kubernetes_overview.vue @@ -7,7 +7,14 @@ import { helpPagePath } from '~/helpers/help_page_helper'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { k8sResourceType } from '~/environments/graphql/resolvers/kubernetes/constants'; import { createK8sAccessConfiguration } from '~/environments/helpers/k8s_integration_helper'; -import { CLUSTER_HEALTH_SUCCESS, CLUSTER_HEALTH_ERROR } from '~/environments/constants'; +import fluxKustomizationQuery from '~/environments/graphql/queries/flux_kustomization.query.graphql'; +import fluxHelmReleaseQueryStatus from '~/environments/graphql/queries/flux_helm_release_status.query.graphql'; +import { + CLUSTER_HEALTH_SUCCESS, + CLUSTER_HEALTH_ERROR, + HELM_RELEASES_RESOURCE_TYPE, + KUSTOMIZATIONS_RESOURCE_TYPE, +} from '~/environments/constants'; import KubernetesStatusBar from './kubernetes_status_bar.vue'; import KubernetesAgentInfo from './kubernetes_agent_info.vue'; import KubernetesTabs from './kubernetes_tabs.vue'; @@ -44,13 +51,49 @@ export default { default: '', }, }, - + apollo: { + fluxKustomization: { + query: fluxKustomizationQuery, + variables() { + return { + configuration: this.k8sAccessConfiguration, + fluxResourcePath: this.fluxResourcePath, + }; + }, + skip() { + return Boolean( + !this.fluxResourcePath || this.fluxResourcePath?.includes(HELM_RELEASES_RESOURCE_TYPE), + ); + }, + error(err) { + this.fluxApiError = err.message; + }, + }, + fluxHelmReleaseStatus: { + query: fluxHelmReleaseQueryStatus, + variables() { + return { + configuration: this.k8sAccessConfiguration, + fluxResourcePath: this.fluxResourcePath, + }; + }, + skip() { + return Boolean( + !this.fluxResourcePath || this.fluxResourcePath?.includes(KUSTOMIZATIONS_RESOURCE_TYPE), + ); + }, + error(err) { + this.fluxApiError = err.message; + }, + }, + }, data() { return { error: null, failedState: {}, podsLoading: false, activeTab: k8sResourceType.k8sPods, + fluxApiError: '', }; }, computed: { @@ -72,6 +115,9 @@ export default { hasFailedState() { return Object.values(this.failedState).some((item) => item); }, + fluxResourceStatus() { + return this.fluxKustomization?.conditions || this.fluxHelmReleaseStatus?.conditions; + }, }, methods: { handleError(message) { @@ -114,6 +160,8 @@ export default { :environment-name="environmentName" :flux-resource-path="fluxResourcePath" :resource-type="activeTab" + :flux-resource-status="fluxResourceStatus" + :flux-api-error="fluxApiError" @error="handleError" /> @@ -126,6 +174,7 @@ export default { v-model="activeTab" :configuration="k8sAccessConfiguration" :namespace="kubernetesNamespace" + :flux-kustomization="fluxKustomization" class="gl-mb-5" @cluster-error="handleError" @loading="podsLoading = $event" diff --git a/app/assets/javascripts/environments/environment_details/components/kubernetes/kubernetes_status_bar.vue b/app/assets/javascripts/environments/environment_details/components/kubernetes/kubernetes_status_bar.vue index cca5f0c8b9d..f2c1d0b2bdb 100644 --- a/app/assets/javascripts/environments/environment_details/components/kubernetes/kubernetes_status_bar.vue +++ b/app/assets/javascripts/environments/environment_details/components/kubernetes/kubernetes_status_bar.vue @@ -14,8 +14,6 @@ import { HELM_RELEASES_RESOURCE_TYPE, KUSTOMIZATIONS_RESOURCE_TYPE, } from '~/environments/constants'; -import fluxKustomizationStatusQuery from '~/environments/graphql/queries/flux_kustomization_status.query.graphql'; -import fluxHelmReleaseStatusQuery from '~/environments/graphql/queries/flux_helm_release_status.query.graphql'; import KubernetesConnectionStatus from '~/environments/environment_details/components/kubernetes/kubernetes_connection_status.vue'; import KubernetesConnectionStatusBadge from '~/environments/environment_details/components/kubernetes/kubernetes_connection_status_badge.vue'; import { @@ -64,46 +62,19 @@ export default { type: String, required: true, }, - }, - apollo: { - fluxKustomizationStatus: { - query: fluxKustomizationStatusQuery, - variables() { - return { - configuration: this.configuration, - fluxResourcePath: this.fluxResourcePath, - }; - }, - skip() { - return Boolean( - !this.fluxResourcePath || this.fluxResourcePath?.includes(HELM_RELEASES_RESOURCE_TYPE), - ); - }, - error(err) { - this.fluxApiError = err.message; - }, + fluxResourceStatus: { + type: Array, + required: false, + default: () => [], }, - fluxHelmReleaseStatus: { - query: fluxHelmReleaseStatusQuery, - variables() { - return { - configuration: this.configuration, - fluxResourcePath: this.fluxResourcePath, - }; - }, - skip() { - return Boolean( - !this.fluxResourcePath || this.fluxResourcePath?.includes(KUSTOMIZATIONS_RESOURCE_TYPE), - ); - }, - error(err) { - this.fluxApiError = err.message; - }, + fluxApiError: { + type: String, + required: false, + default: '', }, }, data() { return { - fluxApiError: '', clusterResourceTypeParams: { [k8sResourceType.k8sServices]: { resourceType: k8sResourceType.k8sServices, @@ -157,35 +128,16 @@ export default { healthBadge() { return HEALTH_BADGES[this.clusterHealthStatus]; }, - hasKustomizations() { - return this.fluxKustomizationStatus?.length; - }, - hasHelmReleases() { - return this.fluxHelmReleaseStatus?.length; - }, - isLoading() { - return ( - this.$apollo.queries.fluxKustomizationStatus.loading || - this.$apollo.queries.fluxHelmReleaseStatus.loading - ); - }, fluxBadgeId() { return `${this.environmentName}-flux-sync-badge`; }, - fluxCRD() { - if (!this.hasKustomizations && !this.hasHelmReleases) { - return []; - } - - return this.hasKustomizations ? this.fluxKustomizationStatus : this.fluxHelmReleaseStatus; - }, fluxAnyStalled() { - return this.fluxCRD.find((condition) => { + return this.fluxResourceStatus.find((condition) => { return condition.status === STATUS_TRUE && condition.type === 'Stalled'; }); }, fluxAnyReconcilingWithBadConfig() { - return this.fluxCRD.find((condition) => { + return this.fluxResourceStatus.find((condition) => { return ( condition.status === STATUS_UNKNOWN && condition.type === 'Ready' && @@ -194,25 +146,25 @@ export default { }); }, fluxAnyReconciling() { - return this.fluxCRD.find((condition) => { + return this.fluxResourceStatus.find((condition) => { return condition.status === STATUS_TRUE && condition.type === 'Reconciling'; }); }, fluxAnyReconciled() { - return this.fluxCRD.find((condition) => { + return this.fluxResourceStatus.find((condition) => { return condition.status === STATUS_TRUE && condition.type === 'Ready'; }); }, fluxAnyFailed() { - return this.fluxCRD.find((condition) => { + return this.fluxResourceStatus.find((condition) => { return condition.status === STATUS_FALSE && condition.type === 'Ready'; }); }, syncStatusBadge() { - if (!this.fluxCRD.length && this.fluxApiError) { + if (!this.fluxResourceStatus.length && this.fluxApiError) { return { ...SYNC_STATUS_BADGES.unavailable, popoverText: this.fluxApiError }; } - if (!this.fluxCRD.length) { + if (!this.fluxResourceStatus.length) { return SYNC_STATUS_BADGES.unavailable; } if (this.fluxAnyFailed) { diff --git a/app/assets/javascripts/environments/environment_details/components/kubernetes/kubernetes_summary.vue b/app/assets/javascripts/environments/environment_details/components/kubernetes/kubernetes_summary.vue index b5c3f5d860a..188656afe3c 100644 --- a/app/assets/javascripts/environments/environment_details/components/kubernetes/kubernetes_summary.vue +++ b/app/assets/javascripts/environments/environment_details/components/kubernetes/kubernetes_summary.vue @@ -1,4 +1,5 @@ diff --git a/app/assets/javascripts/environments/environment_details/components/kubernetes/kubernetes_tabs.vue b/app/assets/javascripts/environments/environment_details/components/kubernetes/kubernetes_tabs.vue index fee8ab57372..b9c0064a44d 100644 --- a/app/assets/javascripts/environments/environment_details/components/kubernetes/kubernetes_tabs.vue +++ b/app/assets/javascripts/environments/environment_details/components/kubernetes/kubernetes_tabs.vue @@ -34,6 +34,11 @@ export default { required: true, type: String, }, + fluxKustomization: { + required: false, + type: Object, + default: () => ({}), + }, }, data() { return { @@ -70,7 +75,7 @@ export default { diff --git a/app/assets/javascripts/repository/components/commit_info.vue b/app/assets/javascripts/repository/components/commit_info.vue index b338b5a868f..8fe7cafadca 100644 --- a/app/assets/javascripts/repository/components/commit_info.vue +++ b/app/assets/javascripts/repository/components/commit_info.vue @@ -94,7 +94,7 @@ export default { v-safe-html:[$options.safeHtmlConfig]="commit.titleHtml" :href="commit.webPath" :class="{ 'gl-italic': !commit.message }" - class="commit-row-message item-title gl-line-clamp-1 !gl-break-all" + class="commit-row-message item-title gl-line-clamp-1 gl-whitespace-normal !gl-break-all" />