diff options
26 files changed, 302 insertions, 111 deletions
diff --git a/app/assets/javascripts/lib/utils/datetime/date_format_utility.js b/app/assets/javascripts/lib/utils/datetime/date_format_utility.js index 5ec5c391964..0a35efb0ac8 100644 --- a/app/assets/javascripts/lib/utils/datetime/date_format_utility.js +++ b/app/assets/javascripts/lib/utils/datetime/date_format_utility.js @@ -299,8 +299,12 @@ export const dateToYearMonthDate = (date) => { // eslint-disable-next-line @gitlab/require-i18n-strings throw new Error('Argument should be a Date instance'); } - const [year, month, day] = date.toISOString().replace(/T.*$/, '').split('-'); - return { year, month, day }; + const [month, day] = padWithZeros(date.getMonth() + 1, date.getDate()); + return { + year: `${date.getFullYear()}`, + month, + day, + }; }; /** @@ -328,13 +332,15 @@ export const timeToHoursMinutes = (time = '') => { * @param {String} offset An optional Date-compatible offset. * @returns {String} The combined Date's ISO string representation. */ -export const dateAndTimeToUTCString = (date, time, offset = '') => { +export const dateAndTimeToISOString = (date, time, offset = '') => { const { year, month, day } = dateToYearMonthDate(date); const { hours, minutes } = timeToHoursMinutes(time); - - return new Date( - `${year}-${month}-${day}T${hours}:${minutes}:00.000${offset || 'Z'}`, - ).toISOString(); + const dateString = `${year}-${month}-${day}T${hours}:${minutes}:00.000${offset || 'Z'}`; + if (Number.isNaN(Date.parse(dateString))) { + // eslint-disable-next-line @gitlab/require-i18n-strings + throw new Error('Could not initialize date'); + } + return dateString; }; /** diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/pipeline_schedules_callout.vue b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/pipeline_schedules_callout.vue index 92b2bc9644b..42b08bcaa7b 100644 --- a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/pipeline_schedules_callout.vue +++ b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/pipeline_schedules_callout.vue @@ -53,7 +53,7 @@ Those scheduled pipelines will inherit limited project access based on their ass <p> {{ __('Learn more in the') }} <a :href="docsUrl" target="_blank" rel="nofollow"> - {{ s__('Learn more in the|pipeline schedules documentation') }}</a + {{ __('pipeline schedules documentation') }}</a >. <!-- oneline to prevent extra space before period --> </p> diff --git a/app/assets/javascripts/projects/storage_counter/components/app.vue b/app/assets/javascripts/projects/storage_counter/components/app.vue index 773459df14f..cfb08c11f0e 100644 --- a/app/assets/javascripts/projects/storage_counter/components/app.vue +++ b/app/assets/javascripts/projects/storage_counter/components/app.vue @@ -1,6 +1,7 @@ <script> import { GlAlert } from '@gitlab/ui'; import { s__ } from '~/locale'; +import UsageGraph from '~/vue_shared/components/storage_counter/usage_graph.vue'; import getProjectStorageCount from '../queries/project_storage.query.graphql'; import { parseGetProjectStorageResults } from '../utils'; @@ -8,6 +9,7 @@ export default { name: 'StorageCounterApp', components: { GlAlert, + UsageGraph, }, inject: ['projectPath'], apollo: { @@ -43,8 +45,13 @@ export default { }; </script> <template> - <gl-alert v-if="error" variant="danger" @dismiss="clearError"> - {{ error }} - </gl-alert> - <div v-else>{{ $options.i18n.placeholder }}</div> + <div> + <gl-alert v-if="error" variant="danger" @dismiss="clearError"> + {{ error }} + </gl-alert> + <div v-else>{{ $options.i18n.placeholder }}</div> + <div v-if="project.statistics" class="gl-w-full"> + <usage-graph :root-storage-statistics="project.statistics" :limit="0" /> + </div> + </div> </template> diff --git a/app/assets/javascripts/projects/storage_counter/utils.js b/app/assets/javascripts/projects/storage_counter/utils.js index 009aabbc221..cfc5f14b26a 100644 --- a/app/assets/javascripts/projects/storage_counter/utils.js +++ b/app/assets/javascripts/projects/storage_counter/utils.js @@ -60,5 +60,6 @@ export const parseGetProjectStorageResults = (data) => { totalUsage: numberToHumanSize(storageSize), storageTypes, }, + statistics: projectStatistics, }; }; diff --git a/app/assets/javascripts/vue_shared/components/timezone_dropdown.vue b/app/assets/javascripts/vue_shared/components/timezone_dropdown.vue index b9ee74d6a03..42334d80eec 100644 --- a/app/assets/javascripts/vue_shared/components/timezone_dropdown.vue +++ b/app/assets/javascripts/vue_shared/components/timezone_dropdown.vue @@ -66,7 +66,7 @@ export default { }; </script> <template> - <gl-dropdown :text="selectedTimezoneLabel" block lazy menu-class="gl-w-full!"> + <gl-dropdown :text="selectedTimezoneLabel" block lazy menu-class="gl-w-full!" v-bind="$attrs"> <gl-search-box-by-type v-model.trim="searchTerm" v-autofocusonshow autofocus /> <gl-dropdown-item v-for="timezone in filteredResults" diff --git a/app/models/namespaces/traversal/linear.rb b/app/models/namespaces/traversal/linear.rb index b17d4c5e26f..d7130322ed1 100644 --- a/app/models/namespaces/traversal/linear.rb +++ b/app/models/namespaces/traversal/linear.rb @@ -74,7 +74,7 @@ module Namespaces return super unless use_traversal_ids_for_root_ancestor? strong_memoize(:root_ancestor) do - if parent.nil? + if parent_id.nil? self else Namespace.find_by(id: traversal_ids.first) diff --git a/app/models/namespaces/traversal/recursive.rb b/app/models/namespaces/traversal/recursive.rb index c1ada715d6d..8d2c5d3be5a 100644 --- a/app/models/namespaces/traversal/recursive.rb +++ b/app/models/namespaces/traversal/recursive.rb @@ -7,12 +7,12 @@ module Namespaces include RecursiveScopes def root_ancestor - return self if parent.nil? - - if persisted? + if persisted? && !parent_id.nil? strong_memoize(:root_ancestor) do - recursive_self_and_ancestors.reorder(nil).find_by(parent_id: nil) + recursive_ancestors.reorder(nil).find_by(parent_id: nil) end + elsif parent.nil? + self else parent.root_ancestor end diff --git a/doc/api/access_requests.md b/doc/api/access_requests.md index 8ef3e882209..1634184a374 100644 --- a/doc/api/access_requests.md +++ b/doc/api/access_requests.md @@ -5,7 +5,7 @@ info: "To determine the technical writer assigned to the Stage/Group associated type: reference, api --- -# Group and project access requests API +# Group and project access requests API **(FREE)** > [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/18583) in GitLab 8.11. diff --git a/doc/api/api_resources.md b/doc/api/api_resources.md index 345f0d5ed70..8706b1e7e76 100644 --- a/doc/api/api_resources.md +++ b/doc/api/api_resources.md @@ -129,7 +129,7 @@ The following API resources are available outside of project and group contexts | Resource | Available endpoints | |:---------------------------------------------------|:------------------------------------------------------------------------| -| [Instance-level CI/CD variables](instance_level_ci_variables.md) | `/admin/ci/variables` | +| [Instance-level CI/CD variables](instance_level_ci_variables.md) **(FREE SELF)** | `/admin/ci/variables` | | [Sidekiq queues administration](admin_sidekiq_queues.md) **(FREE SELF)** | `/admin/sidekiq/queues/:queue_name` | | [Appearance](appearance.md) **(FREE SELF)** | `/application/appearance` | | [Applications](applications.md) | `/applications` | @@ -145,7 +145,7 @@ The following API resources are available outside of project and group contexts | [Group Activity Analytics](group_activity_analytics.md) | `/analytics/group_activity/{issues_count | merge_requests_count | new_members_count }` | | [Group repository storage moves](group_repository_storage_moves.md) **(PREMIUM SELF)** | `/group_repository_storage_moves` | | [Import repository from GitHub](import.md) | `/import/github` | -| [Instance clusters](instance_clusters.md) | `/admin/clusters` | +| [Instance clusters](instance_clusters.md) **(FREE SELF)** | `/admin/clusters` | | [Issues](issues.md) | `/issues` (also available for groups and projects) | | [Issues Statistics](issues_statistics.md) | `/issues_statistics` (also available for groups and projects) | | [Jobs](jobs.md) | `/job` | diff --git a/doc/api/applications.md b/doc/api/applications.md index 7047dccea88..2b5eff68010 100644 --- a/doc/api/applications.md +++ b/doc/api/applications.md @@ -4,7 +4,7 @@ group: Access info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments --- -# Applications API +# Applications API **(FREE)** > [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/8160) in GitLab 10.5. diff --git a/doc/api/avatar.md b/doc/api/avatar.md index baa670f3e93..200d7524b7f 100644 --- a/doc/api/avatar.md +++ b/doc/api/avatar.md @@ -4,7 +4,7 @@ group: Access info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments --- -# Avatar API +# Avatar API **(FREE)** > [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/19121) in GitLab 11.0. diff --git a/doc/api/award_emoji.md b/doc/api/award_emoji.md index dc3dc9fcaca..61f84dfb812 100644 --- a/doc/api/award_emoji.md +++ b/doc/api/award_emoji.md @@ -10,7 +10,7 @@ An [awarded emoji](../user/award_emojis.md) tells a thousand words. We call GitLab objects on which you can award an emoji "awardables". You can award emojis on the following: -- [Epics](../user/group/epics/index.md) ([API](epics.md)). +- [Epics](../user/group/epics/index.md) ([API](epics.md)). **(PREMIUM)** - [Issues](../user/project/issues/index.md) ([API](issues.md)). - [Merge requests](../user/project/merge_requests/index.md) ([API](merge_requests.md)). - [Snippets](../user/snippets.md) ([API](snippets.md)). diff --git a/doc/development/stage_group_dashboards.md b/doc/development/stage_group_dashboards.md index 61a98ece892..7c518e9b6ca 100644 --- a/doc/development/stage_group_dashboards.md +++ b/doc/development/stage_group_dashboards.md @@ -56,7 +56,7 @@ component can have 2 indicators: [Git](https://gitlab.com/gitlab-com/runbooks/-/blob/f22f40b2c2eab37d85e23ccac45e658b2c914445/metrics-catalog/services/git.jsonnet#L216), and [Web](https://gitlab.com/gitlab-com/runbooks/-/blob/f22f40b2c2eab37d85e23ccac45e658b2c914445/metrics-catalog/services/web.jsonnet#L154) - services, that threshold is **1 second**. + services, that threshold is **5 seconds**. For Sidekiq job execution, the threshold depends on the [job urgency](sidekiq_style_guide.md#job-urgency). It is diff --git a/doc/user/project/settings/index.md b/doc/user/project/settings/index.md index 58d902f5b40..edfa12b9843 100644 --- a/doc/user/project/settings/index.md +++ b/doc/user/project/settings/index.md @@ -196,23 +196,24 @@ to **Only Project Members**. In addition, you can select the option to Use the switches to enable or disable the following features: -| Option | More access limit options | Description | -|:----------------------------------|:--------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **Issues** | ✓ | Activates the GitLab issues tracker | -| **Repository** | ✓ | Enables [repository](../repository/) functionality | -| **Merge Requests** | ✓ | Enables [merge request](../merge_requests/) functionality; also see [Merge request settings](#merge-request-settings) | -| **Forks** | ✓ | Enables [forking](../repository/forking_workflow.md) functionality | -| **Pipelines** | ✓ | Enables [CI/CD](../../../ci/index.md) functionality | -| **Container Registry** | | Activates a [registry](../../packages/container_registry/) for your Docker images | -| **Git Large File Storage** | | Enables the use of [large files](../../../topics/git/lfs/index.md#git-large-file-storage-lfs) | -| **Packages** | | Supports configuration of a [package registry](../../../administration/packages/index.md#gitlab-package-registry-administration) functionality | -| **Analytics** | ✓ | Enables [analytics](../../analytics/) | -| **Wiki** | ✓ | Enables a separate system for [documentation](../wiki/) | -| **Snippets** | ✓ | Enables [sharing of code and text](../../snippets.md) | -| **Pages** | ✓ | Allows you to [publish static websites](../pages/) | -| **Metrics Dashboard** | ✓ | Control access to [metrics dashboard](../integrations/prometheus.md) -| **Requirements** | ✓ | Control access to [Requirements Management](../requirements/index.md) | -| **Operations Dashboard** | ✓ | Control access to [operations dashboard](../../../operations/index.md) +| Option | More access limit options | Description | +|:---------------------------------|:--------------------------|:--------------| +| **Issues** | ✓ | Activates the GitLab issues tracker. | +| **Repository** | ✓ | Enables [repository](../repository/) functionality | +| **Merge Requests** | ✓ | Enables [merge request](../merge_requests/) functionality; also see [Merge request settings](#merge-request-settings). | +| **Forks** | ✓ | Enables [forking](../repository/forking_workflow.md) functionality. | +| **Git Large File Storage (LFS)** | | Enables the use of [large files](../../../topics/git/lfs/index.md#git-large-file-storage-lfs). | +| **Packages** | | Supports configuration of a [package registry](../../../administration/packages/index.md#gitlab-package-registry-administration) functionality. | +| **CI/CD** | ✓ | Enables [CI/CD](../../../ci/index.md) functionality. | +| **Container Registry** | | Activates a [registry](../../packages/container_registry/) for your Docker images. | +| **Analytics** | ✓ | Enables [analytics](../../analytics/). | +| **Requirements** | ✓ | Control access to [Requirements Management](../requirements/index.md). | +| **Security & Compliance** | ✓ | Control access to [security features](../../application_security/index.md). | +| **Wiki** | ✓ | Enables a separate system for [documentation](../wiki/). | +| **Snippets** | ✓ | Enables [sharing of code and text](../../snippets.md). | +| **Pages** | ✓ | Allows you to [publish static websites](../pages/). | +| **Operations** | ✓ | Control access to [operations dashboard](../../../operations/index.md). | +| **Metrics Dashboard** | ✓ | Control access to [metrics dashboard](../integrations/prometheus.md). | Some features depend on others: @@ -232,7 +233,7 @@ Some features depend on others: - If you disable **Repository** functionality, GitLab also disables the following features for your project: - **Merge Requests** - - **Pipelines** + - **CI/CD** - **Container Registry** - **Git Large File Storage** - **Packages** diff --git a/lib/gitlab/ci/templates/Android.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Android.latest.gitlab-ci.yml new file mode 100644 index 00000000000..9f0e9bcc1f2 --- /dev/null +++ b/lib/gitlab/ci/templates/Android.latest.gitlab-ci.yml @@ -0,0 +1,87 @@ +# To contribute improvements to CI/CD templates, please follow the Development guide at: +# https://docs.gitlab.com/ee/development/cicd/templates.html +# This specific template is located at: +# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Android.gitlab-ci.yml + +# Read more about this script on this blog post https://about.gitlab.com/2018/10/24/setting-up-gitlab-ci-for-android-projects/, by Jason Lenny +# If you are interested in using Android with FastLane for publishing take a look at the Android-Fastlane template. + +image: openjdk:11-jdk + +variables: + + # ANDROID_COMPILE_SDK is the version of Android you're compiling with. + # It should match compileSdkVersion. + ANDROID_COMPILE_SDK: "30" + + # ANDROID_BUILD_TOOLS is the version of the Android build tools you are using. + # It should match buildToolsVersion. + ANDROID_BUILD_TOOLS: "30.0.3" + + # It's what version of the command line tools we're going to download from the official site. + # Official Site-> https://developer.android.com/studio/index.html + # There, look down below at the cli tools only, sdk tools package is of format: + # commandlinetools-os_type-ANDROID_SDK_TOOLS_latest.zip + # when the script was last modified for latest compileSdkVersion, it was which is written down below + ANDROID_SDK_TOOLS: "7583922" + +# Packages installation before running script +before_script: + - apt-get --quiet update --yes + - apt-get --quiet install --yes wget tar unzip lib32stdc++6 lib32z1 + + # Setup path as ANDROID_SDK_ROOT for moving/exporting the downloaded sdk into it + - export ANDROID_SDK_ROOT="${PWD}/android-home" + # Create a new directory at specified location + - install -d $ANDROID_SDK_ROOT + # Here we are installing androidSDK tools from official source, + # (the key thing here is the url from where you are downloading these sdk tool for command line, so please do note this url pattern there and here as well) + # after that unzipping those tools and + # then running a series of SDK manager commands to install necessary android SDK packages that'll allow the app to build + - wget --output-document=$ANDROID_SDK_ROOT/cmdline-tools.zip https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_TOOLS}_latest.zip + # move to the archive at ANDROID_SDK_ROOT + - pushd $ANDROID_SDK_ROOT + - unzip -d cmdline-tools cmdline-tools.zip + - pushd cmdline-tools + # since commandline tools version 7583922 the root folder is named "cmdline-tools" so we rename it if necessary + - mv cmdline-tools tools || true + - popd + - popd + - export PATH=$PATH:${ANDROID_SDK_ROOT}/cmdline-tools/tools/bin/ + + # Nothing fancy here, just checking sdkManager version + - sdkmanager --version + + # use yes to accept all licenses + - yes | sdkmanager --licenses || true + - sdkmanager "platforms;android-${ANDROID_COMPILE_SDK}" + - sdkmanager "platform-tools" + - sdkmanager "build-tools;${ANDROID_BUILD_TOOLS}" + + # Not necessary, but just for surity + - chmod +x ./gradlew + +# Basic android and gradle stuff +# Check linting +lintDebug: + interruptible: true + stage: build + script: + - ./gradlew -Pci --console=plain :app:lintDebug -PbuildDir=lint + +# Make Project +assembleDebug: + interruptible: true + stage: build + script: + - ./gradlew assembleDebug + artifacts: + paths: + - app/build/outputs/ + +# Run all tests, if any fails, interrupt the pipeline(fail it) +debugTests: + interruptible: true + stage: test + script: + - ./gradlew -Pci --console=plain :app:testDebug diff --git a/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml index a9f6fd88d0b..3e7fa579595 100644 --- a/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml @@ -16,6 +16,9 @@ stages: init: extends: .terraform:init +fmt: + extends: .terraform:fmt + validate: extends: .terraform:validate diff --git a/lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml index c30860ad174..b3cbf6a0b85 100644 --- a/lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml @@ -28,6 +28,14 @@ cache: - cd ${TF_ROOT} - gitlab-terraform init +.terraform:fmt: &terraform_fmt + stage: validate + needs: [] + script: + - cd ${TF_ROOT} + - gitlab-terraform fmt -check -recursive + allow_failure: true + .terraform:validate: &terraform_validate stage: validate script: diff --git a/lib/gitlab/database/connection.rb b/lib/gitlab/database/connection.rb index 69ef77c63d2..348b7207b23 100644 --- a/lib/gitlab/database/connection.rb +++ b/lib/gitlab/database/connection.rb @@ -88,7 +88,16 @@ module Gitlab # Disables prepared statements for the current database connection. def disable_prepared_statements - scope.establish_connection(config.merge(prepared_statements: false)) + db_config_object = scope.connection_db_config + config = db_config_object.configuration_hash.merge(prepared_statements: false) + + hash_config = ActiveRecord::DatabaseConfigurations::HashConfig.new( + db_config_object.env_name, + db_config_object.name, + config + ) + + scope.establish_connection(hash_config) end # Check whether the underlying database is in read-only mode diff --git a/locale/gitlab.pot b/locale/gitlab.pot index f9d9a219e3c..a97d4bd1eb4 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -13495,6 +13495,12 @@ msgstr "" msgid "Every %{action} attempt has failed: %{job_error_message}. Please try again." msgstr "" +msgid "Every 3 months" +msgstr "" + +msgid "Every 6 months" +msgstr "" + msgid "Every day" msgstr "" @@ -13521,6 +13527,9 @@ msgstr[1] "" msgid "Every week (%{weekday} at %{time})" msgstr "" +msgid "Every year" +msgstr "" + msgid "Everyone" msgstr "" @@ -19821,9 +19830,6 @@ msgstr "" msgid "Learn more in the" msgstr "" -msgid "Learn more in the|pipeline schedules documentation" -msgstr "" - msgid "Learn more." msgstr "" @@ -23445,12 +23451,18 @@ msgstr "" msgid "OnDemandScans|Scanner profile" msgstr "" +msgid "OnDemandScans|Schedule scan" +msgstr "" + msgid "OnDemandScans|Select one of the existing profiles" msgstr "" msgid "OnDemandScans|Site profile" msgstr "" +msgid "OnDemandScans|Start time" +msgstr "" + msgid "OnDemandScans|Use existing scanner profile" msgstr "" @@ -28098,6 +28110,9 @@ msgstr "" msgid "Reopens this %{quick_action_target}." msgstr "" +msgid "Repeats" +msgstr "" + msgid "Replace" msgstr "" @@ -40338,6 +40353,9 @@ msgstr "" msgid "pipeline" msgstr "" +msgid "pipeline schedules documentation" +msgstr "" + msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character" msgstr "" diff --git a/package.json b/package.json index 88ebd34a813..964ec8bb742 100644 --- a/package.json +++ b/package.json @@ -61,16 +61,16 @@ "@rails/ujs": "6.1.3-2", "@sentry/browser": "5.30.0", "@sourcegraph/code-host-integration": "0.0.60", - "@tiptap/core": "^2.0.0-beta.102", + "@tiptap/core": "^2.0.0-beta.103", "@tiptap/extension-blockquote": "^2.0.0-beta.15", "@tiptap/extension-bold": "^2.0.0-beta.15", "@tiptap/extension-bullet-list": "^2.0.0-beta.15", "@tiptap/extension-code": "^2.0.0-beta.16", - "@tiptap/extension-code-block-lowlight": "2.0.0-beta.35", + "@tiptap/extension-code-block-lowlight": "2.0.0-beta.36", "@tiptap/extension-document": "^2.0.0-beta.13", "@tiptap/extension-dropcursor": "^2.0.0-beta.19", "@tiptap/extension-gapcursor": "^2.0.0-beta.19", - "@tiptap/extension-hard-break": "^2.0.0-beta.15", + "@tiptap/extension-hard-break": "^2.0.0-beta.16", "@tiptap/extension-heading": "^2.0.0-beta.15", "@tiptap/extension-history": "^2.0.0-beta.16", "@tiptap/extension-horizontal-rule": "^2.0.0-beta.19", @@ -83,14 +83,14 @@ "@tiptap/extension-strike": "^2.0.0-beta.17", "@tiptap/extension-subscript": "^2.0.0-beta.4", "@tiptap/extension-superscript": "^2.0.0-beta.4", - "@tiptap/extension-table": "^2.0.0-beta.29", + "@tiptap/extension-table": "^2.0.0-beta.30", "@tiptap/extension-table-cell": "^2.0.0-beta.14", "@tiptap/extension-table-header": "^2.0.0-beta.16", "@tiptap/extension-table-row": "^2.0.0-beta.14", "@tiptap/extension-task-item": "^2.0.0-beta.17", "@tiptap/extension-task-list": "^2.0.0-beta.17", "@tiptap/extension-text": "^2.0.0-beta.13", - "@tiptap/vue-2": "^2.0.0-beta.48", + "@tiptap/vue-2": "^2.0.0-beta.49", "@toast-ui/editor": "^2.5.2", "@toast-ui/vue-editor": "^2.5.2", "apollo-cache-inmemory": "^1.6.6", diff --git a/spec/frontend/lib/utils/datetime/date_format_utility_spec.js b/spec/frontend/lib/utils/datetime/date_format_utility_spec.js index ec3574c1d86..942ba56196e 100644 --- a/spec/frontend/lib/utils/datetime/date_format_utility_spec.js +++ b/spec/frontend/lib/utils/datetime/date_format_utility_spec.js @@ -69,35 +69,35 @@ describe('date_format_utility.js', () => { }); }); - describe('dateAndTimeToUTCString', () => { + describe('dateAndTimeToISOString', () => { it('computes the date properly', () => { - expect(utils.dateAndTimeToUTCString(new Date('2021-08-16'), '10:00')).toBe( + expect(utils.dateAndTimeToISOString(new Date('2021-08-16'), '10:00')).toBe( '2021-08-16T10:00:00.000Z', ); }); it('computes the date properly with an offset', () => { - expect(utils.dateAndTimeToUTCString(new Date('2021-08-16'), '10:00', '-04:00')).toBe( - '2021-08-16T14:00:00.000Z', + expect(utils.dateAndTimeToISOString(new Date('2021-08-16'), '10:00', '-04:00')).toBe( + '2021-08-16T10:00:00.000-04:00', ); }); it('throws if date in invalid', () => { - expect(() => utils.dateAndTimeToUTCString('Invalid date', '10:00')).toThrow( + expect(() => utils.dateAndTimeToISOString('Invalid date', '10:00')).toThrow( 'Argument should be a Date instance', ); }); it('throws if time in invalid', () => { - expect(() => utils.dateAndTimeToUTCString(new Date('2021-08-16'), '')).toThrow( + expect(() => utils.dateAndTimeToISOString(new Date('2021-08-16'), '')).toThrow( 'Invalid time provided', ); }); it('throws if offset is invalid', () => { expect(() => - utils.dateAndTimeToUTCString(new Date('2021-08-16'), '10:00', 'not an offset'), - ).toThrow('Invalid time value'); + utils.dateAndTimeToISOString(new Date('2021-08-16'), '10:00', 'not an offset'), + ).toThrow('Could not initialize date'); }); }); diff --git a/spec/frontend/projects/storage_counter/app_spec.js b/spec/frontend/projects/storage_counter/app_spec.js index 9b044350b10..db099527015 100644 --- a/spec/frontend/projects/storage_counter/app_spec.js +++ b/spec/frontend/projects/storage_counter/app_spec.js @@ -4,18 +4,18 @@ import VueApollo from 'vue-apollo'; import createMockApollo from 'helpers/mock_apollo_helper'; import StorageCounterApp from '~/projects/storage_counter/components/app.vue'; import getProjectStorageCount from '~/projects/storage_counter/queries/project_storage.query.graphql'; +import UsageGraph from '~/vue_shared/components/storage_counter/usage_graph.vue'; +import { projectStorageCountResponse } from './mock_data'; const localVue = createLocalVue(); describe('Storage counter app', () => { let wrapper; - const createMockApolloProvider = () => { + const createMockApolloProvider = ({ mutationMock }) => { localVue.use(VueApollo); - const requestHandlers = [ - [getProjectStorageCount, jest.fn().mockRejectedValue(new Error('GraphQL error'))], - ]; + const requestHandlers = [[getProjectStorageCount, mutationMock]]; return createMockApollo(requestHandlers); }; @@ -36,6 +36,7 @@ describe('Storage counter app', () => { }; const findAlert = () => wrapper.findComponent(GlAlert); + const findUsageGraph = () => wrapper.findComponent(UsageGraph); beforeEach(() => { createComponent(); @@ -50,10 +51,10 @@ describe('Storage counter app', () => { }); describe('handling apollo fetching error', () => { - let mockApollo; + const mutationMock = jest.fn().mockRejectedValue(new Error('GraphQL error')); beforeEach(() => { - mockApollo = createMockApolloProvider(); + const mockApollo = createMockApolloProvider({ mutationMock }); createComponent({ mockApollo }); }); @@ -61,4 +62,22 @@ describe('Storage counter app', () => { expect(findAlert().exists()).toBe(true); }); }); + + describe('rendering <usage-graph />', () => { + const mutationMock = jest.fn().mockResolvedValue(projectStorageCountResponse); + + beforeEach(() => { + const mockApollo = createMockApolloProvider({ mutationMock }); + createComponent({ mockApollo }); + }); + + it('renders usage-graph component if project.statistics exists', () => { + expect(findUsageGraph().exists()).toBe(true); + }); + + it('passes project.statistics to usage-graph component', () => { + const { __typename, ...statistics } = projectStorageCountResponse.data.project.statistics; + expect(findUsageGraph().props('rootStorageStatistics')).toMatchObject(statistics); + }); + }); }); diff --git a/spec/frontend/projects/storage_counter/mock_data.js b/spec/frontend/projects/storage_counter/mock_data.js new file mode 100644 index 00000000000..27c576a0619 --- /dev/null +++ b/spec/frontend/projects/storage_counter/mock_data.js @@ -0,0 +1,19 @@ +export const projectStorageCountResponse = { + data: { + project: { + id: 'gid://gitlab/Project/20', + statistics: { + buildArtifactsSize: 400000, + lfsObjectsSize: 4800000, + packagesSize: 3800000, + repositorySize: 39000000, + snippetsSize: 0, + storageSize: 39930000, + uploadsSize: 0, + wikiSize: 300000, + __typename: 'ProjectStatistics', + }, + __typename: 'Project', + }, + }, +}; diff --git a/spec/lib/gitlab/database/connection_spec.rb b/spec/lib/gitlab/database/connection_spec.rb index 905f2a419ac..4d1e78fe425 100644 --- a/spec/lib/gitlab/database/connection_spec.rb +++ b/spec/lib/gitlab/database/connection_spec.rb @@ -162,6 +162,12 @@ RSpec.describe Gitlab::Database::Connection do expect(connection.scope.connection.prepared_statements).to eq(false) end + it 'retains the connection name' do + connection.disable_prepared_statements + + expect(connection.scope.connection_db_config.name).to eq('main') + end + context 'with dynamic connection pool size' do before do connection.scope.establish_connection(connection.config.merge(pool: 7)) diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb index e2700378f5f..434e4382dd5 100644 --- a/spec/models/namespace_spec.rb +++ b/spec/models/namespace_spec.rb @@ -1377,6 +1377,13 @@ RSpec.describe Namespace do expect { root_group.root_ancestor }.not_to exceed_query_limit(0) end + it 'returns root_ancestor for nested group with a single query' do + nested_group = create(:group, parent: root_group) + nested_group.reload + + expect { nested_group.root_ancestor }.not_to exceed_query_limit(1) + end + it 'returns the top most ancestor' do nested_group = create(:group, parent: root_group) deep_nested_group = create(:group, parent: nested_group) diff --git a/yarn.lock b/yarn.lock index f9f67aba5ed..eae5144d50e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1467,10 +1467,10 @@ dom-accessibility-api "^0.5.1" pretty-format "^26.4.2" -"@tiptap/core@^2.0.0-beta.102": - version "2.0.0-beta.102" - resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.0.0-beta.102.tgz#14afa2f00bef254ee34d78646a597269dd98dc8a" - integrity sha512-ykSAyYfyb14xiYWQ6mTaa+GF6j5dQvSDgeXQDNcy8xvBjZHm1g+51D0jm9FF/dsrY0rEps5h8yX883h7MaGFHA== +"@tiptap/core@^2.0.0-beta.103": + version "2.0.0-beta.103" + resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.0.0-beta.103.tgz#f88f0217a26a3dc5413f44ffff246c4692709afb" + integrity sha512-tCU94zEJgv/mADMZ0dM1/+23uJoc2YyrRauEekt6Yd44TdPTJSDk7v82GJdmMLWj5mDjLbXVL7kvrJpi0/4zjg== dependencies: "@types/prosemirror-commands" "^1.0.4" "@types/prosemirror-inputrules" "^1.0.4" @@ -1479,7 +1479,7 @@ "@types/prosemirror-schema-list" "^1.0.3" "@types/prosemirror-state" "^1.2.7" "@types/prosemirror-transform" "^1.1.4" - "@types/prosemirror-view" "^1.17.2" + "@types/prosemirror-view" "^1.19.0" prosemirror-commands "^1.1.10" prosemirror-inputrules "^1.1.3" prosemirror-keymap "^1.1.3" @@ -1487,7 +1487,7 @@ prosemirror-schema-list "^1.1.5" prosemirror-state "^1.3.4" prosemirror-transform "^1.3.2" - prosemirror-view "^1.19.3" + prosemirror-view "^1.20.0" "@tiptap/extension-blockquote@^2.0.0-beta.15": version "2.0.0-beta.15" @@ -1501,13 +1501,13 @@ resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-2.0.0-beta.15.tgz#cf9ddb3fc316be9707753ad4e497bfb8a3ebb0c2" integrity sha512-jKyV6iiwhxwa0+7uuKD74jNDVNLNOS1GmU14MgaA95pY5e1fyaRBPPX8Gtt89niz2CLOY711AV17RPZTe/e60w== -"@tiptap/extension-bubble-menu@^2.0.0-beta.31": - version "2.0.0-beta.31" - resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.0.0-beta.31.tgz#0bf1bf3bc9d1e89830abe0af2f6796bcda87d66a" - integrity sha512-O0U12A+4tWZo97MRWOhGrZ+Z0DWYHPzLP3rbUMl1bClvOoggKgMZnSdvgjC7LmP5h/8Y+qB92swk5LVYvrOcDQ== +"@tiptap/extension-bubble-menu@^2.0.0-beta.32": + version "2.0.0-beta.32" + resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.0.0-beta.32.tgz#5f9358c775760bac057c444c1a52a3bfe54358e5" + integrity sha512-ZrP7yoYBTEZZg5L612jIRzGwwmuV5Jf68cHlPaMY4R11F5wn2Z+J/v+QcJUuRxEtIraUFnL03IV0VWJC7gUMSg== dependencies: prosemirror-state "^1.3.4" - prosemirror-view "^1.19.3" + prosemirror-view "^1.20.0" tippy.js "^6.3.1" "@tiptap/extension-bullet-list@^2.0.0-beta.15": @@ -1517,17 +1517,17 @@ dependencies: prosemirror-inputrules "^1.1.3" -"@tiptap/extension-code-block-lowlight@2.0.0-beta.35": - version "2.0.0-beta.35" - resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block-lowlight/-/extension-code-block-lowlight-2.0.0-beta.35.tgz#a08e98d7c2fcc4a80f927766842bfc9980e5b55e" - integrity sha512-lPjrZg9bJp83O7EJaDU2Ial15JU0SNX9zbXpdpatbzxFOKsXpgMuRPrYxMYelbIq2XuhEOdu/Q9cc6+vtqmfFQ== +"@tiptap/extension-code-block-lowlight@2.0.0-beta.36": + version "2.0.0-beta.36" + resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block-lowlight/-/extension-code-block-lowlight-2.0.0-beta.36.tgz#f4d5fed298d376fb2dc33955a67e55ebcb04bc8d" + integrity sha512-Z/Oza3eaBJKYcE76d0zU5ScnQU31KAmzwb16G+lUKU5oYxGvWWLgseYiHdU1oQinf9FC1c7asMwI6x3ydkKIlA== dependencies: "@tiptap/extension-code-block" "^2.0.0-beta.17" "@types/lowlight" "^0.0.3" lowlight "^1.20.0" prosemirror-model "^1.14.3" prosemirror-state "^1.3.4" - prosemirror-view "^1.19.3" + prosemirror-view "^1.20.0" "@tiptap/extension-code-block@^2.0.0-beta.17": version "2.0.0-beta.17" @@ -1554,13 +1554,13 @@ "@types/prosemirror-dropcursor" "^1.0.3" prosemirror-dropcursor "^1.3.5" -"@tiptap/extension-floating-menu@^2.0.0-beta.25": - version "2.0.0-beta.25" - resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-2.0.0-beta.25.tgz#9b8dcbdd6f844d077483d6c631800c29f57273e6" - integrity sha512-nXBi1eA3Kji8tk+gOIyxXKsaTpGBgXSX9hHTgIvbBMMvfP9onLKuZIAKG/cBUMBzt+CKns1XooE71UqyMESDhQ== +"@tiptap/extension-floating-menu@^2.0.0-beta.26": + version "2.0.0-beta.26" + resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-2.0.0-beta.26.tgz#949672fd16820b2cd695d93189814d9f9f6e9468" + integrity sha512-qxC9ndyLf/H0H8ilVBGczOF66gFMUmQBqhZJ15hQpRFPeNNUMbLjn9Hka/BLNcQ83ypGN/mulXADIRuD9o6VhA== dependencies: prosemirror-state "^1.3.4" - prosemirror-view "^1.19.3" + prosemirror-view "^1.20.0" tippy.js "^6.3.1" "@tiptap/extension-gapcursor@^2.0.0-beta.19": @@ -1571,10 +1571,10 @@ "@types/prosemirror-gapcursor" "^1.0.4" prosemirror-gapcursor "^1.1.5" -"@tiptap/extension-hard-break@^2.0.0-beta.15": - version "2.0.0-beta.15" - resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-2.0.0-beta.15.tgz#ce00dd40f5abeaff8574f2288ade6815ab696c94" - integrity sha512-MS7MjGOtKtC1bVNAShwCetFRuk8nPr/j18OOzKChNrJFrZXWNJrid3dUojwDLqCraYdzSTmiOmMgU+yoUe/gnw== +"@tiptap/extension-hard-break@^2.0.0-beta.16": + version "2.0.0-beta.16" + resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-2.0.0-beta.16.tgz#1a55e901ce2deaaeaf53d77d254371955fe8fd99" + integrity sha512-vRw8OIJlvlr17Y7mtJGL/dWbotX9fjgmA/zYqL//UIXQjp1FWW5JMh5E1Z5+jlJpGWjsWGH8fHpGSM2JCZVPRw== "@tiptap/extension-heading@^2.0.0-beta.15": version "2.0.0-beta.15" @@ -1662,13 +1662,13 @@ resolved "https://registry.yarnpkg.com/@tiptap/extension-table-row/-/extension-table-row-2.0.0-beta.14.tgz#9ec98c73e309ee966b71ccd140019874d179e0c8" integrity sha512-mewdlTqgBCyzeZIZ6F08gfuzwsiYjQ7BvABo2UhDfr0+EN2UvfJj0bT3tGgeZhMxT5Js2DXL+c+ZOVJxWJ9faQ== -"@tiptap/extension-table@^2.0.0-beta.29": - version "2.0.0-beta.29" - resolved "https://registry.yarnpkg.com/@tiptap/extension-table/-/extension-table-2.0.0-beta.29.tgz#bc2a13203c432b297f3f4806d5dcb21271af7fa9" - integrity sha512-2yK4dZboe7+KQoJeM0p6v7xx+G/yKDWbbtDtYRnFecD2Oiz1u44DeMKGzVqPXcMYWxmCnAeUK0kcbmwnPYyBTg== +"@tiptap/extension-table@^2.0.0-beta.30": + version "2.0.0-beta.30" + resolved "https://registry.yarnpkg.com/@tiptap/extension-table/-/extension-table-2.0.0-beta.30.tgz#f6ff97ea71b17ecf3371ddf80374df9f49042334" + integrity sha512-s6+HRo3sFv7SUprsUAAF27hg7inITpzl78If3XdrpscuzTVuRmd7GsFnY+aZGPVikekwCMjp/0klE92P4A7w0w== dependencies: prosemirror-tables "^1.1.1" - prosemirror-view "^1.19.3" + prosemirror-view "^1.20.0" "@tiptap/extension-task-item@^2.0.0-beta.17": version "2.0.0-beta.17" @@ -1687,14 +1687,14 @@ resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-2.0.0-beta.13.tgz#da0af8d9a3f149d20076e15d88c6af21fb6d940f" integrity sha512-0EtAwuRldCAoFaL/iXgkRepEeOd55rPg5N4FQUN1xTwZT7PDofukP0DG/2jff/Uj17x4uTaJAa9qlFWuNnDvjw== -"@tiptap/vue-2@^2.0.0-beta.48": - version "2.0.0-beta.48" - resolved "https://registry.yarnpkg.com/@tiptap/vue-2/-/vue-2-2.0.0-beta.48.tgz#ee0bfec8819ab588c558dfa39f56269099a226bf" - integrity sha512-Cx8n8a2UwuJKyAheZKmAQe4s3gCmmPsgzZeh3FYtomp0xmf12H+dZbejqbv/w8pnCc/ATMdl3szf7NKA4hNz1Q== +"@tiptap/vue-2@^2.0.0-beta.49": + version "2.0.0-beta.49" + resolved "https://registry.yarnpkg.com/@tiptap/vue-2/-/vue-2-2.0.0-beta.49.tgz#4511ce8099c6f7e8e086430b22f0be0898029290" + integrity sha512-kHEsJGo3puqi9kyJj86DvorNFqUl4xICguB1Hhwv5PbeRbFN8aiIjM7I8xElfL6KCoIsWGeBIJJILHZ4YlIMrA== dependencies: - "@tiptap/extension-bubble-menu" "^2.0.0-beta.31" - "@tiptap/extension-floating-menu" "^2.0.0-beta.25" - prosemirror-view "^1.19.3" + "@tiptap/extension-bubble-menu" "^2.0.0-beta.32" + "@tiptap/extension-floating-menu" "^2.0.0-beta.26" + prosemirror-view "^1.20.0" "@toast-ui/editor@^2.5.2": version "2.5.2" @@ -1950,10 +1950,10 @@ dependencies: "@types/prosemirror-model" "*" -"@types/prosemirror-view@*", "@types/prosemirror-view@^1.17.2": - version "1.18.0" - resolved "https://registry.yarnpkg.com/@types/prosemirror-view/-/prosemirror-view-1.18.0.tgz#3ec23f48f0d8d9fe290a9bd43a91ce0622bec9b1" - integrity sha512-7NBy7qIV/ig49ThfkrIJrvW8E+HwumMgmpopUTYJlKwOh/fQ6SVUG/RtdnAIBLD+4uK0R2SMObbGZm06x6OwbA== +"@types/prosemirror-view@*", "@types/prosemirror-view@^1.19.0": + version "1.19.0" + resolved "https://registry.yarnpkg.com/@types/prosemirror-view/-/prosemirror-view-1.19.0.tgz#35320b6875ae7c750bce799cccf735e5da91af7a" + integrity sha512-Y8OX9L+Yni0HgXAN9wcNSf61IId13uqpURnRC5WkmCOlVDsr35vfGjj+tcaQL4dZzblsu3bRkXI/c0oGXp+xgw== dependencies: "@types/prosemirror-model" "*" "@types/prosemirror-state" "*" @@ -9692,10 +9692,10 @@ prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transfor dependencies: prosemirror-model "^1.0.0" -prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.16.5, prosemirror-view@^1.19.3: - version "1.19.3" - resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.19.3.tgz#8d9bc91705bcf9cb5ae3b4de2668f73c7b93fa14" - integrity sha512-YP/ZzVwqPPwbHbJi97U2/CeyZ8PIHmLJt0gIhZWP8XfnuBRGG3y+jwLzUoBVmiuoUCy3R6PSB+pOATliGzLfPg== +prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.16.5, prosemirror-view@^1.20.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.20.0.tgz#64198845f0d112c14a5594732c46a96ac3d9d828" + integrity sha512-OqU/bHUIiJhpyb2ytX4fLalYAJJOyZ0k5H0AibP/WPsdHq9CqmJFU676gO+N8WWhR5tVz1NxsqMZgEBy5Lc6GQ== dependencies: prosemirror-model "^1.14.3" prosemirror-state "^1.0.0" |