Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-11-01 12:10:18 +00:00
parent 58c42f2f45
commit 3a5bee7879
26 changed files with 327 additions and 78 deletions

View file

@ -246,7 +246,7 @@ gem 're2', '~> 1.6.0'
gem 'version_sorter', '~> 2.2.4'
# Export Ruby Regex to Javascript
gem 'js_regex', '~> 3.7'
gem 'js_regex', '~> 3.8'
# User agent parsing
gem 'device_detector'

View file

@ -286,7 +286,7 @@
{"name":"jaro_winkler","version":"1.5.4","platform":"ruby","checksum":"50c3e83c5a9e8769c1cf5b73c8b51bb6eebbf8852a0ee53bf6ad6e4dc63414f9"},
{"name":"jira-ruby","version":"2.1.4","platform":"ruby","checksum":"4267c095cac8323b9eef3ba866eb28bb1388b7623a5abb60c1e7caf12d4adb9e"},
{"name":"jmespath","version":"1.6.1","platform":"ruby","checksum":"40ca83f4141bdd1e503db5485de68b84237183d84cf7a159fbeebcc6005adbd6"},
{"name":"js_regex","version":"3.7.0","platform":"ruby","checksum":"b13fac68c4416d1a5f21c3bab8a71b4530f424b7c4ff9f46d8e62b895dc05975"},
{"name":"js_regex","version":"3.8.0","platform":"ruby","checksum":"7934bcdd5a0e6d5af4a520288fd4684a02a472ae55831d9178ccaf82356344b5"},
{"name":"json","version":"2.5.1","platform":"java","checksum":"be284a0c4a9d0373e81b0d5dfe71ed5b18d0479f05970e60a77be89a2978ce6c"},
{"name":"json","version":"2.5.1","platform":"ruby","checksum":"918d8c41dacb7cfdbe0c7bbd6014a5372f0cf1c454ca150e9f4010fe80cc3153"},
{"name":"json-jwt","version":"1.15.3","platform":"ruby","checksum":"66db4f14e538a774c15502a5b5b26b1f3e7585481bbb96df490aa74b5c2d6110"},

View file

@ -758,9 +758,9 @@ GEM
multipart-post
oauth (~> 0.5, >= 0.5.0)
jmespath (1.6.1)
js_regex (3.7.0)
js_regex (3.8.0)
character_set (~> 1.4)
regexp_parser (~> 2.1)
regexp_parser (~> 2.5)
regexp_property_values (~> 1.0)
json (2.5.1)
json-jwt (1.15.3)
@ -1673,7 +1673,7 @@ DEPENDENCIES
ipaddress (~> 0.8.3)
ipynbdiff!
jira-ruby (~> 2.1.4)
js_regex (~> 3.7)
js_regex (~> 3.8)
json (~> 2.5.1)
json_schemer (~> 0.2.18)
jwt (~> 2.1.0)

View file

@ -85,10 +85,12 @@ export const billingPlanNames = {
};
const INTEGRATION_TYPE_SLACK = 'slack';
const INTEGRATION_TYPE_SLACK_APPLICATION = 'gitlab_slack_application';
const INTEGRATION_TYPE_MATTERMOST = 'mattermost';
export const placeholderForType = {
[INTEGRATION_TYPE_SLACK]: __('#general, #development'),
[INTEGRATION_TYPE_SLACK_APPLICATION]: __('#general, #development'),
[INTEGRATION_TYPE_MATTERMOST]: __('my-channel'),
};

View file

@ -23,7 +23,7 @@ export default {
},
computed: {
...mapGetters(['isInheriting']),
placeholder() {
defaultPlaceholder() {
return placeholderForType[this.type];
},
},
@ -55,7 +55,7 @@ export default {
v-if="event.field"
v-model="event.field.value"
:name="fieldName(event.field.name)"
:placeholder="placeholder"
:placeholder="event.field.placeholder || defaultPlaceholder"
:readonly="isInheriting"
/>
</gl-form-group>

View file

@ -12,6 +12,7 @@
s_('ProjectSettings|Skipped pipelines are considered successful'),
help_text: s_('ProjectSettings|Introduces the risk of merging changes that do not pass the pipeline.'),
checkbox_options: { class: 'gl-pl-6' }
= render_if_exists 'projects/merge_request_merge_checks_status_checks', form: form, project: @project
= form.gitlab_ui_checkbox_component :only_allow_merge_if_all_discussions_are_resolved,
s_('ProjectSettings|All threads must be resolved'),
checkbox_options: { data: { qa_selector: 'allow_merge_if_all_discussions_are_resolved_checkbox' } }

View file

@ -1,7 +1,7 @@
---
name: integration_slack_app_notifications
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/98663
rollout_issue_url:
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/381012
milestone: '15.5'
type: development
group: group::integrations

View file

@ -1,15 +1,18 @@
# frozen_string_literal: true
# Currently we register validator only for `dev` or `test` environment
Gitlab::Database::QueryAnalyzer.instance.hook!
Gitlab::Database::QueryAnalyzer.instance.all_analyzers.append(::Gitlab::Database::QueryAnalyzers::GitlabSchemasMetrics)
Gitlab::Database::QueryAnalyzer.instance.all_analyzers.append(
::Gitlab::Database::QueryAnalyzers::PreventCrossDatabaseModification
)
Gitlab::Database::QueryAnalyzer.instance.tap do |query_analyzer|
query_analyzer.hook!
if Gitlab.dev_or_test_env?
query_analyzer = ::Gitlab::Database::QueryAnalyzers::GitlabSchemasValidateConnection
Gitlab::Database::QueryAnalyzer.instance.all_analyzers.append(query_analyzer)
query_analyzer.all_analyzers.tap do |analyzers|
analyzers.append(::Gitlab::Database::QueryAnalyzers::GitlabSchemasMetrics)
analyzers.append(::Gitlab::Database::QueryAnalyzers::PreventCrossDatabaseModification)
if Gitlab.dev_or_test_env?
analyzers.append(::Gitlab::Database::QueryAnalyzers::GitlabSchemasValidateConnection)
analyzers.append(::Gitlab::Database::QueryAnalyzers::QueryRecorder)
end
end
end
Gitlab::Application.configure do |config|

View file

@ -26,6 +26,10 @@ metadata:
description: Operations related to deploy tokens
- name: deployments
description: Operations related to deployments
- name: environments
description: Operations related to environments
- name: feature_flags_user_lists
description: Operations related to accessing GitLab feature flag user lists
- name: features
description: Operations related to managing Flipper-based feature flags
- name: freeze_periods

View file

@ -20,7 +20,7 @@ GET /projects/:id/environments
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
| `name` | string | no | Return the environment with this name. Mutually exclusive with `search` |
| `search` | string | no | Return list of environments matching the search criteria. Mutually exclusive with `name` |
| `states` | string | no | List all environments that match a specific state. Accepted values: `available`, `stopping` or `stopped`. If no state value given, returns all environments. |
| `states` | string | no | List all environments that match a specific state. Accepted values: `available`, `stopping`, or `stopped`. If no state value given, returns all environments. |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/environments?name=review%2Ffix-foo"
@ -279,7 +279,7 @@ Example response:
}
```
## Edit an existing environment
## Update an existing environment
Updates an existing environment's name and/or `external_url`.

View file

@ -107,6 +107,33 @@ job:
- make build
```
#### Skip job if the branch is empty
Use [`rules:changes:compare_to`](../yaml/index.md#ruleschangescompare_to) to avoid
running a job when the branch is empty, which saves CI/CD resources. Compare the
branch to the default branch, and if the branch:
- Doesn't have changed files, the job doesn't run.
- Has changed files, the job runs.
For example, in a project with `main` as the default branch:
```yaml
job:
script:
- echo "This job only runs for branches that are not empty"
rules:
- if: $CI_COMMIT_BRANCH
changes:
compare_to: refs/heads/main
paths:
- '*'
```
The rule for this job compares all files and paths (`*`) in the current branch against
the default branch `main`. The rule matches and the job runs only when there are
changes to the files in the branch.
### Complex rules
You can use all `rules` keywords, like `if`, `changes`, and `exists`, in the same

View file

@ -1155,7 +1155,7 @@ that use the same cache key use the same cache, including in different pipelines
If not set, the default key is `default`. All jobs with the `cache` keyword but
no `cache:key` share the `default` cache.
Must be used with `cache: path`, or nothing is cached.
Must be used with `cache: paths`, or nothing is cached.
**Keyword type**: Job keyword. You can use it only as part of a job or in the
[`default` section](#default).
@ -1325,7 +1325,7 @@ rspec:
Use `cache:when` to define when to save the cache, based on the status of the job.
Must be used with `cache: path`, or nothing is cached.
Must be used with `cache: paths`, or nothing is cached.
**Keyword type**: Job keyword. You can use it only as part of a job or in the
[`default` section](#default).
@ -1365,7 +1365,7 @@ Use the `pull` policy when you have many jobs executing in parallel that use the
This policy speeds up job execution and reduces load on the cache server. You can
use a job with the `push` policy to build the cache.
Must be used with `cache: path`, or nothing is cached.
Must be used with `cache: paths`, or nothing is cached.
**Keyword type**: Job keyword. You can use it only as part of a job or in the
[`default` section](#default).
@ -1773,7 +1773,7 @@ deploy:
**Additional details**:
- Enviroments created from this job definition are assigned a [tier](../environments/index.md#deployment-tier-of-environments) based on this value.
- Existing environments don't have their tier updated if this value is added later. Existing enviroments must have their tier updated via the [Environments API](../../api/environments.md#edit-an-existing-environment).
- Existing environments don't have their tier updated if this value is added later. Existing enviroments must have their tier updated via the [Environments API](../../api/environments.md#update-an-existing-environment).
**Related topics**:

View file

@ -176,6 +176,8 @@ module API
mount ::API::DeployKeys
mount ::API::DeployTokens
mount ::API::Deployments
mount ::API::Environments
mount ::API::FeatureFlagsUserLists
mount ::API::Features
mount ::API::FreezePeriods
mount ::API::Metadata
@ -225,13 +227,11 @@ module API
mount ::API::DebianProjectPackages
mount ::API::DependencyProxy
mount ::API::Discussions
mount ::API::Environments
mount ::API::ErrorTracking::ClientKeys
mount ::API::ErrorTracking::Collector
mount ::API::ErrorTracking::ProjectSettings
mount ::API::Events
mount ::API::FeatureFlags
mount ::API::FeatureFlagsUserLists
mount ::API::Files
mount ::API::GenericPackages
mount ::API::Geo

View file

@ -5,10 +5,10 @@ module API
class Environment < Entities::EnvironmentBasic
include RequestAwareEntity
expose :tier
expose :tier, documentation: { type: 'string', example: 'development' }
expose :project, using: Entities::BasicProjectDetails
expose :last_deployment, using: Entities::Deployment, if: { last_deployment: true }
expose :state
expose :state, documentation: { type: 'string', example: 'available' }
end
end
end

View file

@ -3,7 +3,12 @@
module API
module Entities
class EnvironmentBasic < Grape::Entity
expose :id, :name, :slug, :external_url, :created_at, :updated_at
expose :id, documentation: { type: 'integer', example: 1 }
expose :name, documentation: { type: 'string', example: 'deploy' }
expose :slug, documentation: { type: 'string', example: 'deploy' }
expose :external_url, documentation: { type: 'string', example: 'https://deploy.gitlab.example.com' }
expose :created_at, documentation: { type: 'dateTime', example: '2019-05-25T18:55:13.252Z' }
expose :updated_at, documentation: { type: 'dateTime', example: '2019-05-25T18:55:13.252Z' }
end
end
end

View file

@ -6,13 +6,13 @@ module API
class UserList < Grape::Entity
include RequestAwareEntity
expose :id
expose :iid
expose :project_id
expose :created_at
expose :updated_at
expose :name
expose :user_xids
expose :id, documentation: { type: 'integer', example: 1 }
expose :iid, documentation: { type: 'integer', example: 1 }
expose :project_id, documentation: { type: 'integer', example: 2 }
expose :created_at, documentation: { type: 'dateTime', example: '2020-02-04T08:13:10.507Z' }
expose :updated_at, documentation: { type: 'dateTime', example: '2020-02-04T08:13:10.507Z' }
expose :name, documentation: { type: 'string', example: 'user_list' }
expose :user_xids, documentation: { type: 'string', example: 'user1,user2' }
expose :path do |list|
project_feature_flags_user_list_path(list.project, list)

View file

@ -11,18 +11,27 @@ module API
urgency :low
params do
requires :id, type: String, desc: 'The project ID'
requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project owned by the authenticated user'
end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'Get all environments of the project' do
detail 'This feature was introduced in GitLab 8.11.'
desc 'List environments' do
detail 'Get all environments for a given project. This feature was introduced in GitLab 8.11.'
success Entities::Environment
is_array true
failure [
{ code: 403, message: 'Unauthenticated' },
{ code: 404, message: 'Not found' }
]
tags %w[environments]
end
params do
use :pagination
optional :name, type: String, desc: 'Returns the environment with this name'
optional :search, type: String, desc: 'Returns list of environments matching the search criteria'
optional :states, type: String, values: Environment.valid_states.map(&:to_s), desc: 'List all environments that match a specific state'
optional :name, type: String, desc: 'Return the environment with this name. Mutually exclusive with search'
optional :search, type: String, desc: 'Return list of environments matching the search criteria. Mutually exclusive with name'
optional :states,
type: String,
values: Environment.valid_states.map(&:to_s),
desc: 'List all environments that match a specific state. Accepted values: `available`, `stopping`, or `stopped`. If no state value given, returns all environments'
mutually_exclusive :name, :search, message: 'cannot be used together'
end
get ':id/environments' do
@ -33,15 +42,21 @@ module API
present paginate(environments), with: Entities::Environment, current_user: current_user
end
desc 'Creates a new environment' do
detail 'This feature was introduced in GitLab 8.11.'
desc 'Create a new environment' do
detail 'Creates a new environment with the given name and `external_url`. It returns `201` if the environment was successfully created, `400` for wrong parameters. This feature was introduced in GitLab 8.11.'
success Entities::Environment
failure [
{ code: 403, message: 'Unauthenticated' },
{ code: 404, message: 'Not found' },
{ code: 422, message: 'Unprocessable entity' }
]
tags %w[environments]
end
params do
requires :name, type: String, desc: 'The name of the environment to be created'
optional :external_url, type: String, desc: 'URL on which this deployment is viewable'
requires :name, type: String, desc: 'The name of the environment'
optional :external_url, type: String, desc: 'Place to link to for this environment'
optional :slug, absence: { message: "is automatically generated and cannot be changed" }, documentation: { hidden: true }
optional :tier, type: String, values: Environment.tiers.keys, desc: 'The tier of the environment to be created'
optional :tier, type: String, values: Environment.tiers.keys, desc: 'The tier of the new environment. Allowed values are `production`, `staging`, `testing`, `development`, and `other`'
end
post ':id/environments' do
authorize! :create_environment, user_project
@ -55,17 +70,23 @@ module API
end
end
desc 'Updates an existing environment' do
detail 'This feature was introduced in GitLab 8.11.'
desc 'Update an existing environment' do
detail 'Updates an existing environment name and/or `external_url`. It returns `200` if the environment was successfully updated. In case of an error, a status code `400` is returned. This feature was introduced in GitLab 8.11.'
success Entities::Environment
failure [
{ code: 403, message: 'Unauthenticated' },
{ code: 404, message: 'Not found' },
{ code: 422, message: 'Unprocessable entity' }
]
tags %w[environments]
end
params do
requires :environment_id, type: Integer, desc: 'The environment ID'
requires :environment_id, type: Integer, desc: 'The ID of the environment'
# TODO: disallow renaming via the API https://gitlab.com/gitlab-org/gitlab/-/issues/338897
optional :name, type: String, desc: 'DEPRECATED: Renaming environment can lead to errors, this will be removed in 15.0'
optional :external_url, type: String, desc: 'The new URL on which this deployment is viewable'
optional :slug, absence: { message: "is automatically generated and cannot be changed" }, documentation: { hidden: true }
optional :tier, type: String, values: Environment.tiers.keys, desc: 'The tier of the environment to be created'
optional :tier, type: String, values: Environment.tiers.keys, desc: 'The tier of the new environment. Allowed values are `production`, `staging`, `testing`, `development`, and `other`'
end
put ':id/environments/:environment_id' do
authorize! :update_environment, user_project
@ -80,14 +101,21 @@ module API
end
end
desc "Delete multiple stopped review apps" do
detail "Remove multiple stopped review environments older than a specific age"
desc 'Delete multiple stopped review apps' do
detail 'It schedules for deletion multiple environments that have already been stopped and are in the review app folder. The actual deletion is performed after 1 week from the time of execution. By default, it only deletes environments 30 days or older. You can change this default using the `before` parameter.'
success Entities::EnvironmentBasic
failure [
{ code: 400, message: 'Bad request' },
{ code: 403, message: 'Unauthenticated' },
{ code: 404, message: 'Not found' },
{ code: 409, message: 'Conflict' }
]
tags %w[environments]
end
params do
optional :before, type: Time, desc: "The timestamp before which environments can be deleted. Defaults to 30 days ago.", default: -> { 30.days.ago }
optional :limit, type: Integer, desc: "Maximum number of environments to delete. Defaults to 100.", default: 100, values: 1..1000
optional :dry_run, type: Boolean, desc: "If set, perform a dry run where no actual deletions will be performed. Defaults to true.", default: true
optional :before, type: Time, desc: "The date before which environments can be deleted. Defaults to 30 days ago. Expected in ISO 8601 format (`YYYY-MM-DDTHH:MM:SSZ`)", default: -> { 30.days.ago }
optional :limit, type: Integer, desc: "Maximum number of environments to delete. Defaults to 100", default: 100, values: 1..1000
optional :dry_run, type: Boolean, desc: "Defaults to true for safety reasons. It performs a dry run where no actual deletion will be performed. Set to false to actually delete the environment", default: true
end
delete ":id/environments/review_apps" do
authorize! :read_environment, user_project
@ -107,12 +135,17 @@ module API
end
end
desc 'Deletes an existing environment' do
detail 'This feature was introduced in GitLab 8.11.'
desc 'Delete an environment' do
detail 'It returns 204 if the environment was successfully deleted, and 404 if the environment does not exist. This feature was introduced in GitLab 8.11.'
success Entities::Environment
failure [
{ code: 403, message: 'Unauthenticated' },
{ code: 404, message: 'Not found' }
]
tags %w[environments]
end
params do
requires :environment_id, type: Integer, desc: 'The environment ID'
requires :environment_id, type: Integer, desc: 'The ID of the environment'
end
delete ':id/environments/:environment_id' do
authorize! :read_environment, user_project
@ -123,12 +156,18 @@ module API
destroy_conditionally!(environment)
end
desc 'Stops an existing environment' do
desc 'Stop an environment' do
detail 'It returns 200 if the environment was successfully stopped, and 404 if the environment does not exist.'
success Entities::Environment
failure [
{ code: 403, message: 'Unauthenticated' },
{ code: 404, message: 'Not found' }
]
tags %w[environments]
end
params do
requires :environment_id, type: Integer, desc: 'The environment ID'
optional :force, type: Boolean, default: false
requires :environment_id, type: Integer, desc: 'The ID of the environment'
optional :force, type: Boolean, default: false, desc: 'Force environment to stop without executing `on_stop` actions'
end
post ':id/environments/:environment_id/stop' do
authorize! :read_environment, user_project
@ -141,11 +180,16 @@ module API
present environment, with: Entities::Environment, current_user: current_user
end
desc 'Get a single environment' do
desc 'Get a specific environment' do
success Entities::Environment
failure [
{ code: 403, message: 'Unauthenticated' },
{ code: 404, message: 'Not found' }
]
tags %w[environments]
end
params do
requires :environment_id, type: Integer, desc: 'The environment ID'
requires :environment_id, type: Integer, desc: 'The ID of the environment'
end
get ':id/environments/:environment_id' do
authorize! :read_environment, user_project

View file

@ -16,16 +16,19 @@ module API
end
params do
requires :id, type: String, desc: 'The ID of a project'
requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end
resource 'projects/:id', requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
resource :feature_flags_user_lists do
desc 'Get all feature flags user lists of a project' do
detail 'This feature was introduced in GitLab 12.10'
desc 'List all feature flag user lists for a project' do
detail 'Gets all feature flag user lists for the requested project. ' \
'This feature was introduced in GitLab 12.10.'
success ::API::Entities::FeatureFlag::UserList
is_array true
tags %w[feature_flags_user_lists]
end
params do
optional :search, type: String, desc: 'Returns the list of user lists matching the search critiera'
optional :search, type: String, desc: 'Return user lists matching the search criteria'
use :pagination
end
@ -35,9 +38,10 @@ module API
with: ::API::Entities::FeatureFlag::UserList
end
desc 'Create a feature flags user list for a project' do
detail 'This feature was introduced in GitLab 12.10'
desc 'Create a feature flag user list' do
detail 'Creates a feature flag user list. This feature was introduced in GitLab 12.10.'
success ::API::Entities::FeatureFlag::UserList
tags %w[feature_flags_user_lists]
end
params do
requires :name, type: String, desc: 'The name of the list'
@ -59,12 +63,13 @@ module API
end
params do
requires :iid, type: String, desc: 'The internal ID of the user list'
requires :iid, types: [String, Integer], desc: "The internal ID of the project's feature flag user list"
end
resource 'feature_flags_user_lists/:iid' do
desc 'Get a single feature flag user list belonging to a project' do
detail 'This feature was introduced in GitLab 12.10'
desc 'Get a feature flag user list' do
detail 'Gets a feature flag user list. This feature was introduced in GitLab 12.10.'
success ::API::Entities::FeatureFlag::UserList
tags %w[feature_flags_user_lists]
end
get do
present user_project.operations_feature_flags_user_lists.find_by_iid!(params[:iid]),
@ -72,8 +77,9 @@ module API
end
desc 'Update a feature flag user list' do
detail 'This feature was introduced in GitLab 12.10'
detail 'Updates a feature flag user list. This feature was introduced in GitLab 12.10.'
success ::API::Entities::FeatureFlag::UserList
tags %w[feature_flags_user_lists]
end
params do
optional :name, type: String, desc: 'The name of the list'
@ -93,8 +99,9 @@ module API
end
end
desc 'Delete a feature flag user list' do
detail 'This feature was introduced in GitLab 12.10'
desc 'Delete feature flag user list' do
detail 'Deletes a feature flag user list. This feature was introduced in GitLab 12.10.'
tags %w[feature_flags_user_lists]
end
delete do
# TODO: Move the business logic to a service class in app/services/feature_flags.

View file

@ -86,7 +86,11 @@ module Gitlab
analyzers.each do |analyzer|
next if analyzer.suppressed? && !analyzer.requires_tracking?(parsed)
analyzer.analyze(parsed)
if analyzer.raw?
analyzer.analyze(sql)
else
analyzer.analyze(parsed)
end
rescue StandardError, ::Gitlab::Database::QueryAnalyzers::Base::QueryAnalyzerError => e
# We catch all standard errors to prevent validation errors to introduce fatal errors in production
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e)

View file

@ -53,6 +53,10 @@ module Gitlab
Thread.current[self.context_key]
end
def self.raw?
false
end
def self.enabled?
raise NotImplementedError
end

View file

@ -0,0 +1,45 @@
# frozen_string_literal: true
module Gitlab
module Database
module QueryAnalyzers
class QueryRecorder < Base
LOG_FILE = 'rspec/query_recorder.ndjson'
class << self
def raw?
true
end
def enabled?
# Only enable QueryRecorder in CI
ENV['CI'].present?
end
def analyze(sql)
payload = {
sql: sql
}
log_query(payload)
end
private
def log_query(payload)
log_path = Rails.root.join(LOG_FILE)
log_dir = File.dirname(log_path)
# Create log directory if it does not exist since it is only created
# ahead of time by certain CI jobs
FileUtils.mkdir_p(log_dir) unless Dir.exist?(log_dir)
log_line = "#{Gitlab::Json.dump(payload)}\n"
File.write(log_path, log_line, mode: 'a')
end
end
end
end
end
end

View file

@ -4548,9 +4548,6 @@ msgstr ""
msgid "Analytics"
msgstr ""
msgid "AnalyticsDashboards|Dashboards"
msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
@ -25468,6 +25465,9 @@ msgstr ""
msgid "Merge requests are a place to propose changes you've made to a project and discuss those changes with others"
msgstr ""
msgid "Merge requests can't be merged if the status checks did not succeed or are still running."
msgstr ""
msgid "Merge the feature branch into the target branch and fix any conflicts. %{linkStart}How do I fix them?%{linkEnd}"
msgstr ""
@ -32060,6 +32060,9 @@ msgstr ""
msgid "ProjectSettings|Squashing is never performed and the checkbox is hidden."
msgstr ""
msgid "ProjectSettings|Status checks must succeed"
msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""

View file

@ -1,5 +1,6 @@
import { GlFormGroup, GlFormCheckbox, GlFormInput } from '@gitlab/ui';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import { placeholderForType } from 'jh_else_ce/integrations/constants';
import TriggerFields from '~/integrations/edit/components/trigger_fields.vue';
@ -28,6 +29,50 @@ describe('TriggerFields', () => {
const findAllGlFormCheckboxes = () => wrapper.findAllComponents(GlFormCheckbox);
const findAllGlFormInputs = () => wrapper.findAllComponents(GlFormInput);
describe('placeholder text on the event fields and default values', () => {
const dummyFieldPlaceholder = '#foo';
const integrationTypes = {
INTEGRATION_TYPE_SLACK: 'slack',
INTEGRATION_TYPE_SLACK_APPLICATION: 'gitlab_slack_application',
INTEGRATION_TYPE_MATTERMOST: 'mattermost',
INTEGRATION_TYPE_NON_EXISTING: 'non_existing',
};
it.each`
integrationType | fieldPlaceholder | expectedPlaceholder
${integrationTypes.INTEGRATION_TYPE_SLACK} | ${undefined} | ${placeholderForType[integrationTypes.INTEGRATION_TYPE_SLACK]}
${integrationTypes.INTEGRATION_TYPE_SLACK} | ${''} | ${placeholderForType[integrationTypes.INTEGRATION_TYPE_SLACK]}
${integrationTypes.INTEGRATION_TYPE_SLACK} | ${dummyFieldPlaceholder} | ${dummyFieldPlaceholder}
${integrationTypes.INTEGRATION_TYPE_SLACK_APPLICATION} | ${undefined} | ${placeholderForType[integrationTypes.INTEGRATION_TYPE_SLACK_APPLICATION]}
${integrationTypes.INTEGRATION_TYPE_SLACK_APPLICATION} | ${''} | ${placeholderForType[integrationTypes.INTEGRATION_TYPE_SLACK_APPLICATION]}
${integrationTypes.INTEGRATION_TYPE_SLACK_APPLICATION} | ${dummyFieldPlaceholder} | ${dummyFieldPlaceholder}
${integrationTypes.INTEGRATION_TYPE_MATTERMOST} | ${undefined} | ${placeholderForType[integrationTypes.INTEGRATION_TYPE_MATTERMOST]}
${integrationTypes.INTEGRATION_TYPE_MATTERMOST} | ${''} | ${placeholderForType[integrationTypes.INTEGRATION_TYPE_MATTERMOST]}
${integrationTypes.INTEGRATION_TYPE_MATTERMOST} | ${dummyFieldPlaceholder} | ${dummyFieldPlaceholder}
${integrationTypes.INTEGRATION_TYPE_NON_EXISTING} | ${undefined} | ${undefined}
${integrationTypes.INTEGRATION_TYPE_NON_EXISTING} | ${''} | ${undefined}
${integrationTypes.INTEGRATION_TYPE_NON_EXISTING} | ${dummyFieldPlaceholder} | ${dummyFieldPlaceholder}
`(
'passed down correct placeholder for "$integrationType" type and "$fieldPlaceholder" placeholder on the field',
({ integrationType, fieldPlaceholder, expectedPlaceholder }) => {
createComponent({
type: integrationType,
events: [
{
field: {
name: 'foo',
value: '',
placeholder: fieldPlaceholder,
},
},
],
});
const field = wrapper.findComponent(GlFormInput);
expect(field.attributes('placeholder')).toBe(expectedPlaceholder);
},
);
});
describe.each([true, false])('template, isInheriting = `%p`', (isInheriting) => {
it('renders a label with text "Trigger"', () => {
createComponent();

View file

@ -10,6 +10,7 @@ RSpec.describe Gitlab::Database::QueryAnalyzer, query_analyzers: false do
before do
allow(described_class.instance).to receive(:all_analyzers).and_return([analyzer, disabled_analyzer])
allow(analyzer).to receive(:enabled?).and_return(true)
allow(analyzer).to receive(:raw?).and_return(false)
allow(analyzer).to receive(:suppressed?).and_return(false)
allow(analyzer).to receive(:begin!)
allow(analyzer).to receive(:end!)
@ -181,6 +182,13 @@ RSpec.describe Gitlab::Database::QueryAnalyzer, query_analyzers: false do
expect { process_sql("SELECT 1 FROM projects") }.not_to raise_error
end
it 'does call analyze with raw sql when raw? is true' do
expect(analyzer).to receive(:raw?).and_return(true)
expect(analyzer).to receive(:analyze).with('SELECT 1 FROM projects')
expect { process_sql("SELECT 1 FROM projects") }.not_to raise_error
end
def process_sql(sql)
described_class.instance.within do
ApplicationRecord.load_balancer.read_write do |connection|

View file

@ -0,0 +1,38 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Database::QueryAnalyzers::QueryRecorder, query_analyzers: false do
# We keep only the QueryRecorder analyzer running
around do |example|
described_class.with_suppressed(false) do
example.run
end
end
context 'when analyzer is enabled for tests' do
let(:query) { 'SELECT 1 FROM projects' }
let(:log_path) { Rails.root.join(described_class::LOG_FILE) }
before do
stub_env('CI', 'true')
# This is needed to be able to stub_env the CI variable
::Gitlab::Database::QueryAnalyzer.instance.begin!([described_class])
end
after do
::Gitlab::Database::QueryAnalyzer.instance.end!([described_class])
end
it 'logs queries to a file' do
allow(FileUtils).to receive(:mkdir_p)
.with(File.dirname(log_path))
expect(File).to receive(:write)
.with(log_path, /^{"sql":"#{query}/, mode: 'a')
expect(described_class).to receive(:analyze).with(/^#{query}/).and_call_original
expect { ApplicationRecord.connection.execute(query) }.not_to raise_error
end
end
end

View file

@ -0,0 +1,9 @@
# frozen_string_literal: true
RSpec.configure do |config|
# Truncate the query_recorder log file before starting the suite
config.before(:suite) do
log_path = Rails.root.join(Gitlab::Database::QueryAnalyzers::QueryRecorder::LOG_FILE)
File.write(log_path, '') if File.exist?(log_path)
end
end