diff options
Diffstat (limited to 'app')
8 files changed, 70 insertions, 20 deletions
diff --git a/app/assets/javascripts/ci/catalog/components/list/ci_resources_list_item.vue b/app/assets/javascripts/ci/catalog/components/list/ci_resources_list_item.vue index 504d3d38275..6e4ad5d60de 100644 --- a/app/assets/javascripts/ci/catalog/components/list/ci_resources_list_item.vue +++ b/app/assets/javascripts/ci/catalog/components/list/ci_resources_list_item.vue @@ -1,6 +1,6 @@ <script> import { GlAvatar, GlBadge, GlIcon, GlLink, GlSprintf, GlTooltipDirective } from '@gitlab/ui'; -import { s__ } from '~/locale'; +import { s__, n__ } from '~/locale'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { formatDate, getTimeago } from '~/lib/utils/datetime_utility'; import { cleanLeadingSeparator } from '~/lib/utils/url_utility'; @@ -49,6 +49,9 @@ export default { starIcon() { return this.starCount > 0 ? 'star' : 'star-o'; }, + starCountText() { + return n__('Star', 'Stars', this.starCount); + }, hasReleasedVersion() { return Boolean(this.latestVersion?.releasedAt); }, @@ -115,7 +118,12 @@ export default { <div class="gl-display-flex gl-flex-grow-1 gl-md-justify-content-space-between"> <gl-badge size="sm" class="gl-h-5 gl-align-self-center">{{ tagName }}</gl-badge> <span class="gl-display-flex gl-align-items-center gl-ml-5"> - <span class="gl--flex-center" data-testid="stats-favorites"> + <span + v-gl-tooltip.top + :title="starCountText" + class="gl--flex-center" + data-testid="stats-favorites" + > <gl-icon :name="starIcon" :size="14" class="gl-mr-2" /> <span class="gl-mr-3">{{ starCount }}</span> </span> @@ -130,7 +138,7 @@ export default { <span v-if="hasReleasedVersion"> <gl-sprintf :message="$options.i18n.releasedMessage"> <template #timeAgo> - <span v-gl-tooltip.bottom :title="formattedDate"> + <span v-gl-tooltip.top :title="formattedDate"> {{ releasedAt }} </span> </template> diff --git a/app/assets/javascripts/editor/schema/ci.json b/app/assets/javascripts/editor/schema/ci.json index 308a68544bc..b8d3606d23e 100644 --- a/app/assets/javascripts/editor/schema/ci.json +++ b/app/assets/javascripts/editor/schema/ci.json @@ -509,6 +509,18 @@ "description": "Command or script that should be executed as the container's entrypoint. It will be translated to Docker's --entrypoint option while creating the container. The syntax is similar to Dockerfile's ENTRYPOINT directive, where each shell token is a separate string in the array.", "minItems": 1 }, + "docker": { + "type": "object", + "markdownDescription": "Options to pass to Runners Docker Executor. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#imagedocker)", + "additionalProperties": false, + "properties": { + "platform": { + "type": "string", + "minLength": 1, + "description": "Image architecture to pull." + } + } + }, "pull_policy": { "markdownDescription": "Specifies how to pull the image in Runner. It can be one of `always`, `never` or `if-not-present`. The default value is `always`. [Learn more](https://docs.gitlab.com/ee/ci/yaml/#imagepull_policy).", "default": "always", @@ -540,13 +552,6 @@ "required": [ "name" ] - }, - { - "type": "array", - "minLength": 1, - "items": { - "type": "string" - } } ], "markdownDescription": "Specifies the docker image to use for the job or globally for all jobs. Job configuration takes precedence over global setting. Requires a certain kind of Gitlab runner executor. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#image)." @@ -579,8 +584,20 @@ "type": "string" } }, + "docker": { + "type": "object", + "markdownDescription": "Options to pass to Runners Docker Executor. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#servicesdocker)", + "additionalProperties": false, + "properties": { + "platform": { + "type": "string", + "minLength": 1, + "description": "Image architecture to pull." + } + } + }, "pull_policy": { - "markdownDescription": "Specifies how to pull the image in Runner. It can be one of `always`, `never` or `if-not-present`. The default value is `always`. [Learn more](https://docs.gitlab.com/ee/ci/yaml/#servicepull_policy).", + "markdownDescription": "Specifies how to pull the image in Runner. It can be one of `always`, `never` or `if-not-present`. The default value is `always`. [Learn more](https://docs.gitlab.com/ee/ci/yaml/#servicespull_policy).", "default": "always", "oneOf": [ { diff --git a/app/assets/javascripts/projects/settings_service_desk/custom_email_constants.js b/app/assets/javascripts/projects/settings_service_desk/custom_email_constants.js index 5b0266c95df..7a3d74e1e93 100644 --- a/app/assets/javascripts/projects/settings_service_desk/custom_email_constants.js +++ b/app/assets/javascripts/projects/settings_service_desk/custom_email_constants.js @@ -112,7 +112,7 @@ export const I18N_ERROR_SMTP_HOST_ISSUE_DESC = s__( ); export const I18N_ERROR_INVALID_CREDENTIALS_LABEL = s__('ServiceDesk|Invalid credentials'); export const I18N_ERROR_INVALID_CREDENTIALS_DESC = s__( - 'ServiceDesk|The given credentials (username and password) were rejected by the SMTP server.', + 'ServiceDesk|The given credentials (username and password) were rejected by the SMTP server, or you need to explicitly set an authentication method.', ); export const I18N_ERROR_MAIL_NOT_RECEIVED_IN_TIMEFRAME_LABEL = s__( 'ServiceDesk|Verification email not received within timeframe', diff --git a/app/validators/json_schema_validator.rb b/app/validators/json_schema_validator.rb index 2ef011df73e..f661392082f 100644 --- a/app/validators/json_schema_validator.rb +++ b/app/validators/json_schema_validator.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + # # JsonSchemaValidator # @@ -24,11 +25,19 @@ class JsonSchemaValidator < ActiveModel::EachValidator end def validate_each(record, attribute, value) - value = value.to_h.stringify_keys if options[:hash_conversion] == true + value = value.to_h.deep_stringify_keys if options[:hash_conversion] == true value = Gitlab::Json.parse(value.to_s) if options[:parse_json] == true && !value.nil? - unless valid_schema?(value) - record.errors.add(attribute, _("must be a valid json schema")) + if options[:detail_errors] + validator.validate(value).each do |error| + message = format( + _("'%{data_pointer}' must be a valid '%{type}'"), + data_pointer: error['data_pointer'], type: error['type'] + ) + record.errors.add(attribute, message) + end + else + record.errors.add(attribute, _("must be a valid json schema")) unless valid_schema?(value) end end diff --git a/app/views/notify/service_desk_verification_result_email.html.haml b/app/views/notify/service_desk_verification_result_email.html.haml index faf8ae2e28c..651f94533ec 100644 --- a/app/views/notify/service_desk_verification_result_email.html.haml +++ b/app/views/notify/service_desk_verification_result_email.html.haml @@ -35,7 +35,7 @@ %p %b = s_('Notify|Invalid credentials:') - = s_('Notify|The given credentials (username and password) were rejected by the SMTP server.') + = s_('Notify|The given credentials (username and password) were rejected by the SMTP server, or you need to explicitly set an authentication method.') - if @verification.mail_not_received_within_timeframe? %p %b diff --git a/app/views/notify/service_desk_verification_result_email.text.erb b/app/views/notify/service_desk_verification_result_email.text.erb index fd2e4446d0b..134b6592197 100644 --- a/app/views/notify/service_desk_verification_result_email.text.erb +++ b/app/views/notify/service_desk_verification_result_email.text.erb @@ -18,7 +18,7 @@ <%= s_('Notify|We were not able to make a connection to the specified host or there was an SSL issue.') %> <% elsif @verification.invalid_credentials? %> <%= s_('Notify|Invalid credentials:') %> - <%= s_('Notify|The given credentials (username and password) were rejected by the SMTP server.') %> + <%= s_('Notify|The given credentials (username and password) were rejected by the SMTP server, or you need to explicitly set an authentication method.') %> <% elsif @verification.mail_not_received_within_timeframe? %> <%= s_('Notify|Verification email not received within timeframe:') %> <%= s_('Notify|We did not receive the verification email we sent out to %{strong_open}%{email_address}%{strong_close} in time.') % { email_address: verify_email_address, strong_open: '', strong_close: '' } %> diff --git a/app/workers/bulk_imports/entity_worker.rb b/app/workers/bulk_imports/entity_worker.rb index caee292a504..6ff2d15d6e8 100644 --- a/app/workers/bulk_imports/entity_worker.rb +++ b/app/workers/bulk_imports/entity_worker.rb @@ -3,9 +3,10 @@ module BulkImports class EntityWorker include ApplicationWorker + include ExclusiveLeaseGuard idempotent! - deduplicate :until_executed, if_deduplicated: :reschedule_once + deduplicate :until_executing data_consistency :always feature_category :importers sidekiq_options retry: 3, dead: false @@ -27,7 +28,10 @@ module BulkImports if running_tracker.present? log_info(message: 'Stage running', entity_stage: running_tracker.stage) else - start_next_stage + # Use lease guard to prevent duplicated workers from starting multiple stages + try_obtain_lease do + start_next_stage + end end re_enqueue @@ -78,6 +82,18 @@ module BulkImports end end + def lease_timeout + PERFORM_DELAY + end + + def lease_key + "gitlab:bulk_imports:entity_worker:#{entity.id}" + end + + def log_lease_taken + log_info(message: lease_taken_message) + end + def source_version entity.bulk_import.source_version_info.to_s end diff --git a/app/workers/packages/npm/create_metadata_cache_worker.rb b/app/workers/packages/npm/create_metadata_cache_worker.rb index 0b6e34b13eb..cff7871dab7 100644 --- a/app/workers/packages/npm/create_metadata_cache_worker.rb +++ b/app/workers/packages/npm/create_metadata_cache_worker.rb @@ -16,7 +16,7 @@ module Packages def perform(project_id, package_name) project = Project.find_by_id(project_id) - return unless project && Feature.enabled?(:npm_metadata_cache, project) + return unless project ::Packages::Npm::CreateMetadataCacheService .new(project, package_name) |