diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-08-09 06:08:53 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-08-09 06:08:53 +0300 |
commit | 251f4007156b40a0585e208eee2847d9d5746e08 (patch) | |
tree | ad7bd847a0807981d678c4b997c0acc614e91d0a | |
parent | 4596c2f5a5aef62aee84c24c26d9dc8db538ef3e (diff) |
Add latest changes from gitlab-org/gitlab@master
34 files changed, 554 insertions, 82 deletions
diff --git a/.gitlab/issue_templates/Geo Replicate a new Git repository type.md b/.gitlab/issue_templates/Geo Replicate a new Git repository type.md index 09449cadc0a..9e7d2634f3a 100644 --- a/.gitlab/issue_templates/Geo Replicate a new Git repository type.md +++ b/.gitlab/issue_templates/Geo Replicate a new Git repository type.md @@ -430,7 +430,6 @@ That's all of the required database changes. let(:model_record) { build(:cool_widget) } include_examples 'a repository replicator' - include_examples 'a verifiable replicator' end ``` diff --git a/.gitlab/issue_templates/Geo Replicate a new blob type.md b/.gitlab/issue_templates/Geo Replicate a new blob type.md index f06c8609707..11ad6614bc2 100644 --- a/.gitlab/issue_templates/Geo Replicate a new blob type.md +++ b/.gitlab/issue_templates/Geo Replicate a new blob type.md @@ -387,7 +387,6 @@ That's all of the required database changes. let(:model_record) { build(:cool_widget) } include_examples 'a blob replicator' - include_examples 'a verifiable replicator' end ``` diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index 0429815f10b..f79e948a1f3 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -c0e688008f860bd70647b3a30c1410f75744b6d5 +e6fe6870aaee291695fed50c2ef9a5de7b3dc356 diff --git a/app/assets/javascripts/sessions/new/components/update_email.vue b/app/assets/javascripts/sessions/new/components/update_email.vue index f63176e5513..192b46089ad 100644 --- a/app/assets/javascripts/sessions/new/components/update_email.vue +++ b/app/assets/javascripts/sessions/new/components/update_email.vue @@ -1,7 +1,6 @@ <script> import { GlForm, GlFormGroup, GlFormInput, GlButton } from '@gitlab/ui'; import { createAlert, VARIANT_SUCCESS } from '~/alert'; -import { isEmail } from '~/lib/utils/forms'; import axios from '~/lib/utils/axios_utils'; import { I18N_EMAIL, @@ -10,6 +9,7 @@ import { I18N_EMAIL_INVALID, I18N_UPDATE_EMAIL_SUCCESS, I18N_GENERIC_ERROR, + EMAIL_REGEXP, SUCCESS_RESPONSE, FAILURE_RESPONSE, } from '../constants'; @@ -47,7 +47,7 @@ export default { return ''; } - if (!isEmail(this.email)) { + if (!EMAIL_REGEXP.test(this.email)) { return I18N_EMAIL_INVALID; } diff --git a/app/assets/javascripts/sessions/new/constants.js b/app/assets/javascripts/sessions/new/constants.js index dec96f78232..c38829747fb 100644 --- a/app/assets/javascripts/sessions/new/constants.js +++ b/app/assets/javascripts/sessions/new/constants.js @@ -22,5 +22,6 @@ export const I18N_UPDATE_EMAIL_SUCCESS = s__( ); export const VERIFICATION_CODE_REGEX = /^\d{6}$/; +export const EMAIL_REGEXP = /^[^@\s]+@[^@\s]+$/; // Taken from DeviseEmailValidator export const SUCCESS_RESPONSE = 'success'; export const FAILURE_RESPONSE = 'failure'; diff --git a/app/models/integration.rb b/app/models/integration.rb index 26fbd857764..bc86b08018f 100644 --- a/app/models/integration.rb +++ b/app/models/integration.rb @@ -517,11 +517,11 @@ class Integration < ApplicationRecord end def api_field_names - fields.reject { _1[:type] == :password || _1[:name] == 'webhook' }.pluck(:name) + fields.reject { _1[:type] == :password || _1[:name] == 'webhook' || (_1.key?(:if) && _1[:if] != true) }.pluck(:name) end def form_fields - fields.reject { _1[:api_only] == true } + fields.reject { _1[:api_only] == true || (_1.key?(:if) && _1[:if] != true) } end def configurable_events diff --git a/app/models/integrations/field.rb b/app/models/integrations/field.rb index 11fac45323e..9dc90629344 100644 --- a/app/models/integrations/field.rb +++ b/app/models/integrations/field.rb @@ -6,7 +6,7 @@ module Integrations ATTRIBUTES = %i[ section type placeholder choices value checkbox_label - title help + title help if non_empty_password_help non_empty_password_title ].concat(BOOLEAN_ATTRIBUTES).freeze @@ -15,12 +15,15 @@ module Integrations attr_reader :name, :integration_class + delegate :key?, to: :attributes + def initialize(name:, integration_class:, type: :text, is_secret: false, api_only: false, **attributes) @name = name.to_s.freeze @integration_class = integration_class attributes[:type] = is_secret ? :password : type attributes[:api_only] = api_only + attributes[:if] = attributes.fetch(:if, true) attributes[:is_secret] = is_secret @attributes = attributes.freeze @@ -35,7 +38,7 @@ module Integrations def [](key) return name if key == :name - value = @attributes[key] + value = attributes[key] return integration_class.class_exec(&value) if value.respond_to?(:call) value @@ -56,5 +59,9 @@ module Integrations TYPES.each do |type| define_method("#{type}?") { self[:type] == type } end + + private + + attr_reader :attributes end end diff --git a/db/migrate/20230807202427_add_label_lock_on_merge_redux.rb b/db/migrate/20230807202427_add_label_lock_on_merge_redux.rb index 7c9975a0a71..99a4808777e 100644 --- a/db/migrate/20230807202427_add_label_lock_on_merge_redux.rb +++ b/db/migrate/20230807202427_add_label_lock_on_merge_redux.rb @@ -2,7 +2,17 @@ # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/128570 class AddLabelLockOnMergeRedux < Gitlab::Database::Migration[2.1] - def change + enable_lock_retries! + + def up + return if column_exists?(:labels, :lock_on_merge) + add_column :labels, :lock_on_merge, :boolean, default: false, null: false end + + def down + return unless column_exists?(:labels, :lock_on_merge) + + remove_column :labels, :lock_on_merge + end end diff --git a/db/post_migrate/20230718025027_cleanup_bigint_conversion_for_events_for_gitlab_com.rb b/db/post_migrate/20230718025027_cleanup_bigint_conversion_for_events_for_gitlab_com.rb index 00c155c8a8f..647052b987c 100644 --- a/db/post_migrate/20230718025027_cleanup_bigint_conversion_for_events_for_gitlab_com.rb +++ b/db/post_migrate/20230718025027_cleanup_bigint_conversion_for_events_for_gitlab_com.rb @@ -1,28 +1,13 @@ # frozen_string_literal: true +# Turning this migration to a no-op due to incident https://gitlab.com/gitlab-com/gl-infra/production/-/issues/16102 +# Migration will be retried in 20230801150214_retry_cleanup_bigint_conversion_for_events_for_gitlab_com.rb class CleanupBigintConversionForEventsForGitlabCom < Gitlab::Database::Migration[2.1] - include Gitlab::Database::MigrationHelpers::ConvertToBigint - - enable_lock_retries! - - TABLE = :events - COLUMNS = [:target_id] - def up - return unless should_run? - - cleanup_conversion_of_integer_to_bigint(TABLE, COLUMNS) + # no-op end def down - return unless should_run? - - restore_conversion_of_integer_to_bigint(TABLE, COLUMNS) - end - - private - - def should_run? - com_or_dev_or_test_but_not_jh? + # no-op end end diff --git a/db/post_migrate/20230801150214_retry_cleanup_bigint_conversion_for_events_for_gitlab_com.rb b/db/post_migrate/20230801150214_retry_cleanup_bigint_conversion_for_events_for_gitlab_com.rb new file mode 100644 index 00000000000..231c28e538c --- /dev/null +++ b/db/post_migrate/20230801150214_retry_cleanup_bigint_conversion_for_events_for_gitlab_com.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +class RetryCleanupBigintConversionForEventsForGitlabCom < Gitlab::Database::Migration[2.1] + include Gitlab::Database::MigrationHelpers::ConvertToBigint + + enable_lock_retries! + + TABLE = :events + COLUMNS = [:target_id] + + # We first attempted to drop the temporary trigger and column at + # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/126794 + def up + return unless should_run? + + return unless column_exists?(TABLE, :target_id_convert_to_bigint) + + cleanup_conversion_of_integer_to_bigint(TABLE, COLUMNS) + end + + def down + return unless should_run? + + return if column_exists?(TABLE, :target_id_convert_to_bigint) + + restore_conversion_of_integer_to_bigint(TABLE, COLUMNS) + end + + private + + def should_run? + com_or_dev_or_test_but_not_jh? + end +end diff --git a/db/post_migrate/20230808170646_remove_free_user_cap_over_limt_notified_at_column.rb b/db/post_migrate/20230808170646_remove_free_user_cap_over_limt_notified_at_column.rb new file mode 100644 index 00000000000..cd061499d67 --- /dev/null +++ b/db/post_migrate/20230808170646_remove_free_user_cap_over_limt_notified_at_column.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class RemoveFreeUserCapOverLimtNotifiedAtColumn < Gitlab::Database::Migration[2.1] + enable_lock_retries! + + def change + remove_column :namespace_details, :free_user_cap_over_limt_notified_at, :datetime_with_timezone + end +end diff --git a/db/schema_migrations/20230801150214 b/db/schema_migrations/20230801150214 new file mode 100644 index 00000000000..a94dfb5bcbd --- /dev/null +++ b/db/schema_migrations/20230801150214 @@ -0,0 +1 @@ +34601628500574506908150f11a5705dd65b7b144e09b7cd8f60176fdaec43c8
\ No newline at end of file diff --git a/db/schema_migrations/20230808170646 b/db/schema_migrations/20230808170646 new file mode 100644 index 00000000000..80f454148e1 --- /dev/null +++ b/db/schema_migrations/20230808170646 @@ -0,0 +1 @@ +e641285671d775a8aee8911a5775718a546c88a9a970ba99e3631ff88a8a9d4d
\ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 6ecb967d91e..5af92e124bd 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -18880,7 +18880,6 @@ CREATE TABLE namespace_details ( cached_markdown_version integer, description text, description_html text, - free_user_cap_over_limt_notified_at timestamp with time zone, free_user_cap_over_limit_notified_at timestamp with time zone, dashboard_notification_at timestamp with time zone, dashboard_enforcement_at timestamp with time zone, diff --git a/doc/administration/repository_checks.md b/doc/administration/repository_checks.md index 8cc635b50fc..1a33b6b5746 100644 --- a/doc/administration/repository_checks.md +++ b/doc/administration/repository_checks.md @@ -93,6 +93,10 @@ If periodic repository checks cause false alarms, you can clear all repository c 1. Expand the **Repository maintenance** section. 1. Select **Clear all repository checks**. +## Troubleshooting + +When working with repository checks, you might encounter the following issues. + ### Error: `failed to parse commit <commit SHA> from object database for commit-graph` You can see a `failed to parse commit <commit SHA> from object database for commit-graph` error in repository check logs. This error occurs if your `commit-graph` cache is out diff --git a/doc/api/rest/index.md b/doc/api/rest/index.md index 947142e3a50..20e260cfbb4 100644 --- a/doc/api/rest/index.md +++ b/doc/api/rest/index.md @@ -745,10 +745,56 @@ The correct encoding for the query parameter would be: 2017-10-17T23:11:13.000%2B05:30 ``` -## Clients +## Third-party clients -Many unofficial GitLab API Clients are available for most of the popular programming -languages. For a complete list, see the [GitLab website](https://about.gitlab.com/partners/technology-partners/#api-clients). +You can integrate third-party API client libraries with GitLab. The following libraries are maintained by community members and not officially supported by GitLab. +Report bugs and feature proposals to the respective projects. + +For questions about these integrations, use the [GitLab community forum](https://forum.gitlab.com/). + +### `C#` + +- [`GitLabApiClient`](https://github.com/nmklotas/GitLabApiClient) + +### Go + +- [`go-gitlab`](https://github.com/xanzy/go-gitlab) + +### Haskell + +- [`gitlab-haskell`](http://hackage.haskell.org/package/gitlab-haskell) + +### Java + +- [`gitlab4j-api`](https://github.com/gmessner/gitlab4j-api) +- [`java-gitlab-api`](https://github.com/timols/java-gitlab-api) + +### Node.js + +- [`gitlab-yaac`](https://www.npmjs.com/package/gitlab-yaac) +- [`backbone-gitlab`](https://github.com/oreillymedia/backbone-gitlab) + +### Perl + +- [`GitLab::API::v4`](https://metacpan.org/pod/GitLab::API::v4) + +### PHP + +- [`php-gitlab-api`](https://github.com/GitLabPHP/Client) + +### Python + +- [`python-gitlab`](https://github.com/python-gitlab/python-gitlab) + - Blog post: [Efficient DevSecOps workflows: Hands-on `python-gitlab` API automation](https://about.gitlab.com/blog/2023/02/01/efficient-devsecops-workflows-hands-on-python-gitlab-api-automation/) +- [`libsaas_gitlab`](https://gitlab.com/bor-sh-infrastructure/libsaas_gitlab) + +### Ruby + +- [Ruby wrapper and CLI for the GitLab REST API](https://github.com/NARKOZ/gitlab) + +### Swift + +- [`RxGitLabKit`](https://github.com/Qase/RxGitLabKit) ## Rate limits diff --git a/doc/development/documentation/testing.md b/doc/development/documentation/testing.md index d556d486b67..0c65e008436 100644 --- a/doc/development/documentation/testing.md +++ b/doc/development/documentation/testing.md @@ -508,7 +508,7 @@ To configure markdownlint in your editor, install one of the following as approp To configure Vale in your editor, install one of the following as appropriate: - Sublime Text [`SublimeLinter-vale` package](https://packagecontrol.io/packages/SublimeLinter-vale). -- Visual Studio Code [`errata-ai.vale-server` extension](https://marketplace.visualstudio.com/items?itemName=errata-ai.vale-server). +- Visual Studio Code [`ChrisChinchilla.vale-vscode` extension](https://marketplace.visualstudio.com/items?itemName=ChrisChinchilla.vale-vscode). You can configure the plugin to [display only a subset of alerts](#show-subset-of-vale-alerts). - Vim [ALE plugin](https://github.com/dense-analysis/ale). - JetBrains IDEs - No plugin exists, but diff --git a/doc/development/integrations/index.md b/doc/development/integrations/index.md index 9c0a64c68b5..dd73256ce11 100644 --- a/doc/development/integrations/index.md +++ b/doc/development/integrations/index.md @@ -198,6 +198,7 @@ This method should return an array of hashes for each field, where the keys can | `placeholder:` | string | false | | A placeholder for the form field. | `help:` | string | false | | A help text that displays below the form field. | `api_only:` | boolean | false | `false` | Specify if the field should only be available through the API, and excluded from the frontend form. +| `if:` | boolean or lambda | false | `true` | Specify if the field should be available. The value can be a boolean or a lambda. ### Additional keys for `type: 'checkbox'` diff --git a/doc/user/application_security/dependency_list/index.md b/doc/user/application_security/dependency_list/index.md index 8a4c15b082e..83fa4227946 100644 --- a/doc/user/application_security/dependency_list/index.md +++ b/doc/user/application_security/dependency_list/index.md @@ -9,9 +9,11 @@ info: To determine the technical writer assigned to the Stage/Group associated w > - System dependencies [introduced](https://gitlab.com/groups/gitlab-org/-/epics/6698) in GitLab 14.6. > - Group-level dependency list [introduced](https://gitlab.com/groups/gitlab-org/-/epics/8090) in GitLab 16.2 [with a flag](../../../administration/feature_flags.md) named `group_level_dependencies`. Disabled by default. +> - Group-level dependency list [enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/411257) in GitLab 16.3. FLAG: -On self-managed GitLab, by default the group-level dependency list is not available. To make it available, an administrator can [enable the feature flag](../../../administration/feature_flags.md) named `group_level_dependencies`. On GitLab.com, this feature is not available. +On self-managed GitLab, by default the group-level dependency list is available. To hide the feature, an administrator can [disable the feature flag](../../../administration/feature_flags.md) named `group_level_dependencies`. +On GitLab.com, this feature is available. Use the dependency list to review your project or group's dependencies and key details about those dependencies, including their known vulnerabilities. It is a collection of dependencies in your project, including existing and new findings. diff --git a/doc/user/application_security/dependency_scanning/index.md b/doc/user/application_security/dependency_scanning/index.md index a0c1a58dcf3..0995567bdfc 100644 --- a/doc/user/application_security/dependency_scanning/index.md +++ b/doc/user/application_security/dependency_scanning/index.md @@ -123,9 +123,10 @@ table.supported-languages ul { <td rowspan="2"> 8 LTS, 11 LTS, - or 17 LTS + 17 LTS, + or 21 EA<sup><b><a href="#notes-regarding-supported-languages-and-package-managers-2">2</a></b></sup> </td> - <td><a href="https://gradle.org/">Gradle</a><sup><b><a href="#notes-regarding-supported-languages-and-package-managers-2">2</a></b></sup></td> + <td><a href="https://gradle.org/">Gradle</a><sup><b><a href="#notes-regarding-supported-languages-and-package-managers-3">3</a></b></sup></td> <td> <ul> <li><code>build.gradle</code></li> @@ -157,7 +158,7 @@ table.supported-languages ul { <td>Y</td> </tr> <tr> - <td><a href="https://pnpm.io/">pnpm</a><sup><b><a href="#notes-regarding-supported-languages-and-package-managers-3">3</a></b></sup></td> + <td><a href="https://pnpm.io/">pnpm</a><sup><b><a href="#notes-regarding-supported-languages-and-package-managers-4">4</a></b></sup></td> <td><code>pnpm-lock.yaml</code></td> <td>Y</td> </tr> @@ -170,7 +171,7 @@ table.supported-languages ul { </tr> <tr> <td rowspan="4">Python</td> - <td rowspan="4">3.9, 3.10<sup><b><a href="#notes-regarding-supported-languages-and-package-managers-4">4</a></b></sup></td> + <td rowspan="4">3.9, 3.10<sup><b><a href="#notes-regarding-supported-languages-and-package-managers-5">5</a></b></sup></td> <td><a href="https://setuptools.readthedocs.io/en/latest/">setuptools</a></td> <td><code>setup.py</code></td> <td>N</td> @@ -197,7 +198,7 @@ table.supported-languages ul { <td>N</td> </tr> <tr> - <td><a href="https://python-poetry.org/">Poetry</a><sup><b><a href="#notes-regarding-supported-languages-and-package-managers-5">5</a></b></sup></td> + <td><a href="https://python-poetry.org/">Poetry</a><sup><b><a href="#notes-regarding-supported-languages-and-package-managers-6">6</a></b></sup></td> <td><code>poetry.lock</code></td> <td>N</td> </tr> @@ -216,7 +217,7 @@ table.supported-languages ul { <tr> <td>Scala</td> <td>All versions</td> - <td><a href="https://www.scala-sbt.org/">sbt</a><sup><b><a href="#notes-regarding-supported-languages-and-package-managers-6">6</a></b></sup></td> + <td><a href="https://www.scala-sbt.org/">sbt</a><sup><b><a href="#notes-regarding-supported-languages-and-package-managers-7">7</a></b></sup></td> <td><code>build.sbt</code></td> <td>N</td> </tr> @@ -233,18 +234,25 @@ table.supported-languages ul { <li> <a id="notes-regarding-supported-languages-and-package-managers-2"></a> <p> - Gradle is not supported when <a href="https://docs.gitlab.com/ee/development/fips_compliance.html#enable-fips-mode">FIPS mode</a> is enabled. + Java 21 EA is only available when using <a href="https://maven.apache.org/">Maven</a> and is not supported when + <a href="https://docs.gitlab.com/ee/development/fips_compliance.html#enable-fips-mode">FIPS mode</a> is enabled. </p> </li> <li> <a id="notes-regarding-supported-languages-and-package-managers-3"></a> <p> - Support for <code>pnpm</code> lockfiles was <a href="https://gitlab.com/gitlab-org/gitlab/-/issues/336809">introduced in GitLab 15.11</a>. <code>pnpm</code> lockfiles do not store bundled dependencies, so the reported dependencies may differ from <code>npm</code> or <code>yarn</code>. + Gradle is not supported when <a href="https://docs.gitlab.com/ee/development/fips_compliance.html#enable-fips-mode">FIPS mode</a> is enabled. </p> </li> <li> <a id="notes-regarding-supported-languages-and-package-managers-4"></a> <p> + Support for <code>pnpm</code> lockfiles was <a href="https://gitlab.com/gitlab-org/gitlab/-/issues/336809">introduced in GitLab 15.11</a>. <code>pnpm</code> lockfiles do not store bundled dependencies, so the reported dependencies may differ from <code>npm</code> or <code>yarn</code>. + </p> + </li> + <li> + <a id="notes-regarding-supported-languages-and-package-managers-5"></a> + <p> For support of <code>Python 3.10</code>, add the following stanza to the GitLab CI/CD configuration file. This specifies that the <code>Python 3.10</code> image is to be used, instead of the default <code>Python 3.9</code>. <div class="language-yaml highlighter-rouge"> <div class="highlight"> @@ -254,7 +262,7 @@ table.supported-languages ul { </p> </li> <li> - <a id="notes-regarding-supported-languages-and-package-managers-5"></a> + <a id="notes-regarding-supported-languages-and-package-managers-6"></a> <p> Support for <a href="https://python-poetry.org/">Poetry</a> projects with a <code>poetry.lock</code> file was <a href="https://gitlab.com/gitlab-org/gitlab/-/issues/7006">added in GitLab 15.0</a>. Support for projects without a <code>poetry.lock</code> file is tracked in issue: @@ -262,7 +270,7 @@ table.supported-languages ul { </p> </li> <li> - <a id="notes-regarding-supported-languages-and-package-managers-6"></a> + <a id="notes-regarding-supported-languages-and-package-managers-7"></a> <p> Support for <a href="https://www.scala-sbt.org/">sbt</a> 1.3 and above was added in GitLab 13.9. </p> @@ -637,7 +645,7 @@ The following variables are used for configuring specific analyzers (used for a | `DS_REMEDIATE` | `gemnasium` | `"true"`, `"false"` in FIPS mode | Enable automatic remediation of vulnerable dependencies. Not supported in FIPS mode. | | `DS_REMEDIATE_TIMEOUT` | `gemnasium` | `5m` | Timeout for auto-remediation. | | `GEMNASIUM_LIBRARY_SCAN_ENABLED` | `gemnasium` | `"true"` | Enable detecting vulnerabilities in vendored JavaScript libraries. For now, `gemnasium` leverages [`Retire.js`](https://github.com/RetireJS/retire.js) to do this job. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/350512) in GitLab 14.8. | -| `DS_JAVA_VERSION` | `gemnasium-maven` | `17` | Version of Java. Available versions: `8`, `11`, `17`. | +| `DS_JAVA_VERSION` | `gemnasium-maven` | `17` | Version of Java. Available versions: `8`, `11`, `17`, `21` | | `MAVEN_CLI_OPTS` | `gemnasium-maven` | `"-DskipTests --batch-mode"` | List of command line arguments that are passed to `maven` by the analyzer. See an example for [using private repositories](../index.md#using-private-maven-repositories). | | `GRADLE_CLI_OPTS` | `gemnasium-maven` | | List of command line arguments that are passed to `gradle` by the analyzer. | | `SBT_CLI_OPTS` | `gemnasium-maven` | | List of command-line arguments that the analyzer passes to `sbt`. | diff --git a/doc/user/application_security/vulnerabilities/img/explain_this_vulnerability_beta_v16_3.png b/doc/user/application_security/vulnerabilities/img/explain_this_vulnerability_beta_v16_3.png Binary files differindex 8eab47ac5df..55266babbf2 100644 --- a/doc/user/application_security/vulnerabilities/img/explain_this_vulnerability_beta_v16_3.png +++ b/doc/user/application_security/vulnerabilities/img/explain_this_vulnerability_beta_v16_3.png diff --git a/doc/user/project/settings/import_export.md b/doc/user/project/settings/import_export.md index 8330b8c14bc..bbb34d9ec29 100644 --- a/doc/user/project/settings/import_export.md +++ b/doc/user/project/settings/import_export.md @@ -155,14 +155,16 @@ For a quick overview, items that are exported include: - Labels - Milestones - Snippets +- Releases - Time tracking and other project entities - Design management files and data - LFS objects - Issue boards -- Pipelines history +- CI/CD pipelines and pipeline schedules +- Protected branches and tags - Push rules - Emoji reactions -- Group members as long as the user has the Maintainer role in the +- Project and inherited group members, as long as the user has the Maintainer role in the exported project's group or is an administrator ### Items that are not exported diff --git a/lib/click_house/query_builder.rb b/lib/click_house/query_builder.rb new file mode 100644 index 00000000000..fd0931636b0 --- /dev/null +++ b/lib/click_house/query_builder.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true + +# rubocop:disable CodeReuse/ActiveRecord +module ClickHouse + class QueryBuilder + attr_reader :table + + def initialize(table_name) + @table = Arel::Table.new(table_name) + @manager = Arel::SelectManager.new(Arel::Table.engine) + @manager.from(@table) + @manager.project(Arel.star) + end + + # The `where` method currently does not support range queries like ActiveRecord. + # For example, using a range (start_date..end_date) will result in incorrect SQL. + # If you need to query a range, use greater than and less than conditions with Arel. + # + # Correct usage: + # query.where(query.table[:created_at].lteq(Date.today)).to_sql + # "SELECT * FROM \"table\" WHERE \"table\".\"created_at\" <= '2023-08-01'" + # + # This also supports array conditions which will result in an IN query. + # query.where(entity_id: [1,2,3]).to_sql + # "SELECT * FROM \"table\" WHERE \"table\".\"entity_id\" IN (1, 2, 3)" + # + # Range support could be considered for future iterations. + def where(conditions) + if conditions.is_a?(Arel::Nodes::Node) + manager.where(conditions) + else + conditions.each do |key, value| + if value.is_a?(Array) + manager.where(table[key].in(value)) + else + manager.where(table[key].eq(value)) + end + end + end + + self + end + + def select(*fields) + manager.projections = [] + fields.each do |field| + manager.project(table[field]) + end + + self + end + + def order(field, direction = :asc) + direction = direction.to_s.downcase + unless %w[asc desc].include?(direction) + raise ArgumentError, "Invalid order direction '#{direction}'. Must be :asc or :desc" + end + + manager.order(table[field].public_send(direction)) # rubocop:disable GitlabSecurity/PublicSend + + self + end + + def limit(count) + manager.take(count) + self + end + + def offset(count) + manager.skip(count) + self + end + + def to_sql + manager.to_sql + end + + private + + attr_reader :manager + end +end + +# rubocop:enable CodeReuse/ActiveRecord diff --git a/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml index 46d0b92b243..c1aedbe1111 100644 --- a/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml @@ -1,5 +1,5 @@ variables: - AUTO_BUILD_IMAGE_VERSION: 'v1.37.0' + AUTO_BUILD_IMAGE_VERSION: 'v1.38.1' build: stage: build diff --git a/lib/gitlab/ci/templates/Jobs/Build.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Build.latest.gitlab-ci.yml index 46d0b92b243..c1aedbe1111 100644 --- a/lib/gitlab/ci/templates/Jobs/Build.latest.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Jobs/Build.latest.gitlab-ci.yml @@ -1,5 +1,5 @@ variables: - AUTO_BUILD_IMAGE_VERSION: 'v1.37.0' + AUTO_BUILD_IMAGE_VERSION: 'v1.38.1' build: stage: build diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 07ee85d2b78..a483920c794 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -17087,6 +17087,9 @@ msgstr "" msgid "DomainVerification|To verify ownership of your domain, add the above key to a TXT record within your DNS configuration within seven days. %{link_to_help}" msgstr "" +msgid "Domains" +msgstr "" + msgid "Don't have a group?" msgstr "" @@ -44806,9 +44809,6 @@ msgstr "" msgid "Source IP" msgstr "" -msgid "Source Project" -msgstr "" - msgid "Source branch" msgstr "" @@ -44833,6 +44833,9 @@ msgstr "" msgid "Source is not available" msgstr "" +msgid "Source project" +msgstr "" + msgid "Source project cannot be found." msgstr "" @@ -51442,6 +51445,9 @@ msgstr "" msgid "VerificationReminder|You’ll now be able to take advantage of free compute minutes on shared runners." msgstr "" +msgid "Verifications status" +msgstr "" + msgid "Verified" msgstr "" diff --git a/spec/frontend/sessions/new/components/update_email_spec.js b/spec/frontend/sessions/new/components/update_email_spec.js index 37da8b56e9b..822720da898 100644 --- a/spec/frontend/sessions/new/components/update_email_spec.js +++ b/spec/frontend/sessions/new/components/update_email_spec.js @@ -14,18 +14,14 @@ import { FAILURE_RESPONSE, } from '~/sessions/new/constants'; -const validEmailAddress = 'valid@ema.il'; -const invalidEmailAddress = 'invalid@ema.il'; +const validEmailAddress = 'foo+bar@ema.il'; +const invalidEmailAddress = 'invalid@ema@il'; jest.mock('~/alert'); jest.mock('~/lib/utils/url_utility', () => ({ ...jest.requireActual('~/lib/utils/url_utility'), visitUrl: jest.fn(), })); -jest.mock('~/lib/utils/forms', () => ({ - ...jest.requireActual('~/lib/utils/forms'), - isEmail: jest.fn().mockImplementation((email) => email === validEmailAddress), -})); describe('EmailVerification', () => { let wrapper; diff --git a/spec/lib/click_house/query_builder_spec.rb b/spec/lib/click_house/query_builder_spec.rb new file mode 100644 index 00000000000..d1017fe42c5 --- /dev/null +++ b/spec/lib/click_house/query_builder_spec.rb @@ -0,0 +1,131 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe ClickHouse::QueryBuilder, feature_category: :database do + let(:table_name) { :test_table } + let(:builder) { described_class.new(table_name) } + + describe "#initialize" do + it 'initializes with correct table' do + expect(builder.table.name).to eq(table_name.to_s) + end + end + + describe '#where' do + it 'builds correct where query with simple conditions' do + expected_sql = "SELECT * FROM \"test_table\" WHERE \"test_table\".\"column1\" " \ + "= 'value1' AND \"test_table\".\"column2\" = 'value2'" + + sql = builder.where(column1: 'value1', column2: 'value2').to_sql + + expect(sql).to eq(expected_sql) + end + + it 'builds correct where query with array conditions' do + expected_sql = "SELECT * FROM \"test_table\" WHERE \"test_table\".\"column1\" " \ + "IN (1, 2, 3)" + + sql = builder.where(column1: [1, 2, 3]).to_sql + + expect(sql).to eq(expected_sql) + end + + it 'builds correct where query with arel nodes' do + date = Date.today + expected_sql = "SELECT * FROM \"test_table\" WHERE \"test_table\".\"created_at\" <= '#{date}'" + + sql = builder.where(builder.table[:created_at].lteq(date)).to_sql + + expect(sql).to eq(expected_sql) + end + end + + describe '#select' do + it 'builds correct select query with single field' do + expected_sql = "SELECT \"test_table\".\"column1\" FROM \"test_table\"" + + sql = builder.select(:column1).to_sql + + expect(sql).to eq(expected_sql) + end + + it 'builds correct select query with multiple fields' do + expected_sql = "SELECT \"test_table\".\"column1\", \"test_table\".\"column2\" FROM \"test_table\"" + + sql = builder.select(:column1, :column2).to_sql + + expect(sql).to eq(expected_sql) + end + end + + describe '#order' do + it 'builds correct order query with direction :desc' do + expected_sql = "SELECT * FROM \"test_table\" ORDER BY \"test_table\".\"column1\" DESC" + + sql = builder.order(:column1, :desc).to_sql + + expect(sql).to eq(expected_sql) + end + + it 'builds correct order query with default direction asc' do + expected_sql = "SELECT * FROM \"test_table\" ORDER BY \"test_table\".\"column1\" ASC" + + sql = builder.order(:column1).to_sql + + expect(sql).to eq(expected_sql) + end + + it 'raises error for invalid direction' do + expect do + builder.order(:column1, :invalid) + end.to raise_error(ArgumentError, "Invalid order direction 'invalid'. Must be :asc or :desc") + end + end + + describe '#limit' do + it 'builds correct limit query' do + expected_sql = "SELECT * FROM \"test_table\" LIMIT 10" + + sql = builder.limit(10).to_sql + + expect(sql).to eq(expected_sql) + end + end + + describe '#offset' do + it 'builds correct offset query' do + expected_sql = "SELECT * FROM \"test_table\" OFFSET 5" + + sql = builder.offset(5).to_sql + + expect(sql).to eq(expected_sql) + end + end + + describe '#to_sql' do + it 'delegates to the Arel::SelectManager' do + expect(builder.send(:manager)).to receive(:to_sql) + + builder.to_sql + end + end + + describe 'method chaining' do + it 'builds correct SQL query when methods are chained' do + expected_sql = "SELECT \"test_table\".\"column1\", \"test_table\".\"column2\" FROM \"test_table\" " \ + "WHERE \"test_table\".\"column1\" = 'value1' AND \"test_table\".\"column2\" = 'value2' " \ + "ORDER BY \"test_table\".\"column1\" DESC LIMIT 10 OFFSET 5" + + sql = builder + .select(:column1, :column2) + .where(column1: 'value1', column2: 'value2') + .order(:column1, 'desc') + .limit(10) + .offset(5) + .to_sql + + expect(sql).to eq(expected_sql) + end + end +end diff --git a/spec/migrations/20230801150214_retry_cleanup_bigint_conversion_for_events_for_gitlab_com_spec.rb b/spec/migrations/20230801150214_retry_cleanup_bigint_conversion_for_events_for_gitlab_com_spec.rb new file mode 100644 index 00000000000..0eac9f28fcd --- /dev/null +++ b/spec/migrations/20230801150214_retry_cleanup_bigint_conversion_for_events_for_gitlab_com_spec.rb @@ -0,0 +1,147 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require_migration! + +RSpec.describe RetryCleanupBigintConversionForEventsForGitlabCom, :migration, feature_category: :database do + let(:migration) { described_class.new } + let(:connection) { migration.connection } + let(:column_name) { 'target_id_convert_to_bigint' } + let(:events_table) { table(:events) } + + before do + allow(migration).to receive(:should_run?).and_return(should_run?) + end + + shared_examples 'skips the up migration' do + it "doesn't calls cleanup_conversion_of_integer_to_bigint method" do + disable_migrations_output do + expect(migration).not_to receive(:cleanup_conversion_of_integer_to_bigint) + + migration.up + end + end + end + + shared_examples 'skips the down migration' do + it "doesn't calls restore_conversion_of_integer_to_bigint method" do + disable_migrations_output do + expect(migration).not_to receive(:restore_conversion_of_integer_to_bigint) + + migration.down + end + end + end + + describe '#up' do + context 'when column still exists' do + before do + # Ensures the correct state of db before the test + connection.execute('ALTER TABLE events ADD COLUMN IF NOT EXISTS target_id_convert_to_bigint integer') + connection.execute('CREATE OR REPLACE FUNCTION trigger_cd1aeb22b34a() RETURNS trigger LANGUAGE plpgsql AS $$ + BEGIN NEW."target_id_convert_to_bigint" := NEW."target_id"; RETURN NEW; END; $$;') + connection.execute('DROP TRIGGER IF EXISTS trigger_cd1aeb22b34a ON events') + connection.execute('CREATE TRIGGER trigger_cd1aeb22b34a BEFORE INSERT OR UPDATE ON events FOR EACH ROW EXECUTE + FUNCTION trigger_cd1aeb22b34a()') + end + + context 'when is GitLab.com, dev, or test' do + let(:should_run?) { true } + + it 'drop the temporary columns' do + disable_migrations_output do + reversible_migration do |migration| + migration.before -> { + events_table.reset_column_information + expect(events_table.columns.find { |c| c.name == 'target_id_convert_to_bigint' }).not_to be_nil + } + + migration.after -> { + events_table.reset_column_information + expect(events_table.columns.find { |c| c.name == 'target_id_convert_to_bigint' }).to be_nil + } + end + end + end + end + + context 'when is a self-managed instance' do + let(:should_run?) { false } + + it_behaves_like 'skips the up migration' + end + end + + context 'when column not exists' do + before do + connection.execute('ALTER TABLE events DROP COLUMN IF EXISTS target_id_convert_to_bigint') + end + + context 'when is GitLab.com, dev, or test' do + let(:should_run?) { true } + + it_behaves_like 'skips the up migration' + end + + context 'when is a self-managed instance' do + let(:should_run?) { false } + + it_behaves_like 'skips the up migration' + end + end + end + + describe '#down' do + context 'when column still exists' do + before do + # Ensures the correct state of db before the test + connection.execute('ALTER TABLE events ADD COLUMN IF NOT EXISTS target_id_convert_to_bigint integer') + connection.execute('CREATE OR REPLACE FUNCTION trigger_cd1aeb22b34a() RETURNS trigger LANGUAGE plpgsql AS $$ + BEGIN NEW."target_id_convert_to_bigint" := NEW."target_id"; RETURN NEW; END; $$;') + connection.execute('DROP TRIGGER IF EXISTS trigger_cd1aeb22b34a ON events') + connection.execute('CREATE TRIGGER trigger_cd1aeb22b34a BEFORE INSERT OR UPDATE ON events FOR EACH ROW EXECUTE + FUNCTION trigger_cd1aeb22b34a()') + end + + context 'when is GitLab.com, dev, or test' do + let(:should_run?) { true } + + it_behaves_like 'skips the down migration' + end + + context 'when is a self-managed instance' do + let(:should_run?) { false } + + it_behaves_like 'skips the down migration' + end + end + + context 'when column not exists' do + before do + connection.execute('ALTER TABLE events DROP COLUMN IF EXISTS target_id_convert_to_bigint') + end + + context 'when is GitLab.com, dev, or test' do + let(:should_run?) { true } + + it 'restore the temporary columns' do + disable_migrations_output do + migration.down + + column = events_table.columns.find { |c| c.name == 'target_id_convert_to_bigint' } + + expect(column).not_to be_nil + expect(column.sql_type).to eq('integer') + end + end + end + + context 'when is a self-managed instance' do + let(:should_run?) { false } + + it_behaves_like 'skips the down migration' + end + end + end +end diff --git a/spec/models/integration_spec.rb b/spec/models/integration_spec.rb index ffe1e06a063..0b41b46ae3d 100644 --- a/spec/models/integration_spec.rb +++ b/spec/models/integration_spec.rb @@ -836,8 +836,8 @@ RSpec.describe Integration, feature_category: :integrations do end shared_examples '#api_field_names' do - it 'filters out secret fields' do - safe_fields = %w[some_safe_field safe_field url trojan_gift api_only_field] + it 'filters out secret fields and conditional fields' do + safe_fields = %w[some_safe_field safe_field url trojan_gift api_only_field enabled_field] expect(fake_integration.new).to have_attributes( api_field_names: match_array(safe_fields) @@ -849,6 +849,11 @@ RSpec.describe Integration, feature_category: :integrations do it 'filters out API only fields' do expect(fake_integration.new.form_fields.pluck(:name)).not_to include('api_only_field') end + + it 'filters conditionals fields' do + expect(fake_integration.new.form_fields.pluck(:name)).to include('enabled_field') + expect(fake_integration.new.form_fields.pluck(:name)).not_to include('disabled_field', 'disabled_field_2') + end end context 'when the class overrides #fields' do @@ -870,7 +875,10 @@ RSpec.describe Integration, feature_category: :integrations do { name: 'url' }, { name: 'trojan_horse', type: :password }, { name: 'trojan_gift', type: :text }, - { name: 'api_only_field', api_only: true } + { name: 'api_only_field', api_only: true }, + { name: 'enabled_field', if: true }, + { name: 'disabled_field', if: false }, + { name: 'disabled_field_2', if: nil } ].shuffle end end @@ -899,6 +907,9 @@ RSpec.describe Integration, feature_category: :integrations do field :trojan_horse, type: :password field :trojan_gift, type: :text field :api_only_field, api_only: true + field :enabled_field, if: -> { true } + field :disabled_field, if: -> { false } + field :disabled_field_2, if: -> { nil } end end diff --git a/spec/models/integrations/field_spec.rb b/spec/models/integrations/field_spec.rb index 9017d396c29..49eaecd1b2e 100644 --- a/spec/models/integrations/field_spec.rb +++ b/spec/models/integrations/field_spec.rb @@ -85,6 +85,8 @@ RSpec.describe ::Integrations::Field, feature_category: :integrations do eq :text when :is_secret eq false + when :if + be true else be_nil end @@ -183,4 +185,9 @@ RSpec.describe ::Integrations::Field, feature_category: :integrations do it { is_expected.not_to be_secret } end end + + describe '#key?' do + it { is_expected.to be_key(:type) } + it { is_expected.not_to be_key(:foo) } + end end diff --git a/spec/models/preloaders/user_max_access_level_in_groups_preloader_spec.rb b/spec/models/preloaders/user_max_access_level_in_groups_preloader_spec.rb index 3fba2ac003b..5befa3ab66f 100644 --- a/spec/models/preloaders/user_max_access_level_in_groups_preloader_spec.rb +++ b/spec/models/preloaders/user_max_access_level_in_groups_preloader_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Preloaders::UserMaxAccessLevelInGroupsPreloader do +RSpec.describe Preloaders::UserMaxAccessLevelInGroupsPreloader, feature_category: :system_access do let_it_be(:user) { create(:user) } let_it_be(:group1) { create(:group, :private).tap { |g| g.add_developer(user) } } let_it_be(:group2) { create(:group, :private).tap { |g| g.add_developer(user) } } diff --git a/spec/models/preloaders/user_max_access_level_in_projects_preloader_spec.rb b/spec/models/preloaders/user_max_access_level_in_projects_preloader_spec.rb index 17db284c61e..2070d6d167d 100644 --- a/spec/models/preloaders/user_max_access_level_in_projects_preloader_spec.rb +++ b/spec/models/preloaders/user_max_access_level_in_projects_preloader_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Preloaders::UserMaxAccessLevelInProjectsPreloader do +RSpec.describe Preloaders::UserMaxAccessLevelInProjectsPreloader, feature_category: :system_access do let_it_be(:user) { create(:user) } let_it_be(:project_1) { create(:project) } let_it_be(:project_2) { create(:project) } diff --git a/spec/support/helpers/models/ci/partitioning_testing/schema_helpers.rb b/spec/support/helpers/models/ci/partitioning_testing/schema_helpers.rb index 849d9ea117e..f31dbb111ee 100644 --- a/spec/support/helpers/models/ci/partitioning_testing/schema_helpers.rb +++ b/spec/support/helpers/models/ci/partitioning_testing/schema_helpers.rb @@ -3,8 +3,6 @@ module Ci module PartitioningTesting module SchemaHelpers - DEFAULT_PARTITION = 100 - module_function def with_routing_tables @@ -14,16 +12,8 @@ module Ci # model.table_name = :regular_table end - # We're dropping the default values here to ensure that the application code - # populates the `partition_id` value and it's not falling back on the - # database default one. We should be able to clean this up after - # partitioning the tables and substituting the routing table in the model: - # https://gitlab.com/gitlab-org/gitlab/-/issues/377822 - # def setup(connection: Ci::ApplicationRecord.connection) each_partitionable_table do |table_name| - change_column_default(table_name, from: DEFAULT_PARTITION, to: nil, connection: connection) - change_column_default("p_#{table_name}", from: DEFAULT_PARTITION, to: nil, connection: connection) create_test_partition("p_#{table_name}", connection: connection) end end @@ -31,8 +21,6 @@ module Ci def teardown(connection: Ci::ApplicationRecord.connection) each_partitionable_table do |table_name| drop_test_partition("p_#{table_name}", connection: connection) - change_column_default(table_name, from: nil, to: DEFAULT_PARTITION, connection: connection) - change_column_default("p_#{table_name}", from: nil, to: DEFAULT_PARTITION, connection: connection) end end @@ -47,12 +35,6 @@ module Ci end end - def change_column_default(table_name, from:, to:, connection:) - return unless table_available?(table_name, connection: connection) - - connection.change_column_default(table_name, :partition_id, from: from, to: to) - end - def create_test_partition(table_name, connection:) return unless table_available?(table_name, connection: connection) |