diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss index 25f5c0407f75..880231f5644a 100644 --- a/app/assets/stylesheets/pages/issues.scss +++ b/app/assets/stylesheets/pages/issues.scss @@ -1,3 +1,51 @@ +.issue-token-link { + &[href] { + color: $blue-600; + } + + &:hover, + &:focus { + outline: none; + text-decoration: none; + } +} + +.issue-token-reference { + margin-right: 1px; + background-color: $gray-lighter; + transition: background $general-hover-transition-duration $general-hover-transition-curve, color $general-hover-transition-duration $general-hover-transition-curve; + + .issue-token:hover &, + .issue-token-link:focus > & { + background-color: $gray-normal; + color: $blue-800; + text-decoration: none; + } +} + +.issue-token-title { + background-color: $gray-normal; + transition: background $general-hover-transition-duration $general-hover-transition-curve; + + .issue-token:hover &, + .issue-token-link:focus > & { + background-color: $border-gray-normal; + } +} + +.issue-token-remove-button { + background-color: $gray-normal; + transition: background $general-hover-transition-duration $general-hover-transition-curve; + + &:hover, + &:focus, + .issue-token:hover &, + .issue-token-link:focus + & { + background-color: $border-gray-normal; + outline: none; + } +} + .issue-realtime-pre-pulse { opacity: 0; } diff --git a/app/controllers/profiles/two_factor_auths_controller.rb b/app/controllers/profiles/two_factor_auths_controller.rb index d1b9485f06da..3e397684ffe5 100644 --- a/app/controllers/profiles/two_factor_auths_controller.rb +++ b/app/controllers/profiles/two_factor_auths_controller.rb @@ -231,8 +231,6 @@ def groups_notification(groups) end def ensure_verified_primary_email - return unless Feature.enabled?(:ensure_verified_primary_email_for_2fa, default_enabled: :yaml) - unless current_user.two_factor_enabled? || current_user.primary_email_verified? redirect_to profile_emails_path, notice: s_('You need to verify your primary email first before enabling Two-Factor Authentication.') end diff --git a/app/services/ci/stuck_builds/drop_scheduled_service.rb b/app/services/ci/stuck_builds/drop_scheduled_service.rb new file mode 100644 index 000000000000..bc794f3fcead --- /dev/null +++ b/app/services/ci/stuck_builds/drop_scheduled_service.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module Ci + module StuckBuilds + class DropScheduledService + include DropHelpers + + BUILD_SCHEDULED_OUTDATED_TIMEOUT = 1.hour + + def execute + Gitlab::AppLogger.info "#{self.class}: Cleaning scheduled, timed-out builds" + + drop(scheduled_timed_out_builds, failure_reason: :stale_schedule) + end + + private + + def scheduled_timed_out_builds + Ci::Build.where(status: :scheduled).where( # rubocop: disable CodeReuse/ActiveRecord + 'ci_builds.scheduled_at IS NOT NULL AND ci_builds.scheduled_at < ?', + BUILD_SCHEDULED_OUTDATED_TIMEOUT.ago + ) + end + end + end +end diff --git a/app/services/ci/stuck_builds/drop_service.rb b/app/services/ci/stuck_builds/drop_service.rb index dbc1860eb2ba..0f8375e0cf16 100644 --- a/app/services/ci/stuck_builds/drop_service.rb +++ b/app/services/ci/stuck_builds/drop_service.rb @@ -6,7 +6,6 @@ class DropService include DropHelpers BUILD_PENDING_OUTDATED_TIMEOUT = 1.day - BUILD_SCHEDULED_OUTDATED_TIMEOUT = 1.hour BUILD_PENDING_STUCK_TIMEOUT = 1.hour BUILD_LOOKBACK = 5.days @@ -18,8 +17,6 @@ def execute failure_reason: :stuck_or_timeout_failure ) - drop(scheduled_timed_out_builds, failure_reason: :stale_schedule) - drop_stuck( pending_builds(BUILD_PENDING_STUCK_TIMEOUT.ago), failure_reason: :stuck_or_timeout_failure @@ -40,13 +37,6 @@ def pending_builds(timeout) end end # rubocop: enable CodeReuse/ActiveRecord - - def scheduled_timed_out_builds - Ci::Build.where(status: :scheduled).where( # rubocop: disable CodeReuse/ActiveRecord - 'ci_builds.scheduled_at IS NOT NULL AND ci_builds.scheduled_at < ?', - BUILD_SCHEDULED_OUTDATED_TIMEOUT.ago - ) - end end end end diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml index 802697b66e16..ebb4e777b441 100644 --- a/app/workers/all_queues.yml +++ b/app/workers/all_queues.yml @@ -237,6 +237,15 @@ :weight: 1 :idempotent: true :tags: [] +- :name: cronjob:ci_stuck_builds_drop_scheduled + :worker_name: Ci::StuckBuilds::DropScheduledWorker + :feature_category: :continuous_integration + :has_external_dependencies: + :urgency: :low + :resource_boundary: :unknown + :weight: 1 + :idempotent: true + :tags: [] - :name: cronjob:container_expiration_policy :worker_name: ContainerExpirationPolicyWorker :feature_category: :container_registry diff --git a/app/workers/ci/stuck_builds/drop_scheduled_worker.rb b/app/workers/ci/stuck_builds/drop_scheduled_worker.rb new file mode 100644 index 000000000000..923841771cf9 --- /dev/null +++ b/app/workers/ci/stuck_builds/drop_scheduled_worker.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Ci + module StuckBuilds + class DropScheduledWorker + include ApplicationWorker + include ExclusiveLeaseGuard + + idempotent! + + # rubocop:disable Scalability/CronWorkerContext + # This is an instance-wide cleanup query, so there's no meaningful + # scope to consider this in the context of. + include CronjobQueue + # rubocop:enable Scalability/CronWorkerContext + + data_consistency :always + + feature_category :continuous_integration + + def perform + try_obtain_lease do + Ci::StuckBuilds::DropScheduledService.new.execute + end + end + + private + + def lease_timeout + 30.minutes + end + end + end +end diff --git a/app/workers/stuck_ci_jobs_worker.rb b/app/workers/stuck_ci_jobs_worker.rb index d87e866d8a70..6282c9200b10 100644 --- a/app/workers/stuck_ci_jobs_worker.rb +++ b/app/workers/stuck_ci_jobs_worker.rb @@ -18,6 +18,7 @@ class StuckCiJobsWorker # rubocop:disable Scalability/IdempotentWorker def perform Ci::StuckBuilds::DropRunningWorker.perform_in(20.minutes) + Ci::StuckBuilds::DropScheduledWorker.perform_in(40.minutes) return unless try_obtain_lease diff --git a/config/feature_flags/development/ensure_verified_primary_email_for_2fa.yml b/config/feature_flags/development/ensure_verified_primary_email_for_2fa.yml deleted file mode 100644 index 7a52486d3569..000000000000 --- a/config/feature_flags/development/ensure_verified_primary_email_for_2fa.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: ensure_verified_primary_email_for_2fa -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69593 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340151 -milestone: '14.3' -type: development -group: group::access -default_enabled: true diff --git a/doc/administration/gitaly/index.md b/doc/administration/gitaly/index.md index e15812a92cd8..c689530e12c4 100644 --- a/doc/administration/gitaly/index.md +++ b/doc/administration/gitaly/index.md @@ -21,11 +21,11 @@ storage and retrieval. Gitaly can be: Gitaly implements a client-server architecture: - A Gitaly server is any node that runs Gitaly itself. -- A Gitaly client is any node that runs a process that makes requests of the Gitaly server. These - include, but are not limited to: - - [GitLab Rails application](https://gitlab.com/gitlab-org/gitlab). - - [GitLab Shell](https://gitlab.com/gitlab-org/gitlab-shell). - - [GitLab Workhorse](https://gitlab.com/gitlab-org/gitlab-workhorse). +- A Gitaly client is any node that runs a process that makes requests of the Gitaly server. Gitaly clients are also known as _Gitaly consumers_ and include: + - [GitLab Rails application](https://gitlab.com/gitlab-org/gitlab) + - [GitLab Shell](https://gitlab.com/gitlab-org/gitlab-shell) + - [GitLab Workhorse](https://gitlab.com/gitlab-org/gitlab-workhorse) + - [GitLab Elasticsearch Indexer](https://gitlab.com/gitlab-org/gitlab-elasticsearch-indexer) Gitaly manages only Git repository access for GitLab. Other types of GitLab data aren't accessed using Gitaly. diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md index 39a1d9b035e1..67b2144c160c 100644 --- a/doc/ci/yaml/index.md +++ b/doc/ci/yaml/index.md @@ -3342,56 +3342,38 @@ to select a specific site profile and scanner profile. > [Introduced](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/3515) in GitLab 11.5, you can control which failures to retry on. -Use `retry` to configure how many times a job is retried in -case of a failure. +Use `retry` to configure how many times a job is retried if it fails. +If not defined, defaults to `0` and jobs do not retry. -When a job fails, the job is processed again, -until the limit specified by the `retry` keyword is reached. +When a job fails, the job is processed up to two more times, until it succeeds or +reaches the maximum number of retries. -If `retry` is set to `2`, and a job succeeds in a second run (first retry), it is not retried. -The `retry` value must be a positive integer, from `0` to `2` -(two retries maximum, three runs in total). +By default, all failure types cause the job to be retried. Use [`retry:when`](#retrywhen) +to select which failures to retry on. -The following example retries all failure cases: - -```yaml -test: - script: rspec - retry: 2 -``` - -By default, a job is retried on all failure cases. To have better control -over which failures to retry, `retry` can be a hash with the following keys: +**Keyword type**: Job keyword. You can use it only as part of a job or in the +[`default:` section](#custom-default-keyword-values). -- `max`: The maximum number of retries. -- `when`: The failure cases to retry. +**Possible inputs**: `0` (default), `1`, or `2`. -To retry only runner system failures at maximum two times: +**Example of `retry`**: ```yaml test: script: rspec - retry: - max: 2 - when: runner_system_failure + retry: 2 ``` -If there is another failure, other than a runner system failure, the job -is not retried. +#### `retry:when` -To retry on multiple failure cases, `when` can also be an array of failures: +Use `retry:when` with `retry:max` to retry jobs for only specific failure cases. +`retry:max` is the maximum number of retries, like [`retry`](#retry), and can be +`0`, `1`, or `2`. -```yaml -test: - script: rspec - retry: - max: 2 - when: - - runner_system_failure - - stuck_or_timeout_failure -``` +**Keyword type**: Job keyword. You can use it only as part of a job or in the +[`default:` section](#custom-default-keyword-values). -Possible values for `when` are: +**Possible inputs**: A single failure type, or an array of one or more failure types: